MYNEWT-729 SensorAPI: Send sensor data over OIC - Initial commit sensor oic ble
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/878cdc4f Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/878cdc4f Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/878cdc4f Branch: refs/heads/master Commit: 878cdc4fab9bc7aacb082d3ae4ea239d4b4e77ba Parents: f5c02fe Author: Vipul Rahane <vipulrah...@apache.org> Authored: Fri Apr 7 14:42:42 2017 -0700 Committer: Vipul Rahane <vipulrah...@apache.org> Committed: Mon Apr 17 16:14:20 2017 -0700 ---------------------------------------------------------------------- apps/sensors_test/pkg.yml | 3 - apps/sensors_test/src/main.c | 10 +- apps/sensors_test/syscfg.yml | 12 +- hw/sensor/include/sensor/quat.h | 3 +- hw/sensor/include/sensor/sensor.h | 4 + hw/sensor/pkg.yml | 13 + hw/sensor/src/bleprph.h | 59 +++ hw/sensor/src/gatt_svr.c | 309 +++++++++++++++ hw/sensor/src/misc.c | 43 ++ hw/sensor/src/sensor_oic.c | 603 +++++++++++++++++++++++++++++ hw/sensor/syscfg.yml | 13 + kernel/os/syscfg.yml | 2 +- net/oic/src/api/oc_core_res.c | 4 + net/oic/src/port/mynewt/ble_adaptor.c | 1 - net/oic/syscfg.yml | 2 +- 15 files changed, 1068 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/apps/sensors_test/pkg.yml ---------------------------------------------------------------------- diff --git a/apps/sensors_test/pkg.yml b/apps/sensors_test/pkg.yml index 41db418..8ea0ffe 100644 --- a/apps/sensors_test/pkg.yml +++ b/apps/sensors_test/pkg.yml @@ -26,9 +26,6 @@ pkg.keywords: pkg.deps: - test/flash_test - - mgmt/imgmgr - - mgmt/newtmgr - - mgmt/newtmgr/transport/nmgr_shell - kernel/os - hw/sensor - hw/drivers/sensors/sim http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/apps/sensors_test/src/main.c ---------------------------------------------------------------------- diff --git a/apps/sensors_test/src/main.c b/apps/sensors_test/src/main.c index 42cdd10..d6bc12c 100755 --- a/apps/sensors_test/src/main.c +++ b/apps/sensors_test/src/main.c @@ -40,7 +40,6 @@ #if MYNEWT_VAL(SPLIT_LOADER) #include "split/split.h" #endif -#include <newtmgr/newtmgr.h> #include <bootutil/image.h> #include <bootutil/bootutil.h> #include <imgmgr/imgmgr.h> @@ -50,6 +49,7 @@ #include <reboot/log_reboot.h> #include <os/os_time.h> #include <id/id.h> +#include <oic/oc_api.h> #ifdef ARCH_sim #include <mcu/mcu_sim.h> @@ -107,6 +107,10 @@ static char test_str[32]; static uint32_t cbmem_buf[MAX_CBMEM_BUF]; static struct cbmem cbmem; +static const oc_handler_t sensor_oic_handler = { + .init = sensor_oic_init, +}; + static char * test_conf_get(int argc, char **argv, char *buf, int max_len) { @@ -407,7 +411,7 @@ main(int argc, char **argv) #ifdef ARCH_sim mcu_sim_parse_args(argc, argv); #endif - + /* Initialize OS */ sysinit(); rc = conf_register(&test_conf_handler); @@ -422,6 +426,8 @@ main(int argc, char **argv) stats_register("gpio_toggle", STATS_HDR(g_stats_gpio_toggle)); + oc_main_init((oc_handler_t *)&sensor_oic_handler); + flash_test_init(); conf_load(); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/apps/sensors_test/syscfg.yml ---------------------------------------------------------------------- diff --git a/apps/sensors_test/syscfg.yml b/apps/sensors_test/syscfg.yml index 6b70b6a..5097574 100644 --- a/apps/sensors_test/syscfg.yml +++ b/apps/sensors_test/syscfg.yml @@ -37,13 +37,19 @@ syscfg.vals: CONFIG_CLI: 1 # Enable newtmgr commands. - STATS_NEWTMGR: 1 - LOG_NEWTMGR: 1 - CONFIG_NEWTMGR: 1 + STATS_NEWTMGR: 0 + LOG_NEWTMGR: 0 + CONFIG_NEWTMGR: 0 TSL2561_CLI: 0 BNO055_CLI: 0 TCS34725_CLI: 1 + SENSOR_BLE_OIC: 1 + + BLE_ROLE_CENTRAL: 0 + BLE_ROLE_OBSERVER: 0 + OC_SERVER: 1 + OC_TRANSPORT_GATT: 1 syscfg.defs: TSL2561_PRESENT: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/hw/sensor/include/sensor/quat.h ---------------------------------------------------------------------- diff --git a/hw/sensor/include/sensor/quat.h b/hw/sensor/include/sensor/quat.h index 77f96b7..5cfb454 100644 --- a/hw/sensor/include/sensor/quat.h +++ b/hw/sensor/include/sensor/quat.h @@ -28,8 +28,7 @@ extern "C" { #endif -/* Data representing a singular read from an accelerometer. - * All values are in MS^2 +/* Data representing a singular read from a quat sensor. */ struct sensor_quat_data { float sqd_x; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/hw/sensor/include/sensor/sensor.h ---------------------------------------------------------------------- diff --git a/hw/sensor/include/sensor/sensor.h b/hw/sensor/include/sensor/sensor.h index c3bc8fc..9435106 100644 --- a/hw/sensor/include/sensor/sensor.h +++ b/hw/sensor/include/sensor/sensor.h @@ -343,6 +343,10 @@ int sensor_shell_stol(char *param_val, long min, long max, long *output); #endif +#if MYNEWT_VAL(SENSOR_BLE_OIC) +void sensor_oic_init(void); +#endif + /** * }@ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/hw/sensor/pkg.yml ---------------------------------------------------------------------- diff --git a/hw/sensor/pkg.yml b/hw/sensor/pkg.yml index 4fe022d..c83dcf1 100644 --- a/hw/sensor/pkg.yml +++ b/hw/sensor/pkg.yml @@ -23,6 +23,19 @@ pkg.author: "Apache Mynewt <d...@mynewt.incubator.apache.org>" 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 + - sys/stats/full pkg.init: sensor_pkg_init: 501 + http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/hw/sensor/src/bleprph.h ---------------------------------------------------------------------- diff --git a/hw/sensor/src/bleprph.h b/hw/sensor/src/bleprph.h new file mode 100644 index 0000000..2e3f024 --- /dev/null +++ b/hw/sensor/src/bleprph.h @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#ifndef H_BLEPRPH_ +#define H_BLEPRPH_ + +#include "log/log.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_cfg; +struct ble_gatt_register_ctxt; + +extern struct log bleprph_log; + +/* bleprph uses the first "peruser" log module. */ +#define BLEPRPH_LOG_MODULE (LOG_MODULE_PERUSER + 0) + +/* Convenience macro for logging to the bleprph module. */ +#define BLEPRPH_LOG(lvl, ...) \ + LOG_ ## lvl(&bleprph_log, BLEPRPH_LOG_MODULE, __VA_ARGS__) + +/** GATT server. */ +#define GATT_SVR_SVC_ALERT_UUID 0x1811 +#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47 +#define GATT_SVR_CHR_NEW_ALERT 0x2A46 +#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID 0x2A48 +#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID 0x2A45 +#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT 0x2A44 + +void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); +int gatt_svr_init(void); + +/** Misc. */ +void print_bytes(const uint8_t *bytes, int len); +void print_addr(const void *addr); + +#ifdef __cplusplus +} +#endif + +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/hw/sensor/src/gatt_svr.c ---------------------------------------------------------------------- diff --git a/hw/sensor/src/gatt_svr.c b/hw/sensor/src/gatt_svr.c new file mode 100644 index 0000000..659a9c1 --- /dev/null +++ b/hw/sensor/src/gatt_svr.c @@ -0,0 +1,309 @@ +/* + * 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; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/hw/sensor/src/misc.c ---------------------------------------------------------------------- diff --git a/hw/sensor/src/misc.c b/hw/sensor/src/misc.c new file mode 100644 index 0000000..8ec785e --- /dev/null +++ b/hw/sensor/src/misc.c @@ -0,0 +1,43 @@ +/* + * 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 "bleprph.h" + +/** + * Utility function to log an array of bytes. + */ +void +print_bytes(const uint8_t *bytes, int len) +{ + int i; + + for (i = 0; i < len; i++) { + BLEPRPH_LOG(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]); + } +} + +void +print_addr(const void *addr) +{ + const uint8_t *u8p; + + u8p = addr; + BLEPRPH_LOG(INFO, "%02x:%02x:%02x:%02x:%02x:%02x", + u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/hw/sensor/src/sensor_oic.c ---------------------------------------------------------------------- diff --git a/hw/sensor/src/sensor_oic.c b/hw/sensor/src/sensor_oic.c new file mode 100644 index 0000000..7069be0 --- /dev/null +++ b/hw/sensor/src/sensor_oic.c @@ -0,0 +1,603 @@ +/* + * 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 <string.h> +#include <stdio.h> +#include <errno.h> +#include <assert.h> + +#include "defs/error.h" + +#include "os/os.h" + +#include "sensor/sensor.h" +#include "sensor/accel.h" +#include "sensor/mag.h" +#include "sensor/light.h" +#include "sensor/quat.h" +#include "sensor/euler.h" +#include "sensor/color.h" +#include "console/console.h" + +/* BLE */ +#include <nimble/ble.h> +#include <host/ble_hs.h> +#include <services/gap/ble_svc_gap.h> + +/* OIC */ +#include <oic/oc_gatt.h> +#include <oic/oc_rep.h> +#include <oic/oc_ri.h> +#include <oic/oc_api.h> + +/* Application-specified header. */ +#include "bleprph.h" + +/** Log data. */ +struct log bleprph_log; +static int sensor_oic_gap_event(struct ble_gap_event *event, void *arg); + +/** + * Logs information about a connection to the console. + */ +static void +sensor_oic_print_conn_desc(struct ble_gap_conn_desc *desc) +{ + BLEPRPH_LOG(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=", + desc->conn_handle, desc->our_ota_addr.type); + print_addr(desc->our_ota_addr.val); + BLEPRPH_LOG(INFO, " our_id_addr_type=%d our_id_addr=", + desc->our_id_addr.type); + print_addr(desc->our_id_addr.val); + BLEPRPH_LOG(INFO, " peer_ota_addr_type=%d peer_ota_addr=", + desc->peer_ota_addr.type); + print_addr(desc->peer_ota_addr.val); + BLEPRPH_LOG(INFO, " peer_id_addr_type=%d peer_id_addr=", + desc->peer_id_addr.type); + print_addr(desc->peer_id_addr.val); + BLEPRPH_LOG(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d " + "encrypted=%d authenticated=%d bonded=%d\n", + desc->conn_itvl, desc->conn_latency, + desc->supervision_timeout, + desc->sec_state.encrypted, + desc->sec_state.authenticated, + desc->sec_state.bonded); +} + +/** + * Enables advertising with the following parameters: + * o General discoverable mode. + * o Undirected connectable mode. + */ +static void +sensor_oic_advertise(void) +{ + struct ble_gap_adv_params adv_params; + struct ble_hs_adv_fields fields; + const char *name; + int rc; + + /** + * Set the advertisement data included in our advertisements: + * o Flags (indicates advertisement type and other general info). + * o Advertising tx power. + * o Device name. + * o 16-bit service UUIDs (alert notifications). + */ + + memset(&fields, 0, sizeof fields); + + /* Advertise two flags: + * o Discoverability in forthcoming advertisement (general) + * o BLE-only (BR/EDR unsupported). + */ + fields.flags = BLE_HS_ADV_F_DISC_GEN | + BLE_HS_ADV_F_BREDR_UNSUP; + + /* Indicate that the TX power level field should be included; have the + * stack fill this value automatically. This is done by assiging the + * special value BLE_HS_ADV_TX_PWR_LVL_AUTO. + */ + fields.tx_pwr_lvl_is_present = 1; + fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; + + name = ble_svc_gap_device_name(); + fields.name = (uint8_t *)name; + fields.name_len = strlen(name); + fields.name_is_complete = 1; + + fields.uuids128 = (ble_uuid128_t []) { + BLE_UUID128_INIT(OC_GATT_SERVICE_UUID) + }; + fields.num_uuids128 = 1; + fields.uuids128_is_complete = 1; + + rc = ble_gap_adv_set_fields(&fields); + if (rc != 0) { + BLEPRPH_LOG(ERROR, "error setting advertisement data; rc=%d\n", rc); + return; + } + + /* Begin advertising. */ + memset(&adv_params, 0, sizeof adv_params); + adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; + adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + rc = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, + &adv_params, sensor_oic_gap_event, NULL); + if (rc != 0) { + BLEPRPH_LOG(ERROR, "error enabling advertisement; rc=%d\n", rc); + return; + } +} + +/** + * The nimble host executes this callback when a GAP event occurs. The + * application associates a GAP event callback with each connection that forms. + * sensor_oic uses the same callback for all connections. + * + * @param event The type of event being signalled. + * @param ctxt Various information pertaining to the event. + * @param arg Application-specified argument; unuesd by + * sensor_oic. + * + * @return 0 if the application successfully handled the + * event; nonzero on failure. The semantics + * of the return code is specific to the + * particular GAP event being signalled. + */ +static int +sensor_oic_gap_event(struct ble_gap_event *event, void *arg) +{ + struct ble_gap_conn_desc desc; + int rc; + + switch (event->type) { + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + BLEPRPH_LOG(INFO, "connection %s; status=%d ", + event->connect.status == 0 ? "established" : "failed", + event->connect.status); + if (event->connect.status == 0) { + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + sensor_oic_print_conn_desc(&desc); + } + BLEPRPH_LOG(INFO, "\n"); + + if (event->connect.status != 0) { + /* Connection failed; resume advertising. */ + sensor_oic_advertise(); + } else { + oc_ble_coap_conn_new(event->connect.conn_handle); + } + return 0; + + case BLE_GAP_EVENT_DISCONNECT: + BLEPRPH_LOG(INFO, "disconnect; reason=%d ", event->disconnect.reason); + sensor_oic_print_conn_desc(&event->disconnect.conn); + BLEPRPH_LOG(INFO, "\n"); + + oc_ble_coap_conn_del(event->disconnect.conn.conn_handle); + + /* Connection terminated; resume advertising. */ + sensor_oic_advertise(); + return 0; + + case BLE_GAP_EVENT_CONN_UPDATE: + /* The central has updated the connection parameters. */ + BLEPRPH_LOG(INFO, "connection updated; status=%d ", + event->conn_update.status); + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + sensor_oic_print_conn_desc(&desc); + BLEPRPH_LOG(INFO, "\n"); + return 0; + + case BLE_GAP_EVENT_ENC_CHANGE: + /* Encryption has been enabled or disabled for this connection. */ + BLEPRPH_LOG(INFO, "encryption change event; status=%d ", + event->enc_change.status); + rc = ble_gap_conn_find(event->connect.conn_handle, &desc); + assert(rc == 0); + sensor_oic_print_conn_desc(&desc); + BLEPRPH_LOG(INFO, "\n"); + return 0; + + case BLE_GAP_EVENT_SUBSCRIBE: + BLEPRPH_LOG(INFO, "subscribe event; conn_handle=%d attr_handle=%d " + "reason=%d prevn=%d curn=%d previ=%d curi=%d\n", + event->subscribe.conn_handle, + event->subscribe.attr_handle, + event->subscribe.reason, + event->subscribe.prev_notify, + event->subscribe.cur_notify, + event->subscribe.prev_indicate, + event->subscribe.cur_indicate); + return 0; + + case BLE_GAP_EVENT_MTU: + BLEPRPH_LOG(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n", + event->mtu.conn_handle, + event->mtu.channel_id, + event->mtu.value); + return 0; + } + + return 0; +} + + +static void +sensor_oic_on_reset(int reason) +{ + BLEPRPH_LOG(ERROR, "Resetting state; reason=%d\n", reason); +} + +static void +sensor_oic_on_sync(void) +{ + /* Begin advertising. */ + sensor_oic_advertise(); +} + + +static int +sensor_oic_encode(struct sensor* sensor, void *arg, void *databuf) +{ + int rc; + + rc = SYS_EINVAL; + switch(SENSOR_TYPE_ALL & (*(uint32_t *)arg)) { + /* Gyroscope supported */ + case SENSOR_TYPE_GYROSCOPE: + /* Accelerometer functionality supported */ + case SENSOR_TYPE_ACCELEROMETER: + /* Linear Accelerometer (Without Gravity) */ + case SENSOR_TYPE_LINEAR_ACCEL: + /* Gravity Sensor */ + case SENSOR_TYPE_GRAVITY: + + if (((struct sensor_accel_data *)(databuf))->sad_x_is_valid) { + oc_rep_set_double(root, x, + ((struct sensor_accel_data *)(databuf))->sad_x); + } else { + goto err; + } + if (((struct sensor_accel_data *)(databuf))->sad_y_is_valid) { + oc_rep_set_double(root, y, + ((struct sensor_accel_data *)(databuf))->sad_y); + } else { + goto err; + } + if (((struct sensor_accel_data *)(databuf))->sad_z_is_valid) { + oc_rep_set_double(root, z, + ((struct sensor_accel_data *)(databuf))->sad_z); + } else { + goto err; + } + break; + + /* Magnetic field supported */ + case SENSOR_TYPE_MAGNETIC_FIELD: + if (((struct sensor_mag_data *)(databuf))->smd_x_is_valid) { + oc_rep_set_double(root, x, + ((struct sensor_mag_data *)(databuf))->smd_x); + } else { + goto err; + } + if (((struct sensor_mag_data *)(databuf))->smd_y_is_valid) { + oc_rep_set_double(root, y, + ((struct sensor_mag_data *)(databuf))->smd_y); + } else { + goto err; + } + if (((struct sensor_mag_data *)(databuf))->smd_z_is_valid) { + oc_rep_set_double(root, z, + ((struct sensor_mag_data *)(databuf))->smd_z); + } else { + goto err; + } + break; + /* Light supported */ + case SENSOR_TYPE_LIGHT: + if (((struct sensor_light_data *)(databuf))->sld_ir_is_valid) { + oc_rep_set_double(root, ir, + ((struct sensor_light_data *)(databuf))->sld_ir); + } else { + goto err; + } + if (((struct sensor_light_data *)(databuf))->sld_full_is_valid) { + oc_rep_set_double(root, full, + ((struct sensor_light_data *)(databuf))->sld_full); + } else { + goto err; + } + if (((struct sensor_light_data *)(databuf))->sld_lux_is_valid) { + oc_rep_set_double(root, lux, + ((struct sensor_light_data *)(databuf))->sld_lux); + } else { + goto err; + } + break; + + /* Temperature supported */ + case SENSOR_TYPE_TEMPERATURE: + oc_rep_set_double(root, temp, *(double *)databuf); + break; + + /* Ambient temperature supported */ + case SENSOR_TYPE_AMBIENT_TEMPERATURE: + oc_rep_set_double(root, ambient_temp, *(double *)databuf); + break; + +#if 0 + /* Pressure sensor supported */ + SENSOR_TYPE_PRESSURE: + oc_rep_set_double(root, pressure, (double *)databuf); + + /* Proximity sensor supported */ + SENSOR_TYPE_PROXIMITY: + + /* Relative humidity supported */ + SENSOR_TYPE_RELATIVE_HUMIDITY: +#endif + /* Rotation vector (quaternion) supported */ + case SENSOR_TYPE_ROTATION_VECTOR: + if (((struct sensor_quat_data *)(databuf))->sqd_x_is_valid) { + oc_rep_set_double(root, x, + ((struct sensor_quat_data *)(databuf))->sqd_x); + } else { + goto err; + } + if (((struct sensor_quat_data *)(databuf))->sqd_y_is_valid) { + oc_rep_set_double(root, y, + ((struct sensor_quat_data *)(databuf))->sqd_y); + } else { + goto err; + } + if (((struct sensor_quat_data *)(databuf))->sqd_z_is_valid) { + oc_rep_set_double(root, z, + ((struct sensor_quat_data *)(databuf))->sqd_z); + } else { + goto err; + } + if (((struct sensor_quat_data *)(databuf))->sqd_w_is_valid) { + oc_rep_set_double(root, w, + ((struct sensor_quat_data *)(databuf))->sqd_w); + } else { + goto err; + } + break; +#if 0 + /* Altitude Supported */ + SENSOR_TYPE_ALTITUDE: + + /* Weight Supported */ + SENSOR_TYPE_WEIGHT: +#endif + /* Euler Orientation Sensor */ + case SENSOR_TYPE_EULER: + if (((struct sensor_euler_data *)(databuf))->sed_h_is_valid) { + oc_rep_set_double(root, h, + ((struct sensor_euler_data *)(databuf))->sed_h); + } else { + goto err; + } + if (((struct sensor_euler_data *)(databuf))->sed_r_is_valid) { + oc_rep_set_double(root, r, + ((struct sensor_euler_data *)(databuf))->sed_r); + } else { + goto err; + } + if (((struct sensor_euler_data *)(databuf))->sed_p_is_valid) { + oc_rep_set_double(root, p, + ((struct sensor_euler_data *)(databuf))->sed_p); + } else { + goto err; + } + break; + + /* Color Sensor */ + case SENSOR_TYPE_COLOR: + if (((struct sensor_color_data *)(databuf))->scd_r_is_valid) { + oc_rep_set_uint(root, r, + ((struct sensor_color_data *)(databuf))->scd_r); + } else { + goto err; + } + if (((struct sensor_color_data *)(databuf))->scd_g_is_valid) { + oc_rep_set_uint(root, g, + ((struct sensor_color_data *)(databuf))->scd_g); + } else { + goto err; + } + if (((struct sensor_color_data *)(databuf))->scd_b_is_valid) { + oc_rep_set_uint(root, b, + ((struct sensor_color_data *)(databuf))->scd_b); + } else { + goto err; + } + if (((struct sensor_color_data *)(databuf))->scd_lux_is_valid) { + oc_rep_set_uint(root, lux, + ((struct sensor_color_data *)(databuf))->scd_lux); + } else { + goto err; + } + if (((struct sensor_color_data *)(databuf))->scd_colortemp_is_valid) { + oc_rep_set_uint(root, colortemp, + ((struct sensor_color_data *)(databuf))->scd_colortemp); + } else { + goto err; + } + if (((struct sensor_color_data *)(databuf))->scd_saturation_is_valid) { + oc_rep_set_uint(root, saturation, + ((struct sensor_color_data *)(databuf))->scd_saturation); + } else { + goto err; + } + if (((struct sensor_color_data *)(databuf))->scd_saturation75_is_valid) { + oc_rep_set_uint(root, saturation75, + ((struct sensor_color_data *)(databuf))->scd_saturation75); + } else { + goto err; + } + if (((struct sensor_color_data *)(databuf))->scd_is_sat_is_valid) { + oc_rep_set_uint(root, is_sat, + ((struct sensor_color_data *)(databuf))->scd_is_sat); + } else { + goto err; + } + if (((struct sensor_color_data *)(databuf))->scd_cratio_is_valid) { + oc_rep_set_double(root, cratio, + ((struct sensor_color_data *)(databuf))->scd_cratio_is_valid); + } else { + goto err; + } + if (((struct sensor_color_data *)(databuf))->scd_maxlux_is_valid) { + oc_rep_set_uint(root, maxlux, + ((struct sensor_color_data *)(databuf))->scd_maxlux); + } else { + goto err; + } + if (((struct sensor_color_data *)(databuf))->scd_ir_is_valid) { + oc_rep_set_uint(root, ir, + ((struct sensor_color_data *)(databuf))->scd_ir); + } else { + goto err; + } + break; + + /* User defined sensor type 1 */ + case SENSOR_TYPE_USER_DEFINED_1: + /* User defined sensor type 2 */ + case SENSOR_TYPE_USER_DEFINED_2: + /* None */ + case SENSOR_TYPE_NONE: + rc = SYS_EINVAL; + goto err; + } + + return 0; +err: + return rc; +} + +static void +sensor_oic_get_data(oc_request_t *request, oc_interface_mask_t interface) +{ + int rc; + struct sensor *sensor; + struct sensor_listener listener; + + /* Look up sensor by name */ + sensor = sensor_mgr_find_next_bydevname("color0", NULL); + if (!sensor) { + console_printf("Sensor %s not found!\n", "color0"); + } + + oc_rep_start_root_object(); + + switch (interface) { + case OC_IF_BASELINE: + oc_process_baseline_interface(request->resource); + case OC_IF_R: + /* Register a listener and then trigger/read a bunch of samples */ + memset(&listener, 0, sizeof(listener)); + + listener.sl_sensor_type = sensor->s_types & SENSOR_TYPE_COLOR; + listener.sl_func = sensor_oic_encode; + listener.sl_arg = (void *)&listener.sl_sensor_type; + + rc = sensor_register_listener(sensor, &listener); + if (rc) { + goto err; + } + + /* Sensor read results. Every time a sensor is read, all of its + * listeners are called by default. Specify NULL as a callback, + * because we just want to run all the listeners. + */ + rc = sensor_read(sensor, listener.sl_sensor_type, NULL, NULL, + OS_TIMEOUT_NEVER); + if (rc) { + goto err; + } + + break; + default: + break; + } + + sensor_unregister_listener(sensor, &listener); + oc_rep_end_root_object(); + oc_send_response(request, OC_STATUS_OK); +err: + sensor_unregister_listener(sensor, &listener); + oc_send_response(request, OC_STATUS_NOT_FOUND); +} + +void +sensor_oic_init(void) +{ + oc_resource_t *res; + int rc; + + /* 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); + 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); + + oc_init_platform("MyNewt", NULL, NULL); + oc_add_device("/oic/d", "oic.d.color", "color0", "1.0", "1.0", NULL, + NULL); + + res = oc_new_resource("/color/1", 1, 0); + oc_resource_bind_resource_type(res, "oic.r.color0"); + oc_resource_bind_resource_interface(res, OC_IF_R); + oc_resource_set_default_interface(res, OC_IF_R); + + oc_resource_set_discoverable(res); + oc_resource_set_periodic_observable(res, 1); + oc_resource_set_request_handler(res, OC_GET, sensor_oic_get_data); + oc_add_resource(res); +} + +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/hw/sensor/syscfg.yml ---------------------------------------------------------------------- diff --git a/hw/sensor/syscfg.yml b/hw/sensor/syscfg.yml index 879fbb2..abe193e 100644 --- a/hw/sensor/syscfg.yml +++ b/hw/sensor/syscfg.yml @@ -26,3 +26,16 @@ syscfg.defs: SENSOR_CLI: description: 'Whether or not to enable the sensor shell support' value: 1 + + SENSOR_BLE_OIC: + description: 'Enable/Disable the OIC sensor gatt svr' + value: 1 + restrictions: + # Disable central and observer roles. + - BLE_ROLE_BROADCASTER + - '!BLE_ROLE_CENTRAL' + - '!BLE_ROLE_OBSERVER' + - BLE_ROLE_PERIPHERAL + # OC server, with bluetooth transport. + - OC_SERVER + - OC_TRANSPORT_GATT http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/kernel/os/syscfg.yml ---------------------------------------------------------------------- diff --git a/kernel/os/syscfg.yml b/kernel/os/syscfg.yml index 66eae3f..d56c283 100644 --- a/kernel/os/syscfg.yml +++ b/kernel/os/syscfg.yml @@ -80,4 +80,4 @@ syscfg.defs: value: 0 FLOAT_USER: descriptiong: 'Enable float support for users' - value: 0 + value: 1 http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/net/oic/src/api/oc_core_res.c ---------------------------------------------------------------------- diff --git a/net/oic/src/api/oc_core_res.c b/net/oic/src/api/oc_core_res.c index ccb3896..45b9768 100644 --- a/net/oic/src/api/oc_core_res.c +++ b/net/oic/src/api/oc_core_res.c @@ -230,7 +230,11 @@ oc_core_init_platform(const char *mfg_name, oc_core_init_platform_cb_t init_cb, } oc_rep_new(tmp); oc_rep_start_root_object(); +#if 0 oc_rep_set_string_array(root, rt, core_resources[OCF_P].types); +#else + oc_rep_set_text_string(root, rt, "oic.wk.p"); +#endif oc_core_encode_interfaces_mask(oc_rep_object(root), core_resources[OCF_P].interfaces); oc_rep_set_uint(root, p, core_resources[OCF_P].properties & ~OC_PERIODIC); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/net/oic/src/port/mynewt/ble_adaptor.c ---------------------------------------------------------------------- diff --git a/net/oic/src/port/mynewt/ble_adaptor.c b/net/oic/src/port/mynewt/ble_adaptor.c index 056b11c..3ce44a7 100644 --- a/net/oic/src/port/mynewt/ble_adaptor.c +++ b/net/oic/src/port/mynewt/ble_adaptor.c @@ -86,7 +86,6 @@ static int oc_gatt_chr_access(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[] = { { - /* Service: newtmgr */ .type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &oc_gatt_svc_uuid.u, .characteristics = (struct ble_gatt_chr_def[]) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/878cdc4f/net/oic/syscfg.yml ---------------------------------------------------------------------- diff --git a/net/oic/syscfg.yml b/net/oic/syscfg.yml index 51d86e2..08eb9b9 100644 --- a/net/oic/syscfg.yml +++ b/net/oic/syscfg.yml @@ -58,7 +58,7 @@ syscfg.defs: OC_APP_RESOURCES: description: 'Maximum number of server resources' - value: 3 + value: 7 OC_NUM_DEVICES: description: 'Number of devices on the OCF platform'