You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2015/12/15 03:43:05 UTC

[3/3] incubator-mynewt-larva git commit: Notify application of rxed advertisement reports.

Notify application of rxed advertisement reports.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/94311f04
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/94311f04
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/94311f04

Branch: refs/heads/master
Commit: 94311f0442f136e0772d99d2fd0efe524d2e4d72
Parents: 75e3cd0
Author: Christopher Collins <cc...@gmail.com>
Authored: Mon Dec 14 18:07:12 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Mon Dec 14 18:42:33 2015 -0800

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_gap.h  | 26 +++++++-
 net/nimble/host/src/ble_gap_conn.c      | 96 +++++++++++++++++++++-------
 net/nimble/host/src/ble_gap_conn.h      |  4 +-
 net/nimble/host/src/host_hci.c          | 93 +++++++++++++++++++++++++++
 net/nimble/host/src/test/ble_gap_test.c | 15 +++--
 net/nimble/include/nimble/hci_common.h  |  7 ++
 project/hostctlrtest/src/main.c         | 12 ++--
 7 files changed, 213 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/94311f04/net/nimble/host/include/host/ble_gap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gap.h b/net/nimble/host/include/host/ble_gap.h
index c60fc6c..900e659 100644
--- a/net/nimble/host/include/host/ble_gap.h
+++ b/net/nimble/host/include/host/ble_gap.h
@@ -20,13 +20,35 @@
 #include <inttypes.h>
 struct hci_le_conn_complete;
 
-struct ble_gap_connect_desc {
+#define BLE_GAP_CONN_EVENT_TYPE_CONNECT     1
+#define BLE_GAP_CONN_EVENT_TYPE_ADV_RPT     2
+#define BLE_GAP_CONN_EVENT_TYPE_SCAN_DONE   3
+
+struct ble_gap_conn_connect_report {
     uint16_t handle;
     uint8_t status;
     uint8_t peer_addr[6];
 };
 
-typedef void ble_gap_connect_fn(struct ble_gap_connect_desc *desc, void *arg);
+struct ble_gap_conn_adv_rpt {
+    uint8_t event_type;
+    uint8_t addr_type;
+    uint8_t length_data;
+    int8_t rssi;
+    uint8_t addr[6];
+    uint8_t *data;
+};
+
+struct ble_gap_conn_event {
+    uint8_t type;
+
+    union {
+        struct ble_gap_conn_connect_report connect;
+        struct ble_gap_conn_adv_rpt adv_rpt;
+    };
+};
+
+typedef void ble_gap_connect_fn(struct ble_gap_conn_event *event, void *arg);
 
 void ble_gap_conn_set_cb(ble_gap_connect_fn *cb, void *arg);
 int ble_gap_conn_gen_disc(uint32_t duration_ms);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/94311f04/net/nimble/host/src/ble_gap_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap_conn.c b/net/nimble/host/src/ble_gap_conn.c
index fd41737..38a6034 100644
--- a/net/nimble/host/src/ble_gap_conn.c
+++ b/net/nimble/host/src/ble_gap_conn.c
@@ -59,8 +59,8 @@
 /** 10.24 seconds. */
 #define BLE_GAP_GEN_DISC_SCAN_MIN           (10.24 * 1000)
 
-ble_gap_connect_fn *ble_gap_conn_cb;
-void *ble_gap_conn_arg;
+static ble_gap_connect_fn *ble_gap_conn_cb;
+static void *ble_gap_conn_arg;
 
 static int ble_gap_conn_master_state;
 static int ble_gap_conn_slave_state;
@@ -88,30 +88,39 @@ ble_gap_conn_set_cb(ble_gap_connect_fn *cb, void *arg)
     ble_gap_conn_arg = arg;
 }
 
+static void
+ble_gap_conn_call_cb(struct ble_gap_conn_event *event)
+{
+    if (ble_gap_conn_cb != NULL) {
+        ble_gap_conn_cb(event, ble_gap_conn_arg);
+    }
+}
+
 /**
- * Calls the connect callback if one is configured.
+ * Notifies the application of a connection event if a callback is configured.
  *
  * @param status                The HCI status of the connection attempt.
  * @param conn                  The connection this notification concerns;
  *                                  null if a connection was never created.
  */
 static void
