partially working gatt coap service
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/7c30b040 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/7c30b040 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/7c30b040 Branch: refs/heads/develop Commit: 7c30b040bc6a3de9a7a97ab1557f3e366a69f8b0 Parents: 6aea712 Author: Paul Dietrich <paulfdietr...@yahoo.com> Authored: Fri Sep 23 16:08:44 2016 -0700 Committer: Paul Dietrich <paulfdietr...@yahoo.com> Committed: Mon Sep 26 10:41:37 2016 -0700 ---------------------------------------------------------------------- apps/ocf_sample/pkg.yml | 9 +- apps/ocf_sample/src/main.c | 109 ++++- libs/console/full/src/cons_tty.c | 2 +- libs/iotivity/include/iotivity/oc_gatt.h | 38 ++ libs/iotivity/pkg.yml | 5 +- libs/iotivity/src/port/mynewt/adaptor.c | 15 +- libs/iotivity/src/port/mynewt/adaptor.h | 3 + libs/iotivity/src/port/mynewt/ble_adaptor.c | 468 +++++++++++++++++++ libs/iotivity/src/port/mynewt/serial_adaptor.c | 1 + libs/iotivity/src/port/oc_connectivity.h | 1 + .../transport/ble/include/nmgrble/newtmgr_ble.h | 1 + 11 files changed, 636 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7c30b040/apps/ocf_sample/pkg.yml ---------------------------------------------------------------------- diff --git a/apps/ocf_sample/pkg.yml b/apps/ocf_sample/pkg.yml index 52858b5..bf9b362 100644 --- a/apps/ocf_sample/pkg.yml +++ b/apps/ocf_sample/pkg.yml @@ -31,11 +31,16 @@ pkg.deps: - libs/util - sys/log - libs/iotivity - + - "@apache-mynewt-core/net/nimble/host" + - "@apache-mynewt-core/net/nimble/controller" + - "@apache-mynewt-core/net/nimble/transport/ram" + - "@apache-mynewt-core/net/nimble/host/store/ram" + - "@apache-mynewt-core/net/nimble/host/services/gap" + - "@apache-mynewt-core/net/nimble/host/services/gatt" # this tells the library that you intend to suppor the server functionality pkg.cflags: -#-DOC_SERVER -- build the server examples +#-DOC_SERVER -- build the server examples #-DOC_CLIENT -- build the client examples #-DOC_TRANSPORT_GATT -- to send COAP over GATT #-DOC_TRANSPORT_SERIAL -- to send COAP over serial http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7c30b040/apps/ocf_sample/src/main.c ---------------------------------------------------------------------- diff --git a/apps/ocf_sample/src/main.c b/apps/ocf_sample/src/main.c index ebe9988..17d0f6a 100644 --- a/apps/ocf_sample/src/main.c +++ b/apps/ocf_sample/src/main.c @@ -23,24 +23,59 @@ #include <console/prompt.h> #include <shell/shell.h> #include <log/log.h> - #include <iotivity/oc_api.h> #include "mn_socket/mn_socket.h" #include "mn_socket/arch/sim/native_sock.h" +#ifdef OC_TRANSPORT_GATT + +#include <iotivity/oc_gatt.h> + +/* BLE */ +#include "nimble/ble.h" +#include "host/ble_hs.h" +#include "host/ble_hs_adv.h" +#include "host/ble_uuid.h" +#include "host/ble_att.h" +#include "host/ble_gap.h" +#include "host/ble_gatt.h" +#include "host/ble_l2cap.h" +#include "host/ble_sm.h" +#include "controller/ble_ll.h" + +/* RAM HCI transport. */ +#include "transport/ram/ble_hci_ram.h" + +/* RAM persistence layer. */ +#include "store/ram/ble_store_ram.h" + +/* Mandatory services. */ +#include "services/gap/ble_svc_gap.h" +#include "services/gatt/ble_svc_gatt.h" + +uint8_t g_random_addr[6] = {6,5,4,3,2,1}; +uint8_t g_dev_addr[6] = {1,2,3,4,5,6}; + +/** Priority of the nimble host and controller tasks. */ +#define BLE_LL_TASK_PRI (OS_TASK_PRI_HIGHEST) + +#endif + /* Shell */ +#ifdef OC_TRANSPORT_SERIAL #define SHELL_TASK_PRIO (8) #define SHELL_MAX_INPUT_LEN (512) #define SHELL_TASK_STACK_SIZE (OS_STACK_ALIGN(2048)) static os_stack_t shell_stack[SHELL_TASK_STACK_SIZE]; +#endif #define OCF_TASK_PRIO (8) #define OCF_TASK_STACK_SIZE (OS_STACK_ALIGN(2048)) static os_stack_t ocf_stack[OCF_TASK_STACK_SIZE]; struct os_task ocf_task; -#define DEFAULT_MBUF_MPOOL_BUF_LEN (256) -#define DEFAULT_MBUF_MPOOL_NBUFS (10) +#define DEFAULT_MBUF_MPOOL_BUF_LEN OS_ALIGN(BLE_MBUF_PAYLOAD_SIZE, 4) +#define DEFAULT_MBUF_MPOOL_NBUFS (12) static uint8_t default_mbuf_mpool_data[DEFAULT_MBUF_MPOOL_BUF_LEN * DEFAULT_MBUF_MPOOL_NBUFS]; @@ -238,8 +273,6 @@ oc_signal_main_loop(void) { } void ocf_task_handler(void *arg) { - /* TODO */ - oc_main_init(&ocf_handler); os_sem_init(&ocf_main_loop_sem, 1); @@ -265,16 +298,27 @@ ocf_task_init(void) { rc = os_task_init(&ocf_task, "ocf", ocf_task_handler, NULL, OCF_TASK_PRIO, OS_WAIT_FOREVER, ocf_stack, OCF_TASK_STACK_SIZE); assert(rc == 0); + + oc_main_init(&ocf_handler); } int main(int argc, char **argv) { int rc; - + struct os_eventq *ev; +#ifdef OC_TRANSPORT_GATT + struct ble_hci_ram_cfg hci_cfg; + struct ble_hs_cfg cfg; +#endif /* Initialize OS */ os_init(); + /* Set cputime to count at 1 usec increments */ + rc = cputime_init(1000000); + assert(rc == 0); + + rc = os_mempool_init(&default_mbuf_mpool, DEFAULT_MBUF_MPOOL_NBUFS, DEFAULT_MBUF_MPOOL_BUF_LEN, default_mbuf_mpool_data, "default_mbuf_data"); @@ -290,18 +334,68 @@ main(int argc, char **argv) #ifdef OC_TRANSPORT_SERIAL console_echo(0); console_no_prompt(); -#endif /* Init tasks */ rc = shell_task_init(SHELL_TASK_PRIO, shell_stack, SHELL_TASK_STACK_SIZE, SHELL_MAX_INPUT_LEN); assert(rc == 0); +#else + console_init(NULL); +#endif #ifdef OC_TRANSPORT_IP rc = native_sock_init(); assert(rc == 0); #endif +#ifdef OC_TRANSPORT_GATT + /* Initialize the BLE LL */ + rc = ble_ll_init(BLE_LL_TASK_PRI, DEFAULT_MBUF_MPOOL_NBUFS, + DEFAULT_MBUF_MPOOL_BUF_LEN - BLE_HCI_DATA_HDR_SZ); + assert(rc == 0); + + /* Initialize the RAM HCI transport. */ + hci_cfg = ble_hci_ram_cfg_dflt; + rc = ble_hci_ram_init(&hci_cfg); + assert(rc == 0); + + /* Initialize the BLE host. */ + cfg = ble_hs_cfg_dflt; + cfg.max_hci_bufs = hci_cfg.num_evt_hi_bufs + hci_cfg.num_evt_lo_bufs; + cfg.max_connections = 1; + cfg.max_gattc_procs = 2; + cfg.max_l2cap_chans = 3; + cfg.max_l2cap_sig_procs = 1; + cfg.sm_bonding = 1; + cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC; + cfg.sm_their_key_dist = BLE_SM_PAIR_KEY_DIST_ENC; + cfg.sync_cb = NULL; /* TODO */ + cfg.store_read_cb = ble_store_ram_read; + cfg.store_write_cb = ble_store_ram_write; + + /* Populate config with the required GATT server settings. */ + cfg.max_attrs = 0; + cfg.max_services = 0; + cfg.max_client_configs = 0; + + rc = ble_svc_gap_init(&cfg); + assert(rc == 0); + + rc = ble_svc_gatt_init(&cfg); + assert(rc == 0); + + /* COAP Gatt server initialization */ + rc = ble_coap_gatt_srv_init(&cfg, &ev); + assert(rc == 0); + + rc = ble_hs_init(ev, &cfg); + assert(rc == 0); + + /* Set the default device name. */ + rc = ble_svc_gap_device_name_set("Mynewt_OCF"); + assert(rc == 0); +#endif + ocf_task_init(); /* Start the OS */ @@ -309,5 +403,4 @@ main(int argc, char **argv) /* os start should never return. If it does, this should be an error */ assert(0); - } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7c30b040/libs/console/full/src/cons_tty.c ---------------------------------------------------------------------- diff --git a/libs/console/full/src/cons_tty.c b/libs/console/full/src/cons_tty.c index 412f93c..f420c2a 100644 --- a/libs/console/full/src/cons_tty.c +++ b/libs/console/full/src/cons_tty.c @@ -265,7 +265,7 @@ console_rx_char(void *arg, uint8_t data) struct console_tty *ct = (struct console_tty *)arg; struct console_ring *tx = &ct->ct_tx; struct console_ring *rx = &ct->ct_rx; - int tx_space; + int tx_space = 0; int i; int tx_buf[3]; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7c30b040/libs/iotivity/include/iotivity/oc_gatt.h ---------------------------------------------------------------------- diff --git a/libs/iotivity/include/iotivity/oc_gatt.h b/libs/iotivity/include/iotivity/oc_gatt.h new file mode 100644 index 0000000..0cb48a8 --- /dev/null +++ b/libs/iotivity/include/iotivity/oc_gatt.h @@ -0,0 +1,38 @@ +/** + * 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 OC_GATT_H +#define OC_GATT_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct ble_hs_cfg; + +/* returns the event q for bluetooth to use */ +int +ble_coap_gatt_srv_init(struct ble_hs_cfg *cfg, struct os_eventq **out); + +#ifdef __cplusplus +} +#endif + +#endif /* OC_GATT_H */ + http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7c30b040/libs/iotivity/pkg.yml ---------------------------------------------------------------------- diff --git a/libs/iotivity/pkg.yml b/libs/iotivity/pkg.yml index f837bf4..abecc02 100644 --- a/libs/iotivity/pkg.yml +++ b/libs/iotivity/pkg.yml @@ -28,7 +28,10 @@ pkg.deps: - "@apache-mynewt-core/libs/os" - "@apache-mynewt-core/sys/mn_socket" - "@apache-mynewt-core/sys/log" - + - "@apache-mynewt-core/net/nimble/host" + - "@apache-mynewt-core/net/nimble/transport/ram" + - "@apache-mynewt-core/net/nimble/host/services/gap" + - "@apache-mynewt-core/net/nimble/host/services/gatt" # remove debug option to save logging pkg.cflags: -std=c99 -DDEBUG=1 http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7c30b040/libs/iotivity/src/port/mynewt/adaptor.c ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/port/mynewt/adaptor.c b/libs/iotivity/src/port/mynewt/adaptor.c index 2a80f4c..7c2925b 100644 --- a/libs/iotivity/src/port/mynewt/adaptor.c +++ b/libs/iotivity/src/port/mynewt/adaptor.c @@ -111,13 +111,18 @@ void oc_send_multicast_message(oc_message_t *message) /* send all the entries to the OCF stack through the same task */ void oc_task_handler(void *arg) { + +#ifdef OC_TRANSPORT_GATT + oc_connectivity_start_gatt(); +#endif + while (1) { + struct os_callout_func *cf; oc_message_t *pmsg; (void) pmsg; /* to avoid unused */ struct os_event *evt = os_eventq_get(&oc_event_q); switch(evt->ev_type) { - #ifdef OC_TRANSPORT_IP case OC_ADATOR_EVENT_IP: while ((pmsg = oc_attempt_rx_ip()) != NULL) { @@ -125,7 +130,6 @@ oc_task_handler(void *arg) { } break; #endif - #ifdef OC_TRANSPORT_SERIAL case OC_ADATOR_EVENT_SERIAL: while ((pmsg = oc_attempt_rx_serial()) != NULL) { @@ -133,17 +137,20 @@ oc_task_handler(void *arg) { } break; #endif - #ifdef OC_TRANSPORT_GATT case OC_ADATOR_EVENT_GATT: while ((pmsg = oc_attempt_rx_gatt()) != NULL) { oc_network_event(pmsg); } break; + case OS_EVENT_T_TIMER: + cf = (struct os_callout_func *)evt; + assert(cf->cf_func); + cf->cf_func(CF_ARG(cf)); + break; #endif default: ERROR("oc_task_handler: Unidentified event %d\n", evt->ev_type); - } } } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7c30b040/libs/iotivity/src/port/mynewt/adaptor.h ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/port/mynewt/adaptor.h b/libs/iotivity/src/port/mynewt/adaptor.h index 431c7e9..ea9034e 100644 --- a/libs/iotivity/src/port/mynewt/adaptor.h +++ b/libs/iotivity/src/port/mynewt/adaptor.h @@ -41,9 +41,12 @@ oc_message_t *oc_attempt_rx_ip(void); #ifdef OC_TRANSPORT_GATT int oc_connectivity_init_gatt(void); +void oc_connectivity_start_gatt(void); void oc_connectivity_shutdown_gatt(void); void oc_send_buffer_gatt(oc_message_t *message); +void oc_send_buffer_gatt_mcast(oc_message_t *message); oc_message_t *oc_attempt_rx_gatt(void); + #endif #ifdef OC_TRANSPORT_SERIAL http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7c30b040/libs/iotivity/src/port/mynewt/ble_adaptor.c ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/port/mynewt/ble_adaptor.c b/libs/iotivity/src/port/mynewt/ble_adaptor.c index f736fe1..edca8a0 100644 --- a/libs/iotivity/src/port/mynewt/ble_adaptor.c +++ b/libs/iotivity/src/port/mynewt/ble_adaptor.c @@ -16,3 +16,471 @@ * specific language governing permissions and limitations * under the License. */ +#include <assert.h> +#include <os/os.h> +#include <string.h> +#include "oc_buffer.h" +#include "../oc_log.h" +#include "adaptor.h" +#include "host/ble_hs.h" +#include "services/gap/ble_svc_gap.h" +#include "services/gatt/ble_svc_gatt.h" + +/* a custom service for COAP over GATT */ +/* {e3f9f9c4-8a83-4055-b647-728b769745d6} */ +const uint8_t gatt_svr_svc_coap[16] = { + 0xd6, 0x45, 0x97, 0x76, 0x8b, 0x72, 0x47, 0xb6, + 0x55, 0x40, 0x83, 0x8a, 0xc4, 0xf9, 0xf9, 0xe3, +}; + +/* {e467fee6-d6bb-4956-94df-0090350631f5} */ +const uint8_t gatt_svr_chr_coap[16] = { + 0xf5, 0x31, 0x06, 0x35, 0x90, 0x00, 0xdf, 0x94, + 0x56, 0x49, 0xbb, 0xd6, 0xe6, 0xfe, 0x67, 0xe4, +}; + +/* queue to hold mbufs until we get called from oic */ +struct os_mqueue ble_coap_mq; + +static int +blecoap_gap_event(struct ble_gap_event *event, void *arg); + +#ifdef OC_SERVER +/* ble nmgr attr handle */ +uint16_t g_ble_coap_attr_handle; + +static int +gatt_svr_chr_access_coap(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, + .uuid128 = (void *)gatt_svr_svc_coap, + .characteristics = (struct ble_gatt_chr_def[]) { { + /* Characteristic: Write No Rsp */ + .uuid128 = (void *)gatt_svr_chr_coap, + .access_cb = gatt_svr_chr_access_coap, + .flags = BLE_GATT_CHR_F_WRITE_NO_RSP, + .val_handle = &g_ble_coap_attr_handle, + }, { + 0, /* No more characteristics in this service */ + } }, + }, + { + 0, /* No more services */ + }, +}; + +static int +gatt_svr_chr_access_coap(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + struct os_mbuf *m; + int rc; + (void) attr_handle; /* no need to use this since we have onyl one attr + * tied to this callback */ + + switch (ctxt->op) { + case BLE_GATT_ACCESS_OP_WRITE_CHR: + m = ctxt->om; + /* stick the conn handle at the end of the frame -- we will + * pull it out later */ + rc = os_mbuf_append(m, &conn_handle, sizeof(conn_handle)); + if (rc) { + return BLE_ATT_ERR_INSUFFICIENT_RES; + } + rc = os_mqueue_put(&ble_coap_mq, &oc_event_q, m); + if (rc) { + return BLE_ATT_ERR_PREPARE_QUEUE_FULL; + } + + /* tell nimble we are keeping the mbuf */ + ctxt->om = NULL; + + break; + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } + return 0; +} + +static int +oc_gatt_advertise(void) +{ + struct ble_gap_adv_params adv_params; + struct ble_hs_adv_fields fields; + int rc; + + /* + * Set the advertisement data included in our advertisements: + * o Flags (indicates advertisement type and other general info). + * o Advertising tx power. + * o 128 bit UUID + */ + + memset(&fields, 0, sizeof fields); + + /* Indicate that the flags field should be included; specify a value of 0 + * to instruct the stack to fill the value in for us. + */ + fields.flags_is_present = 1; + fields.flags = 0; + + /* Indicate that the TX power level field should be included; have the + * stack fill this one automatically as well. This is done by assigning + * 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; + + fields.uuids128 = (void *)gatt_svr_svc_coap; + fields.num_uuids128 = 1; + fields.uuids128_is_complete = 1; + + rc = ble_gap_adv_set_fields(&fields); + if (rc != 0) { + return rc; + } + + memset(&fields, 0, sizeof fields); + fields.name = (uint8_t *)ble_svc_gap_device_name(); + fields.name_len = strlen((char *)fields.name); + fields.name_is_complete = 1; + + rc = ble_gap_adv_rsp_set_fields(&fields); + if (rc != 0) { + return rc; + } + + /* 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_ADDR_TYPE_PUBLIC, 0, NULL, BLE_HS_FOREVER, + &adv_params, blecoap_gap_event, NULL); + return rc; +} +#endif + +#ifdef OC_CLIENT +/** + * Indicates whether we should tre to connect to the sender of the specified + * advertisement. The function returns a positive result if the device + * advertises connectability and support for the Alert Notification service. + */ +static int +oc_gatt_should_connect(const struct ble_gap_disc_desc *disc) +{ + int i; + + /* The device has to be advertising connectability. */ + if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND && + disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) { + + return 0; + } + + /* The device has to advertise support for the COAP service + */ + for + for (i = 0; i < disc->fields->num_uuids128; i++) { + if (disc->fields->uuids128[i] == gatt_svr_svc_coap) { + return 1; + } + } + + return 0; +} + +/** + * Connects to the sender of the specified advertisement of it looks + * interesting. A device is "interesting" if it advertises connectability and + * support for the Alert Notification service. + */ +static void +oc_gatt_connect_if_interesting(const struct ble_gap_disc_desc *disc) +{ + int rc; + + /* Don't do anything if we don't care about this advertiser. */ + if (!oc_gatt_should_connect(disc)) { + return; + } + + /* Scanning must be stopped before a connection can be initiated. */ + rc = ble_gap_disc_cancel(); + if (rc != 0) { + ERROR("Failed to cancel scan; rc=%d\n", rc); + return; + } + + /* Try to connect the the advertiser. Allow 30 seconds (30000 ms) for + * timeout. + */ + rc = ble_gap_connect(BLE_ADDR_TYPE_PUBLIC, disc->addr_type, disc->addr, + 30000, NULL, blecoap_gap_event, NULL); + if (rc != 0) { + ERROR("Error: Failed to connect to device; addr_type=%d " + "addr=%s\n", disc->addr_type, addr_str(disc->addr)); + return; + } +} + + +/** + * Initiates the GAP general discovery procedure. + */ +static int +oc_gatt_scan(void) +{ + struct ble_gap_disc_params disc_params; + int rc; + + /* Tell the controller to filter duplicates; we don't want to process + * repeated advertisements from the same device. + */ + disc_params.filter_duplicates = 1; + + /** + * Perform a passive scan. I.e., don't send follow-up scan requests to + * each advertiser. + */ + disc_params.passive = 1; + + /* Use defaults for the rest of the parameters. */ + disc_params.itvl = 0; + disc_params.window = 0; + disc_params.filter_policy = 0; + disc_params.limited = 0; + + rc = ble_gap_disc(BLE_ADDR_TYPE_PUBLIC, BLE_HS_FOREVER, &disc_params, + blecent_gap_event, NULL); + if (rc != 0) { + ERROR("Error initiating GAP discovery procedure; rc=%d\n", + rc); + } + return rc; +} + +#endif + +oc_message_t * +oc_attempt_rx_gatt(void) { + int rc; + struct os_mbuf *m = NULL; + struct os_mbuf_pkthdr *pkt; + uint16_t conn_handle; + oc_message_t *message = NULL; + + LOG("oc_transport_gatt attempt rx\n"); + + /* get an mbuf from the queue */ + m = os_mqueue_get(&ble_coap_mq); + if (NULL == m) { + ERROR("oc_transport_gatt: Woke for for receive but found no mbufs\n"); + goto rx_attempt_err; + } + + if (!OS_MBUF_IS_PKTHDR(m)) { + ERROR("oc_transport_gatt: received mbuf that wasn't a packet header\n"); + goto rx_attempt_err; + } + + pkt = OS_MBUF_PKTHDR(m); + + LOG("oc_transport_gatt rx %p-%u\n", pkt, pkt->omp_len); + /* get the conn handle from the end of the message */ + rc = os_mbuf_copydata(m, pkt->omp_len - sizeof(conn_handle), + sizeof(conn_handle), &conn_handle); + if (rc != 0) { + ERROR("Failed to retrieve conn_handle from mbuf \n"); + goto rx_attempt_err; + } + + /* trim conn_handle from the end */ + os_mbuf_adj(m, - sizeof(conn_handle)); + + message = oc_allocate_message(); + if (NULL == message) { + ERROR("Could not allocate OC message buffer\n"); + goto rx_attempt_err; + } + + if (pkt->omp_len > MAX_PAYLOAD_SIZE) { + ERROR("Message to large for OC message buffer\n"); + goto rx_attempt_err; + } + /* copy to message from mbuf chain */ + rc = os_mbuf_copydata(m, 0, pkt->omp_len, message->data); + if (rc != 0) { + ERROR("Failed to copy message from mbuf to OC message buffer \n"); + goto rx_attempt_err; + } + + os_mbuf_free_chain(m); + message->endpoint.flags = GATT; + message->endpoint.bt_addr.conn_handle = conn_handle; + message->length = pkt->omp_len; + LOG("Successfully rx length %lu\n", message->length); + return message; + + /* add the addr info to the message */ +rx_attempt_err: + if (m) { + os_mbuf_free_chain(m); + } + if (message) { + oc_message_unref(message); + } + return NULL; +} + +static int +blecoap_gap_event(struct ble_gap_event *event, void *arg) +{ + switch (event->type) { +#ifdef OC_CLIENT + case BLE_GAP_EVENT_DISC: + /* Try to connect to the advertiser if it looks interesting. */ + blecent_connect_if_interesting(&event->disc); + return 0; +#endif + case BLE_GAP_EVENT_CONNECT: + /* A new connection was established or a connection attempt failed. */ + if (event->connect.status == 0) { + /* nothing to do here on the server */ + } + if (event->connect.status != 0) { + /* nothing to do here on the client */ + } + +#ifdef OC_SERVER + /* keep advertising for multiple connections */ + oc_gatt_advertise(); +#endif +#ifdef OC_CLIENT + /* keep scanning for new connections */ + oc_gatt_scan(); +#endif + return 0; + + case BLE_GAP_EVENT_DISCONNECT: + /* Connection terminated; resume advertising. */ +#ifdef OC_CLIENT + /* keep scanning for new connections */ + oc_gatt_scan(); +#endif +#ifdef OC_SERVER + /* resume advertising */ + oc_gatt_advertise(); +#endif + return 0; +#ifdef OC_CLIENT + case BLE_GAP_EVENT_NOTIFY_RX: + /* TODO queue the packet */ + return 0; +#endif + } + return 0; +} + +#ifdef OC_SERVER +int +ble_coap_gatt_srv_init(struct ble_hs_cfg *cfg, struct os_eventq **out) +{ + int rc; + + *out = &oc_event_q; + + rc = ble_gatts_count_cfg(gatt_svr_svcs, cfg); + if (rc != 0) { + return rc; + } + + rc = ble_gatts_add_svcs(gatt_svr_svcs); + if (rc != 0) { + return rc; + } + return 0; +} +#endif + +int oc_connectivity_init_gatt(void) { + os_mqueue_init(&ble_coap_mq, NULL); + ble_coap_mq.mq_ev.ev_type = OC_ADATOR_EVENT_GATT; + return 0; +} + +void oc_connectivity_start_gatt(void) { + int rc; + rc = ble_hs_start(); + if (rc != 0) { + goto err; + } +#ifdef OC_SERVER + rc = oc_gatt_advertise(); + if (rc != 0) { + goto err; + } +#endif +#ifdef OC_CLIENT + rc = oc_gatt_scan(); + if (rc != 0) { + goto err; + } +#endif +err: + ERROR("error enabling advertisement; rc=%d\n", rc); +} + +void oc_connectivity_shutdown_gatt(void) +{ + /* there is not unregister for BLE */ +} + +void oc_send_buffer_gatt(oc_message_t *message) +{ + struct os_mbuf *m = NULL; + int rc; + + /* get a packet header */ + m = os_msys_get_pkthdr(0, 0); + if (m == NULL) { + ERROR("oc_transport_gatt: No mbuf available\n"); + goto err; + } + + /* add this data to the mbuf */ + rc = os_mbuf_append(m, message->data, message->length); + if (rc != 0) { + ERROR("oc_transport_gatt: could not append data \n"); + goto err; + } +#ifdef OC_CLIENT + /* TODO */ +#endif +#ifdef OC_SERVER + ble_gattc_notify_custom(message->endpoint.bt_addr.conn_handle, + g_ble_coap_attr_handle, m); +#endif +err: + if (m) { + os_mbuf_free_chain(m); + } + oc_message_unref(message); + return; +} + +void +oc_send_buffer_gatt_mcast(oc_message_t *message) +{ +#ifdef OC_CLIENT + /* TODO */ +#elif defined(OC_SERVER) + oc_message_unref(message); + ERROR("oc_transport_gatt: no multicast support for server only system \n"); +#endif +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7c30b040/libs/iotivity/src/port/mynewt/serial_adaptor.c ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/port/mynewt/serial_adaptor.c b/libs/iotivity/src/port/mynewt/serial_adaptor.c index 7fa94b3..0c27b92 100644 --- a/libs/iotivity/src/port/mynewt/serial_adaptor.c +++ b/libs/iotivity/src/port/mynewt/serial_adaptor.c @@ -76,6 +76,7 @@ void oc_send_buffer_serial(oc_message_t *message) { /* add this data to the mbuf */ rc = os_mbuf_append(m, message->data, message->length); if (rc != 0) { + ERROR("oc_transport_serial: could not append data \n"); goto err; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7c30b040/libs/iotivity/src/port/oc_connectivity.h ---------------------------------------------------------------------- diff --git a/libs/iotivity/src/port/oc_connectivity.h b/libs/iotivity/src/port/oc_connectivity.h index 4e4cdec..9b3b185 100644 --- a/libs/iotivity/src/port/oc_connectivity.h +++ b/libs/iotivity/src/port/oc_connectivity.h @@ -34,6 +34,7 @@ typedef struct { uint8_t type; uint8_t address[6]; + uint16_t conn_handle; } oc_le_addr_t; typedef struct http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/7c30b040/libs/newtmgr/transport/ble/include/nmgrble/newtmgr_ble.h ---------------------------------------------------------------------- diff --git a/libs/newtmgr/transport/ble/include/nmgrble/newtmgr_ble.h b/libs/newtmgr/transport/ble/include/nmgrble/newtmgr_ble.h index 315a6e8..b0d2e51 100644 --- a/libs/newtmgr/transport/ble/include/nmgrble/newtmgr_ble.h +++ b/libs/newtmgr/transport/ble/include/nmgrble/newtmgr_ble.h @@ -22,6 +22,7 @@ int nmgr_ble_proc_mq_evt(struct os_event *ev); + int nmgr_ble_gatt_svr_init(void);