MYNEWT-729 SensorAPI: Send sensor data over OIC - Clean up
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/75e65613 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/75e65613 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/75e65613 Branch: refs/heads/master Commit: 75e65613f2629cfe83a52deafcaa193ce378747e Parents: 5453323 Author: Vipul Rahane <vipulrah...@apache.org> Authored: Fri Apr 14 18:04:02 2017 -0700 Committer: Vipul Rahane <vipulrah...@apache.org> Committed: Mon Apr 17 16:14:20 2017 -0700 ---------------------------------------------------------------------- apps/sensors_test/pkg.yml | 11 ++ apps/sensors_test/src/gatt_svr.c | 313 ++++++++++++++++++++++++++++++++++ apps/sensors_test/src/main.c | 143 +++++++++------- apps/sensors_test/syscfg.yml | 2 - hw/sensor/pkg.yml | 7 - hw/sensor/src/gatt_svr.c | 309 --------------------------------- 6 files changed, 406 insertions(+), 379 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/75e65613/apps/sensors_test/pkg.yml ---------------------------------------------------------------------- diff --git a/apps/sensors_test/pkg.yml b/apps/sensors_test/pkg.yml index 8ea0ffe..39250ae 100644 --- a/apps/sensors_test/pkg.yml +++ b/apps/sensors_test/pkg.yml @@ -41,6 +41,17 @@ pkg.deps: - sys/log/full - sys/stats/full - boot/split + - mgmt/imgmgr + #- mgmt/newtmgr + +pkg.deps.SENSOR_BLE_OIC: + - mgmt/oicmgr + - net/nimble/controller + - net/nimble/host + - net/nimble/host/services/gap + - net/nimble/host/services/gatt + - net/nimble/host/store/ram + - net/nimble/transport/ram pkg.deps.CONFIG_NFFS: - fs/nffs http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/75e65613/apps/sensors_test/src/gatt_svr.c ---------------------------------------------------------------------- diff --git a/apps/sensors_test/src/gatt_svr.c b/apps/sensors_test/src/gatt_svr.c new file mode 100644 index 0000000..e29f007 --- /dev/null +++ b/apps/sensors_test/src/gatt_svr.c @@ -0,0 +1,313 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include <syscfg/syscfg.h> +#if MYNEWT_VAL(SENSOR_BLE_OIC) + +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include "bsp/bsp.h" +#include "host/ble_hs.h" +#include "bleprph.h" + +/** + * The vendor specific security test service consists of two characteristics: + * o random-number-generator: generates a random 32-bit number each time + * it is read. This characteristic can only be read over an encrypted + * connection. + * o static-value: a single-byte characteristic that can always be read, + * but can only be written over an encrypted connection. + */ + +/* 59462f12-9543-9999-12c8-58b459a2712d */ +static const ble_uuid128_t gatt_svr_svc_sec_test_uuid = + BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12, \ + 0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59); + +/* 5c3a659e-897e-45e1-b016-007107c96df6 */ +static const ble_uuid128_t gatt_svr_chr_sec_test_rand_uuid = + BLE_UUID128_INIT(0xf6, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, \ + 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c); + +/* 5c3a659e-897e-45e1-b016-007107c96df7 */ +static const ble_uuid128_t gatt_svr_chr_sec_test_static_uuid = + BLE_UUID128_INIT(0xf7, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, \ + 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c); + +static uint8_t gatt_svr_sec_test_static_val; + +static int +gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg); + +static int +gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg); + +static const struct ble_gatt_svc_def gatt_svr_svcs[] = { + { + /*** Alert Notification Service. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(GATT_SVR_SVC_ALERT_UUID), + .characteristics = (struct ble_gatt_chr_def[]) { { + .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID), + .access_cb = gatt_svr_chr_access_alert, + .flags = BLE_GATT_CHR_F_READ, + }, { + .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_NEW_ALERT), + .access_cb = gatt_svr_chr_access_alert, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID), + .access_cb = gatt_svr_chr_access_alert, + .flags = BLE_GATT_CHR_F_READ, + }, { + .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_UNR_ALERT_STAT_UUID), + .access_cb = gatt_svr_chr_access_alert, + .flags = BLE_GATT_CHR_F_NOTIFY, + }, { + .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_ALERT_NOT_CTRL_PT), + .access_cb = gatt_svr_chr_access_alert, + .flags = BLE_GATT_CHR_F_WRITE, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, + + { + /*** Service: Security test. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &gatt_svr_svc_sec_test_uuid.u, + .characteristics = (struct ble_gatt_chr_def[]) { { + /*** Characteristic: Random number generator. */ + .uuid = &gatt_svr_chr_sec_test_rand_uuid.u, + .access_cb = gatt_svr_chr_access_sec_test, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC, + }, { + /*** Characteristic: Static value. */ + .uuid = &gatt_svr_chr_sec_test_static_uuid.u, + .access_cb = gatt_svr_chr_access_sec_test, + .flags = BLE_GATT_CHR_F_READ | + BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC, + }, { + 0, /* No more characteristics in this service. */ + } }, + }, + + { + 0, /* No more services. */ + }, +}; + +static int +gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len, + void *dst, uint16_t *len) +{ + uint16_t om_len; + int rc; + + om_len = OS_MBUF_PKTLEN(om); + if (om_len < min_len || om_len > max_len) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + rc = ble_hs_mbuf_to_flat(om, dst, max_len, len); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } + + return 0; +} + +#define GATT_SVR_NEW_ALERT_VAL_MAX_LEN 64 + +static const uint8_t gatt_svr_new_alert_cat = 0x01; /* Simple alert. */ +static uint8_t gatt_svr_new_alert_val[GATT_SVR_NEW_ALERT_VAL_MAX_LEN]; +static uint16_t gatt_svr_new_alert_val_len; +static const uint8_t gatt_svr_unr_alert_cat = 0x01; /* Simple alert. */ +static uint16_t gatt_svr_unr_alert_stat; +static uint16_t gatt_svr_alert_not_ctrl_pt; + +static int +gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg) +{ + uint16_t uuid16; + int rc; + + uuid16 = ble_uuid_u16(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID: + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + rc = os_mbuf_append(ctxt->om, &gatt_svr_new_alert_cat, + sizeof gatt_svr_new_alert_cat); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + + case GATT_SVR_CHR_NEW_ALERT: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(ctxt->om, 0, + sizeof gatt_svr_new_alert_val, + gatt_svr_new_alert_val, + &gatt_svr_new_alert_val_len); + return rc; + } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = os_mbuf_append(ctxt->om, &gatt_svr_new_alert_val, + sizeof gatt_svr_new_alert_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + + case GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID: + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + rc = os_mbuf_append(ctxt->om, &gatt_svr_unr_alert_cat, + sizeof gatt_svr_unr_alert_cat); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + + case GATT_SVR_CHR_UNR_ALERT_STAT_UUID: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(ctxt->om, 2, 2, &gatt_svr_unr_alert_stat, + NULL); + return rc; + } else { + rc = os_mbuf_append(ctxt->om, &gatt_svr_unr_alert_stat, + sizeof gatt_svr_unr_alert_stat); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + + case GATT_SVR_CHR_ALERT_NOT_CTRL_PT: + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = gatt_svr_chr_write(ctxt->om, 2, 2, + &gatt_svr_alert_not_ctrl_pt, NULL); + } else { + rc = BLE_ATT_ERR_UNLIKELY; + } + return rc; + + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } +} + +static int +gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, + void *arg) +{ + const ble_uuid_t *uuid; + int rand_num; + int rc; + + uuid = ctxt->chr->uuid; + + /* Determine which characteristic is being accessed by examining its + * 128-bit UUID. + */ + + if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_rand_uuid.u) == 0) { + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + + /* Respond with a 32-bit random number. */ + rand_num = rand(); + rc = os_mbuf_append(ctxt->om, &rand_num, sizeof rand_num); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + } + + if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_static_uuid.u) == 0) { + switch (ctxt->op) { + case BLE_GATT_ACCESS_OP_READ_CHR: + rc = os_mbuf_append(ctxt->om, &gatt_svr_sec_test_static_val, + sizeof gatt_svr_sec_test_static_val); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; + + case BLE_GATT_ACCESS_OP_WRITE_CHR: + rc = gatt_svr_chr_write(ctxt->om, + sizeof gatt_svr_sec_test_static_val, + sizeof gatt_svr_sec_test_static_val, + &gatt_svr_sec_test_static_val, NULL); + return rc; + + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } + } + + /* Unknown characteristic; the nimble stack should not have called this + * function. + */ + assert(0); + return BLE_ATT_ERR_UNLIKELY; +} + +void +gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) +{ + char buf[BLE_UUID_STR_LEN]; + + switch (ctxt->op) { + case BLE_GATT_REGISTER_OP_SVC: + BLEPRPH_LOG(DEBUG, "registered service %s with handle=%d\n", + ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), + ctxt->svc.handle); + break; + + case BLE_GATT_REGISTER_OP_CHR: + BLEPRPH_LOG(DEBUG, "registering characteristic %s with " + "def_handle=%d val_handle=%d\n", + ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), + ctxt->chr.def_handle, + ctxt->chr.val_handle); + break; + + case BLE_GATT_REGISTER_OP_DSC: + BLEPRPH_LOG(DEBUG, "registering descriptor %s with handle=%d\n", + ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), + ctxt->dsc.handle); + break; + + default: + assert(0); + break; + } +} + +int +gatt_svr_init(void) +{ + int rc; + + rc = ble_gatts_count_cfg(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + rc = ble_gatts_add_svcs(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + + return 0; +} + +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/75e65613/apps/sensors_test/src/main.c ---------------------------------------------------------------------- diff --git a/apps/sensors_test/src/main.c b/apps/sensors_test/src/main.c index 81dcc9f..322b83b 100755 --- a/apps/sensors_test/src/main.c +++ b/apps/sensors_test/src/main.c @@ -42,13 +42,13 @@ #endif #include <bootutil/image.h> #include <bootutil/bootutil.h> -#include <imgmgr/imgmgr.h> #include <assert.h> #include <string.h> #include <flash_test/flash_test.h> #include <reboot/log_reboot.h> #include <id/id.h> +#if MYNEWT_VAL(SENSOR_BLE_OIC) /* BLE */ #include <nimble/ble.h> #include <host/ble_hs.h> @@ -61,6 +61,13 @@ /* Application-specified header. */ #include "bleprph.h" +static int sensor_oic_gap_event(struct ble_gap_event *event, void *arg); + +/** Log data. */ +struct log bleprph_log; + +#endif + #ifdef ARCH_sim #include <mcu/mcu_sim.h> #endif @@ -76,24 +83,16 @@ static volatile int g_task1_loops; #define TASK2_PRIO (9) #define TASK2_STACK_SIZE OS_STACK_ALIGN(64) static struct os_task task2; - -static int sensor_oic_gap_event(struct ble_gap_event *event, void *arg); - -/** Log data. */ -struct log bleprph_log; +static volatile int g_task2_loops; static struct log my_log; -static volatile int g_task2_loops; - /* Global test semaphore */ static struct os_sem g_test_sem; /* For LED toggling */ static int g_led_pin; -extern int oc_stack_errno; - STATS_SECT_START(gpio_stats) STATS_SECT_ENTRY(toggles) STATS_SECT_END @@ -124,6 +123,9 @@ static char test_str[32]; static uint32_t cbmem_buf[MAX_CBMEM_BUF]; static struct cbmem cbmem; +#if MYNEWT_VAL(SENSOR_BLE_OIC) +extern int oc_stack_errno; + static const oc_handler_t sensor_oic_handler = { .init = sensor_oic_init, }; @@ -332,6 +334,7 @@ sensor_oic_gap_event(struct ble_gap_event *event, void *arg) return 0; } +#endif static char * test_conf_get(int argc, char **argv, char *buf, int max_len) @@ -383,19 +386,12 @@ task1_handler(void *arg) { struct os_task *t; int prev_pin_state, curr_pin_state; - struct image_version ver; /* Set the led pin for the E407 devboard */ g_led_pin = LED_BLINK_PIN; hal_gpio_init_out(g_led_pin, 1); - if (imgr_my_version(&ver) == 0) { - console_printf("\nSensors Test %u.%u.%u.%u\n", - ver.iv_major, ver.iv_minor, ver.iv_revision, - (unsigned int)ver.iv_build_num); - } else { - console_printf("\nSensors Test\n"); - } + console_printf("\nSensors Test App\n"); while (1) { t = os_sched_get_current_task(); @@ -578,9 +574,8 @@ err: return rc; } -#endif +#else -#ifdef ARCH_sim static int config_sensor(void) { @@ -616,6 +611,70 @@ err: } #endif +static void +sensors_dev_shell_init(void) +{ + +#if MYNEWT_VAL(TCS34725_CLI) + tcs34725_shell_init(); +#endif + +#if MYNEWT_VAL(TSL2561_CLI) + tsl2561_shell_init(); +#endif + +#if MYNEWT_VAL(BNO055_CLI) + bno055_shell_init(); +#endif + +} + +static void +sensor_ble_oic_server_init(void) +{ +#if MYNEWT_VAL(SENSOR_BLE_OIC) + int rc; + + /* Set initial BLE device address. */ + memcpy(g_dev_addr, (uint8_t[6]){0x0a, 0xfa, 0xcf, 0xac, 0xfa, 0xc0}, 6); + + oc_ble_coap_gatt_srv_init(); + + ble_hs_cfg.reset_cb = sensor_oic_on_reset; + ble_hs_cfg.sync_cb = sensor_oic_on_sync; + ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb; + + /* Set the default device name. */ + rc = ble_svc_gap_device_name_set("pi"); + assert(rc == 0); + + rc = oc_main_init((oc_handler_t *)&sensor_oic_handler); + assert(!rc); + + oc_init_platform("MyNewt", NULL, NULL); + oc_add_device("/oic/d", "oic.d.pi", "pi", "1.0", "1.0", NULL, + NULL); + assert(!oc_stack_errno); +#endif +} + +static void +ble_oic_log_init(void) +{ +#if MYNEWT_VAL(SENSOR_BLE_OIC) + /* Initialize the bleprph log. */ + log_register("bleprph", &bleprph_log, &log_console_handler, NULL, + LOG_SYSLEVEL); + + /* Initialize the NimBLE host configuration. */ + log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL, + LOG_SYSLEVEL); + + /* Initialize the OIC */ + log_register("oic", &oc_log, &log_console_handler, NULL, LOG_SYSLEVEL); +#endif +} + /** * main * @@ -648,19 +707,7 @@ main(int argc, char **argv) stats_register("gpio_toggle", STATS_HDR(g_stats_gpio_toggle)); - /* Set initial BLE device address. */ - memcpy(g_dev_addr, (uint8_t[6]){0x0a, 0xfa, 0xcf, 0xac, 0xfa, 0xc0}, 6); - - /* Initialize the bleprph log. */ - log_register("bleprph", &bleprph_log, &log_console_handler, NULL, - LOG_SYSLEVEL); - - /* Initialize the NimBLE host configuration. */ - log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL, - LOG_SYSLEVEL); - - /* Initialize the OIC */ - log_register("oic", &oc_log, &log_console_handler, NULL, LOG_SYSLEVEL); + ble_oic_log_init(); flash_test_init(); @@ -683,37 +730,11 @@ main(int argc, char **argv) } #endif -#if MYNEWT_VAL(TCS34725_CLI) - tcs34725_shell_init(); -#endif - -#if MYNEWT_VAL(TSL2561_CLI) - tsl2561_shell_init(); -#endif - -#if MYNEWT_VAL(BNO055_CLI) - bno055_shell_init(); -#endif + sensors_dev_shell_init(); config_sensor(); - oc_ble_coap_gatt_srv_init(); - - ble_hs_cfg.reset_cb = sensor_oic_on_reset; - ble_hs_cfg.sync_cb = sensor_oic_on_sync; - ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb; - - /* Set the default device name. */ - rc = ble_svc_gap_device_name_set("pi"); - assert(rc == 0); - - rc = oc_main_init((oc_handler_t *)&sensor_oic_handler); - assert(!rc); - - oc_init_platform("MyNewt", NULL, NULL); - oc_add_device("/oic/d", "oic.d.color", "color0", "1.0", "1.0", NULL, - NULL); - assert(!oc_stack_errno); + sensor_ble_oic_server_init(); /* * As the last thing, process events from default event queue. http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/75e65613/apps/sensors_test/syscfg.yml ---------------------------------------------------------------------- diff --git a/apps/sensors_test/syscfg.yml b/apps/sensors_test/syscfg.yml index 04adddc..8623667 100644 --- a/apps/sensors_test/syscfg.yml +++ b/apps/sensors_test/syscfg.yml @@ -45,7 +45,6 @@ syscfg.vals: BNO055_CLI: 1 TCS34725_CLI: 1 SENSOR_BLE_OIC: 1 - BLE_ROLE_CENTRAL: 0 BLE_ROLE_OBSERVER: 0 OC_SERVER: 1 @@ -70,4 +69,3 @@ syscfg.defs: SIM_ACCEL_PRESENT: description: 'SIM ACCEL is present' value : 0 - http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/75e65613/hw/sensor/pkg.yml ---------------------------------------------------------------------- diff --git a/hw/sensor/pkg.yml b/hw/sensor/pkg.yml index c83dcf1..bdd0e0b 100644 --- a/hw/sensor/pkg.yml +++ b/hw/sensor/pkg.yml @@ -24,13 +24,6 @@ pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: - - net/nimble/controller - - net/nimble/host - - net/nimble/host/services/gap - - net/nimble/host/services/gatt - - net/nimble/host/store/ram - - net/nimble/transport/ram - - mgmt/oicmgr - sys/shell - sys/console/full - sys/log/full http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/75e65613/hw/sensor/src/gatt_svr.c ---------------------------------------------------------------------- diff --git a/hw/sensor/src/gatt_svr.c b/hw/sensor/src/gatt_svr.c deleted file mode 100644 index 659a9c1..0000000 --- a/hw/sensor/src/gatt_svr.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include <assert.h> -#include <stdio.h> -#include <string.h> -#include "bsp/bsp.h" -#include "host/ble_hs.h" -#include "bleprph.h" - -/** - * The vendor specific security test service consists of two characteristics: - * o random-number-generator: generates a random 32-bit number each time - * it is read. This characteristic can only be read over an encrypted - * connection. - * o static-value: a single-byte characteristic that can always be read, - * but can only be written over an encrypted connection. - */ - -/* 59462f12-9543-9999-12c8-58b459a2712d */ -static const ble_uuid128_t gatt_svr_svc_sec_test_uuid = - BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12, \ - 0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59); - -/* 5c3a659e-897e-45e1-b016-007107c96df6 */ -static const ble_uuid128_t gatt_svr_chr_sec_test_rand_uuid = - BLE_UUID128_INIT(0xf6, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, \ - 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c); - -/* 5c3a659e-897e-45e1-b016-007107c96df7 */ -static const ble_uuid128_t gatt_svr_chr_sec_test_static_uuid = - BLE_UUID128_INIT(0xf7, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, \ - 0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c); - -static uint8_t gatt_svr_sec_test_static_val; - -static int -gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg); - -static int -gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg); - -static const struct ble_gatt_svc_def gatt_svr_svcs[] = { - { - /*** Alert Notification Service. */ - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = BLE_UUID16_DECLARE(GATT_SVR_SVC_ALERT_UUID), - .characteristics = (struct ble_gatt_chr_def[]) { { - .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID), - .access_cb = gatt_svr_chr_access_alert, - .flags = BLE_GATT_CHR_F_READ, - }, { - .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_NEW_ALERT), - .access_cb = gatt_svr_chr_access_alert, - .flags = BLE_GATT_CHR_F_NOTIFY, - }, { - .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID), - .access_cb = gatt_svr_chr_access_alert, - .flags = BLE_GATT_CHR_F_READ, - }, { - .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_UNR_ALERT_STAT_UUID), - .access_cb = gatt_svr_chr_access_alert, - .flags = BLE_GATT_CHR_F_NOTIFY, - }, { - .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_ALERT_NOT_CTRL_PT), - .access_cb = gatt_svr_chr_access_alert, - .flags = BLE_GATT_CHR_F_WRITE, - }, { - 0, /* No more characteristics in this service. */ - } }, - }, - - { - /*** Service: Security test. */ - .type = BLE_GATT_SVC_TYPE_PRIMARY, - .uuid = &gatt_svr_svc_sec_test_uuid.u, - .characteristics = (struct ble_gatt_chr_def[]) { { - /*** Characteristic: Random number generator. */ - .uuid = &gatt_svr_chr_sec_test_rand_uuid.u, - .access_cb = gatt_svr_chr_access_sec_test, - .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC, - }, { - /*** Characteristic: Static value. */ - .uuid = &gatt_svr_chr_sec_test_static_uuid.u, - .access_cb = gatt_svr_chr_access_sec_test, - .flags = BLE_GATT_CHR_F_READ | - BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC, - }, { - 0, /* No more characteristics in this service. */ - } }, - }, - - { - 0, /* No more services. */ - }, -}; - -static int -gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len, - void *dst, uint16_t *len) -{ - uint16_t om_len; - int rc; - - om_len = OS_MBUF_PKTLEN(om); - if (om_len < min_len || om_len > max_len) { - return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; - } - - rc = ble_hs_mbuf_to_flat(om, dst, max_len, len); - if (rc != 0) { - return BLE_ATT_ERR_UNLIKELY; - } - - return 0; -} - -#define GATT_SVR_NEW_ALERT_VAL_MAX_LEN 64 - -static const uint8_t gatt_svr_new_alert_cat = 0x01; /* Simple alert. */ -static uint8_t gatt_svr_new_alert_val[GATT_SVR_NEW_ALERT_VAL_MAX_LEN]; -static uint16_t gatt_svr_new_alert_val_len; -static const uint8_t gatt_svr_unr_alert_cat = 0x01; /* Simple alert. */ -static uint16_t gatt_svr_unr_alert_stat; -static uint16_t gatt_svr_alert_not_ctrl_pt; - -static int -gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) -{ - uint16_t uuid16; - int rc; - - uuid16 = ble_uuid_u16(ctxt->chr->uuid); - assert(uuid16 != 0); - - switch (uuid16) { - case GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID: - assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); - rc = os_mbuf_append(ctxt->om, &gatt_svr_new_alert_cat, - sizeof gatt_svr_new_alert_cat); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - - case GATT_SVR_CHR_NEW_ALERT: - if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(ctxt->om, 0, - sizeof gatt_svr_new_alert_val, - gatt_svr_new_alert_val, - &gatt_svr_new_alert_val_len); - return rc; - } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { - rc = os_mbuf_append(ctxt->om, &gatt_svr_new_alert_val, - sizeof gatt_svr_new_alert_val); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - } - - case GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID: - assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); - rc = os_mbuf_append(ctxt->om, &gatt_svr_unr_alert_cat, - sizeof gatt_svr_unr_alert_cat); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - - case GATT_SVR_CHR_UNR_ALERT_STAT_UUID: - if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(ctxt->om, 2, 2, &gatt_svr_unr_alert_stat, - NULL); - return rc; - } else { - rc = os_mbuf_append(ctxt->om, &gatt_svr_unr_alert_stat, - sizeof gatt_svr_unr_alert_stat); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - } - - case GATT_SVR_CHR_ALERT_NOT_CTRL_PT: - if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { - rc = gatt_svr_chr_write(ctxt->om, 2, 2, - &gatt_svr_alert_not_ctrl_pt, NULL); - } else { - rc = BLE_ATT_ERR_UNLIKELY; - } - return rc; - - default: - assert(0); - return BLE_ATT_ERR_UNLIKELY; - } -} - -static int -gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle, - struct ble_gatt_access_ctxt *ctxt, - void *arg) -{ - const ble_uuid_t *uuid; - int rand_num; - int rc; - - uuid = ctxt->chr->uuid; - - /* Determine which characteristic is being accessed by examining its - * 128-bit UUID. - */ - - if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_rand_uuid.u) == 0) { - assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); - - /* Respond with a 32-bit random number. */ - rand_num = rand(); - rc = os_mbuf_append(ctxt->om, &rand_num, sizeof rand_num); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - } - - if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_static_uuid.u) == 0) { - switch (ctxt->op) { - case BLE_GATT_ACCESS_OP_READ_CHR: - rc = os_mbuf_append(ctxt->om, &gatt_svr_sec_test_static_val, - sizeof gatt_svr_sec_test_static_val); - return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; - - case BLE_GATT_ACCESS_OP_WRITE_CHR: - rc = gatt_svr_chr_write(ctxt->om, - sizeof gatt_svr_sec_test_static_val, - sizeof gatt_svr_sec_test_static_val, - &gatt_svr_sec_test_static_val, NULL); - return rc; - - default: - assert(0); - return BLE_ATT_ERR_UNLIKELY; - } - } - - /* Unknown characteristic; the nimble stack should not have called this - * function. - */ - assert(0); - return BLE_ATT_ERR_UNLIKELY; -} - -void -gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) -{ - char buf[BLE_UUID_STR_LEN]; - - switch (ctxt->op) { - case BLE_GATT_REGISTER_OP_SVC: - BLEPRPH_LOG(DEBUG, "registered service %s with handle=%d\n", - ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf), - ctxt->svc.handle); - break; - - case BLE_GATT_REGISTER_OP_CHR: - BLEPRPH_LOG(DEBUG, "registering characteristic %s with " - "def_handle=%d val_handle=%d\n", - ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf), - ctxt->chr.def_handle, - ctxt->chr.val_handle); - break; - - case BLE_GATT_REGISTER_OP_DSC: - BLEPRPH_LOG(DEBUG, "registering descriptor %s with handle=%d\n", - ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf), - ctxt->dsc.handle); - break; - - default: - assert(0); - break; - } -} - -int -gatt_svr_init(void) -{ - int rc; - - rc = ble_gatts_count_cfg(gatt_svr_svcs); - if (rc != 0) { - return rc; - } - - rc = ble_gatts_add_svcs(gatt_svr_svcs); - if (rc != 0) { - return rc; - } - - return 0; -}