-ble_gap_conn_notify_app(uint8_t status, struct ble_hs_conn *conn)
+ble_gap_conn_notify_connect(uint8_t status, struct ble_hs_conn *conn)
 {
-    struct ble_gap_connect_desc desc;
-
-    if (ble_gap_conn_cb != NULL) {
-        desc.status = status;
-        if (conn != NULL) {
-            desc.handle = conn->bhc_handle;
-            memcpy(desc.peer_addr, conn->bhc_addr, sizeof desc.peer_addr);
-        } else {
-            desc.handle = 0;
-            memset(&desc.peer_addr, 0, sizeof desc.peer_addr);
-        }
+    struct ble_gap_conn_event event;
 
-        ble_gap_conn_cb(&desc, ble_gap_conn_arg);
+    event.type = BLE_GAP_CONN_EVENT_TYPE_CONNECT;
+    event.connect.status = status;
+    if (conn != NULL) {
+        event.connect.handle = conn->bhc_handle;
+        memcpy(event.connect.peer_addr, conn->bhc_addr,
+               sizeof event.connect.peer_addr);
+    } else {
+        event.connect.handle = 0;
+        memset(&event.connect.peer_addr, 0,
+               sizeof event.connect.peer_addr);
     }
+
+    ble_gap_conn_call_cb(&event);
 }
 
 /**
@@ -122,11 +131,35 @@ ble_gap_conn_notify_app(uint8_t status, struct ble_hs_conn *conn)
 static void
 ble_gap_conn_master_failed(uint8_t status)
 {
+    struct ble_gap_conn_event event;
+
+    uint8_t old_state;
+
     os_callout_stop(&ble_gap_conn_master_timer.cf_c);
 
+    old_state = ble_gap_conn_master_state;
     ble_gap_conn_master_state = BLE_GAP_CONN_STATE_IDLE;
     ble_hci_ack_set_callback(NULL, NULL);
-    ble_gap_conn_notify_app(status, NULL);
+
+    switch (old_state) {
+    case BLE_GAP_CONN_STATE_M_GEN_DISC_PENDING:
+    case BLE_GAP_CONN_STATE_M_GEN_DISC_PARAMS:
+    case BLE_GAP_CONN_STATE_M_GEN_DISC_PARAMS_ACKED:
+    case BLE_GAP_CONN_STATE_M_GEN_DISC_ENABLE:
+    case BLE_GAP_CONN_STATE_M_GEN_DISC_ENABLE_ACKED:
+        event.type = BLE_GAP_CONN_EVENT_TYPE_SCAN_DONE;
+        ble_gap_conn_call_cb(&event);
+        break;
+
+    case BLE_GAP_CONN_STATE_M_DIRECT_PENDING:
+    case BLE_GAP_CONN_STATE_M_DIRECT_UNACKED:
+    case BLE_GAP_CONN_STATE_M_DIRECT_ACKED:
+        ble_gap_conn_notify_connect(status, NULL);
+        break;
+
+    default:
+        break;
+    }
 }
 
 /**
@@ -141,7 +174,7 @@ ble_gap_conn_slave_failed(uint8_t status)
 
     ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_IDLE;
     ble_hci_ack_set_callback(NULL, NULL);
-    ble_gap_conn_notify_app(status, NULL);
+    ble_gap_conn_notify_connect(status, NULL);
 }
 
 int
@@ -156,11 +189,11 @@ ble_gap_conn_rx_disconn_complete(struct hci_disconn_complete *evt)
 
     if (evt->status == 0) {
         ble_hs_conn_remove(conn);
-        ble_gap_conn_notify_app(evt->reason, conn);
+        ble_gap_conn_notify_connect(evt->reason, conn);
         ble_hs_conn_free(conn);
     } else {
         /* XXX: Ensure we have a disconnect operation in progress. */
-        ble_gap_conn_notify_app(evt->status, conn);
+        ble_gap_conn_notify_connect(evt->status, conn);
     }
 
     return 0;
@@ -209,6 +242,23 @@ ble_gap_conn_accept_new_conn(uint8_t *addr)
     return BLE_HS_ENOENT;
 }
 
+void
+ble_gap_conn_rx_adv_report(struct ble_gap_conn_adv_rpt *rpt)
+{
+    struct ble_gap_conn_event event;
+
+    switch (ble_gap_conn_master_state) {
+    case BLE_GAP_CONN_STATE_M_GEN_DISC_ENABLE_ACKED:
+        event.type = BLE_GAP_CONN_EVENT_TYPE_ADV_RPT;
+        event.adv_rpt = *rpt;
+        ble_gap_conn_call_cb(&event);
+        break;
+
+    default:
+        break;
+    }
+}
+
 /**
  * Processes an incoming connection-complete HCI event.
  */
@@ -227,7 +277,7 @@ ble_gap_conn_rx_conn_complete(struct hci_le_conn_complete *evt)
     if (conn != NULL) {
         if (evt->status != 0) {
             ble_hs_conn_remove(conn);
-            ble_gap_conn_notify_app(evt->status, conn);
+            ble_gap_conn_notify_connect(evt->status, conn);
             ble_hs_conn_free(conn);
         }
 
@@ -250,7 +300,7 @@ ble_gap_conn_rx_conn_complete(struct hci_le_conn_complete *evt)
     conn = ble_hs_conn_alloc();
     if (conn == NULL) {
         /* XXX: Ensure this never happens. */
-        ble_gap_conn_notify_app(BLE_ERR_MEM_CAPACITY, NULL);
+        ble_gap_conn_notify_connect(BLE_ERR_MEM_CAPACITY, NULL);
         return BLE_HS_ENOMEM;
     }
 
@@ -259,7 +309,7 @@ ble_gap_conn_rx_conn_complete(struct hci_le_conn_complete *evt)
 
     ble_hs_conn_insert(conn);
 
-    ble_gap_conn_notify_app(0, conn);
+    ble_gap_conn_notify_connect(0, conn);
 
     return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/94311f04/net/nimble/host/src/ble_gap_conn.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap_conn.h b/net/nimble/host/src/ble_gap_conn.h
index d89519b..b619a05 100644
--- a/net/nimble/host/src/ble_gap_conn.h
+++ b/net/nimble/host/src/ble_gap_conn.h
@@ -26,13 +26,11 @@ struct ble_hci_ack;
 int ble_gap_conn_general_discovery(void);
 int ble_gap_conn_direct_connect(int addr_type, uint8_t *addr);
 int ble_gap_conn_direct_advertise(int addr_type, uint8_t *addr);
+void ble_gap_conn_rx_adv_report(struct ble_gap_conn_adv_rpt *rpt);
 int ble_gap_conn_rx_conn_complete(struct hci_le_conn_complete *evt);
 int ble_gap_conn_rx_disconn_complete(struct hci_disconn_complete *evt);
 int ble_gap_conn_master_in_progress(void);
 int ble_gap_conn_slave_in_progress(void);
 int ble_gap_conn_init(void);
 
-extern ble_gap_connect_fn *ble_gap_conn_cb;
-extern void *ble_gap_conn_arg;
-
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/94311f04/net/nimble/host/src/host_hci.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/host_hci.c b/net/nimble/host/src/host_hci.c
index 521f304..8d29d51 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -41,6 +41,7 @@ static int host_hci_rx_cmd_status(uint8_t event_code, uint8_t *data, int len);
 static int host_hci_rx_le_meta(uint8_t event_code, uint8_t *data, int len);
 static int host_hci_rx_le_conn_complete(uint8_t subevent, uint8_t *data,
                                         int len);
+static int host_hci_rx_le_adv_rpt(uint8_t subevent, uint8_t *data, int len);
 static uint16_t host_hci_buffer_sz;
 static uint8_t host_hci_max_pkts;
 
@@ -85,6 +86,7 @@ struct host_hci_le_event_dispatch_entry {
 static const struct host_hci_le_event_dispatch_entry
         host_hci_le_event_dispatch[] = {
     { BLE_HCI_LE_SUBEV_CONN_COMPLETE, host_hci_rx_le_conn_complete },
+    { BLE_HCI_LE_SUBEV_ADV_RPT, host_hci_rx_le_adv_rpt },
 };
 
 #define HOST_HCI_LE_EVENT_DISPATCH_SZ \
@@ -289,6 +291,97 @@ host_hci_rx_le_conn_complete(uint8_t subevent, uint8_t *data, int len)
     return 0;
 }
 
+static int
+host_hci_le_adv_rpt_first_pass(uint8_t *data, int len,
+                               uint8_t *out_num_reports, int *out_rssi_off)
+{
+    uint8_t num_reports;
+    int data_len;
+    int off;
+    int i;
+
+    if (len < BLE_HCI_LE_ADV_RPT_MIN_LEN) {
+        return BLE_HS_EMSGSIZE;
+    }
+
+    num_reports = data[1];
+    if (num_reports < BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN ||
+        num_reports > BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX) {
+
+        return BLE_HS_EBADDATA;
+    }
+
+    off = 2 +       /* Subevent code and num reports. */
+          (1 +      /* Event type. */
+           1 +      /* Address type. */
+           6        /* Address. */
+          ) * num_reports;
+    if (off + num_reports >= len) {
+        return BLE_HS_EMSGSIZE;
+    }
+
+    data_len = 0;
+    for (i = 0; i < num_reports; i++) {
+        data_len += data[off];
+        off++;
+    }
+
+    off += data_len;
+
+    /* Check if RSSI fields fit in the packet. */
+    if (off + num_reports > len) {
+        return BLE_HS_EMSGSIZE;
+    }
+
+    *out_num_reports = num_reports;
+    *out_rssi_off = off;
+
+    return 0;
+}
+
+static int
+host_hci_rx_le_adv_rpt(uint8_t subevent, uint8_t *data, int len)
+{
+    struct ble_gap_conn_adv_rpt rpt;
+    uint8_t num_reports;
+    int rssi_off;
+    int data_off;
+    int off;
+    int rc;
+    int i;
+
+    rc = host_hci_le_adv_rpt_first_pass(data, len, &num_reports, &rssi_off);
+    if (rc != 0) {
+        return rc;
+    }
+
+    data_off = 0;
+    for (i = 0; i < num_reports; i++) {
+        off = 2 + 0 * num_reports + i;
+        rpt.event_type = data[2 + 0 * num_reports + i];
+
+        off = 2 + 1 * num_reports + i;
+        rpt.addr_type = data[2 + 1 * num_reports + i];
+
+        off = 2 + 2 * num_reports + i * 6;
+        memcpy(rpt.addr, data + off, 6);
+
+        off = 2 + 8 * num_reports + i;
+        rpt.length_data = data[off];
+
+        off = 2 + 9 * num_reports + data_off;
+        rpt.data = data + off;
+        data_off += rpt.length_data;
+
+        off = rssi_off + 1 * i;
+        rpt.rssi = data[off];
+
+        ble_gap_conn_rx_adv_report(&rpt);
+    }
+
+    return 0;
+}
+
 int
 host_hci_set_buf_size(uint16_t pktlen, uint8_t max_pkts)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/94311f04/net/nimble/host/src/test/ble_gap_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_gap_test.c b/net/nimble/host/src/test/ble_gap_test.c
index b7c1c0c..b74ceeb 100644
--- a/net/nimble/host/src/test/ble_gap_test.c
+++ b/net/nimble/host/src/test/ble_gap_test.c
@@ -54,7 +54,7 @@ ble_gap_test_misc_rx_ack(uint16_t ocf, uint8_t status)
 }
 
 static void
-ble_gap_direct_connect_test_connect_cb(struct ble_gap_connect_desc *desc,
+ble_gap_direct_connect_test_connect_cb(struct ble_gap_conn_event *event,
                                        void *arg)
 {
     int *cb_called;
@@ -62,9 +62,11 @@ ble_gap_direct_connect_test_connect_cb(struct ble_gap_connect_desc *desc,
     cb_called = arg;
     *cb_called = 1;
 
-    TEST_ASSERT(desc->status == BLE_ERR_SUCCESS);
-    TEST_ASSERT(desc->handle == 2);
-    TEST_ASSERT(memcmp(desc->peer_addr, ble_gap_test_peer_addr, 6) == 0);
+    TEST_ASSERT(event->type == BLE_GAP_CONN_EVENT_TYPE_CONNECT);
+    TEST_ASSERT(event->connect.status == BLE_ERR_SUCCESS);
+    TEST_ASSERT(event->connect.handle == 2);
+    TEST_ASSERT(memcmp(event->connect.peer_addr, ble_gap_test_peer_addr, 6) ==
+                0);
 }
 
 static void
@@ -133,15 +135,14 @@ TEST_CASE(ble_gap_direct_connect_test_case)
 }
 
 static void
-ble_gap_gen_disc_test_connect_cb(struct ble_gap_connect_desc *desc, void *arg)
+ble_gap_gen_disc_test_connect_cb(struct ble_gap_conn_event *event, void *arg)
 {
     int *cb_called;
 
     cb_called = arg;
     *cb_called = 1;
 
-    TEST_ASSERT(desc->status == 0);
-    TEST_ASSERT(desc->handle == 0);
+    TEST_ASSERT(event->type == BLE_GAP_CONN_EVENT_TYPE_SCAN_DONE);
 }
 
 static void

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/94311f04/net/nimble/include/nimble/hci_common.h
----------------------------------------------------------------------
diff --git a/net/nimble/include/nimble/hci_common.h b/net/nimble/include/nimble/hci_common.h
index f67aa81..545c82f 100644
--- a/net/nimble/include/nimble/hci_common.h
+++ b/net/nimble/include/nimble/hci_common.h
@@ -309,7 +309,14 @@
 /* LE sub-event specific definitions */
 #define BLE_HCI_LE_MIN_LEN                  (1) /* Not including event hdr. */
 
+/* LE connection complete event */
 #define BLE_HCI_LE_CONN_COMPLETE_LEN        (19)
+
+/* LE advertising report event. */
+#define BLE_HCI_LE_ADV_RPT_MIN_LEN          (12)
+#define BLE_HCI_LE_ADV_RPT_NUM_RPTS_MIN     (1)
+#define BLE_HCI_LE_ADV_RPT_NUM_RPTS_MAX     (0x19)
+
 #define BLE_HCI_LE_DATA_LEN_CHG_LEN         (11)
 
 /*--- Shared data structures ---*/

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/94311f04/project/hostctlrtest/src/main.c
----------------------------------------------------------------------
diff --git a/project/hostctlrtest/src/main.c b/project/hostctlrtest/src/main.c
index 17a1008..b47a0fb 100755
--- a/project/hostctlrtest/src/main.c
+++ b/project/hostctlrtest/src/main.c
@@ -307,16 +307,18 @@ hostctlrtest_register_attrs(void)
 #endif
 
 static void
-hostctlrtest_on_connect(struct ble_gap_connect_desc *desc, void *arg)
+hostctlrtest_on_connect(struct ble_gap_conn_event *event, void *arg)
 {
     console_printf("connection complete; handle=%d status=%d "
                    "peer_addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
-                   desc->handle, desc->status, desc->peer_addr[0],
-                   desc->peer_addr[1], desc->peer_addr[2], desc->peer_addr[3],
-                   desc->peer_addr[4], desc->peer_addr[5]);
+                   event->connect.handle, event->connect.status,
+                   event->connect.peer_addr[0], event->connect.peer_addr[1],
+                   event->connect.peer_addr[2], event->connect.peer_addr[3],
+                   event->connect.peer_addr[4], event->connect.peer_addr[5]);
 
 #if HOSTCTLRTEST_CFG_ROLE == HOSTCTLRTEST_ROLE_INITIATOR
-    ble_gatt_disc_all_services(desc->handle, hostctlrtest_on_disc_s, NULL);
+    ble_gatt_disc_all_services(event->connect.handle, hostctlrtest_on_disc_s,
+                               NULL);
 #endif
 }