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/11/13 21:05:13 UTC

[2/2] incubator-mynewt-larva git commit: BLE host: add connection event callback.

BLE host: add connection event callback.


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/c4ff5a8a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/c4ff5a8a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/c4ff5a8a

Branch: refs/heads/master
Commit: c4ff5a8aca0d736cc3f166baa6aa851ae10b8382
Parents: f4299eb
Author: Christopher Collins <cc...@gmail.com>
Authored: Fri Nov 13 11:52:06 2015 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Fri Nov 13 12:05:01 2015 -0800

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_gap.h  | 35 ++++++++++++
 net/nimble/host/src/ble_gap.c           | 18 ++++++-
 net/nimble/host/src/ble_gap.h           | 25 ---------
 net/nimble/host/src/ble_gap_conn.c      | 79 +++++++++++++++++++++++-----
 net/nimble/host/src/ble_gap_conn.h      |  4 ++
 net/nimble/host/src/test/ble_gap_test.c | 35 +++++++++++-
 6 files changed, 155 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c4ff5a8a/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
new file mode 100644
index 0000000..cb02924
--- /dev/null
+++ b/net/nimble/host/include/host/ble_gap.h
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2015 Runtime Inc.
+ *
+ * Licensed 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_BLE_GAP_
+#define H_BLE_GAP_
+
+#include <inttypes.h>
+struct hci_le_conn_complete;
+
+struct ble_gap_connect_desc {
+    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);
+
+void ble_gap_set_connect_cb(ble_gap_connect_fn *cb, void *arg);
+int ble_gap_direct_connection_establishment(uint8_t addr_type, uint8_t *addr);
+int ble_gap_directed_connectable(uint8_t addr_type, uint8_t *addr);
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c4ff5a8a/net/nimble/host/src/ble_gap.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap.c b/net/nimble/host/src/ble_gap.c
index 8da5ead..bac76e8 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -17,8 +17,24 @@
 #include <stddef.h>
 #include <errno.h>
 #include <string.h>
+#include "host/ble_gap.h"
 #include "ble_hs_work.h"
-#include "ble_gap.h"
+#include "ble_gap_conn.h"
+
+/**
+ * Configures the connection event callback.  The callback is executed whenever
+ * any of the following events occurs:
+ *     o Connection creation succeeds.
+ *     o Connection creation fails.
+ *     o Connection establishment fails.
+ *     o Established connection broken.
+ */
+void
+ble_gap_set_connect_cb(ble_gap_connect_fn *cb, void *arg)
+{
+    ble_gap_conn_cb = cb;
+    ble_gap_conn_arg = arg;
+}
 
 /**
  * Performs the Direct Connection Establishment Procedure, as described in

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c4ff5a8a/net/nimble/host/src/ble_gap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gap.h b/net/nimble/host/src/ble_gap.h
deleted file mode 100644
index 78b0e30..0000000
--- a/net/nimble/host/src/ble_gap.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Copyright (c) 2015 Runtime Inc.
- *
- * Licensed 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_BLE_GAP_
-#define H_BLE_GAP_
-
-#include <inttypes.h>
-
-int ble_gap_direct_connection_establishment(uint8_t addr_type, uint8_t *addr);
-int ble_gap_directed_connectable(uint8_t addr_type, uint8_t *addr);
-
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c4ff5a8a/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 ff22b01..a00c603 100644
--- a/net/nimble/host/src/ble_gap_conn.c
+++ b/net/nimble/host/src/ble_gap_conn.c
@@ -34,27 +34,66 @@
 #define BLE_GAP_CONN_STATE_SLAVE_PARAMS_ACKED       2
 #define BLE_GAP_CONN_STATE_SLAVE_ENABLE_ACKED       3
 
+ble_gap_connect_fn *ble_gap_conn_cb;
+void *ble_gap_conn_arg;
+
 static int ble_gap_conn_master_state;
 static int ble_gap_conn_slave_state;
 static uint8_t ble_gap_conn_addr_master[BLE_DEV_ADDR_LEN];
 static uint8_t ble_gap_conn_addr_slave[BLE_DEV_ADDR_LEN];
 
+/**
+ * Calls the connect callback if one 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)
+{
+    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);
+        }
+
+        ble_gap_conn_cb(&desc, ble_gap_conn_arg);
+    }
+}
+
+/**
+ * Called when an error is encountered while the master-connection-fsm is
+ * active.  Resets the state machine, clears the HCI ack callback, and notifies
+ * the host task that the next work item can be processed.
+ */
 static void
-ble_gap_conn_master_failed(void)
+ble_gap_conn_master_failed(uint8_t status)
 {
     ble_gap_conn_master_state = BLE_GAP_CONN_STATE_IDLE;
     ble_hs_ack_set_callback(NULL, NULL);
     ble_hs_work_done();
-    /* XXX: Notify someone. */
+    ble_gap_conn_notify_app(status, NULL);
 }
 
+/**
+ * Called when an error is encountered while the slave-connection-fsm is
+ * active.  Resets the state machine, clears the HCI ack callback, and notifies
+ * the host task that the next work item can be processed.
+ */
 static void
-ble_gap_conn_slave_failed(void)
+ble_gap_conn_slave_failed(uint8_t status)
 {
     ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_IDLE;
     ble_hs_ack_set_callback(NULL, NULL);
     ble_hs_work_done();
-    /* XXX: Notify someone. */
+    ble_gap_conn_notify_app(status, NULL);
 }
 
 /**
@@ -68,7 +107,7 @@ ble_gap_conn_master_ack(struct ble_hs_ack *ack, void *arg)
            BLE_GAP_CONN_STATE_MASTER_DIRECT_UNACKED);
 
     if (ack->bha_status != 0) {
-        ble_gap_conn_master_failed();
+        ble_gap_conn_master_failed(ack->bha_status);
     } else {
         ble_gap_conn_master_state = BLE_GAP_CONN_STATE_MASTER_DIRECT_ACKED;
     }
@@ -88,21 +127,21 @@ ble_gap_conn_slave_ack(struct ble_hs_ack *ack, void *arg)
 
     switch (ble_gap_conn_slave_state) {
     case BLE_GAP_CONN_STATE_SLAVE_UNACKED:
-        if (ack->bha_status != 0) {
-            ble_gap_conn_slave_failed();
+        if (ack->bha_status != BLE_ERR_SUCCESS) {
+            ble_gap_conn_slave_failed(ack->bha_status);
         } else {
             ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_SLAVE_PARAMS_ACKED;
             ble_hs_ack_set_callback(ble_gap_conn_slave_ack, NULL);
             rc = host_hci_cmd_le_set_adv_enable(1);
-            if (rc != 0) {
-                ble_gap_conn_slave_failed();
+            if (rc != BLE_ERR_SUCCESS) {
+                ble_gap_conn_slave_failed(rc);
             }
         }
         break;
 
     case BLE_GAP_CONN_STATE_SLAVE_PARAMS_ACKED:
         if (ack->bha_status != 0) {
-            ble_gap_conn_slave_failed();
+            ble_gap_conn_slave_failed(ack->bha_status);
         } else {
             ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_SLAVE_ENABLE_ACKED;
 
@@ -161,10 +200,15 @@ ble_gap_conn_direct_connect(int addr_type, uint8_t *addr)
     return 0;
 
 err:
-    /* XXX: Notify someone. */
+    ble_gap_conn_notify_app(rc, NULL);
     return rc;
 }
 
+/**
+ * Enables the GAP Directed Connectable Mode.
+ *
+ * @return 0 on success; nonzero on failure.
+ */
 int
 ble_gap_conn_direct_advertise(int addr_type, uint8_t *addr)
 {
@@ -199,7 +243,7 @@ ble_gap_conn_direct_advertise(int addr_type, uint8_t *addr)
     return 0;
 
 err:
-    /* XXX: Notify someone. */
+    ble_gap_conn_notify_app(rc, NULL);
     return rc;
 }
 
@@ -244,6 +288,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_hs_conn_free(conn);
         }
 
@@ -265,6 +310,8 @@ 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);
         return ENOMEM;
     }
 
@@ -273,17 +320,23 @@ ble_gap_conn_rx_conn_complete(struct hci_le_conn_complete *evt)
 
     ble_hs_conn_insert(conn);
 
-    /* XXX: Notify someone. */
+    ble_gap_conn_notify_app(0, conn);
 
     return 0;
 }
 
+/**
+ * Tells you if the BLE host is in the process of creating a master connection.
+ */
 int
 ble_gap_conn_master_in_progress(void)
 {
     return ble_gap_conn_master_state != BLE_GAP_CONN_STATE_IDLE;
 }
 
+/**
+ * Tells you if the BLE host is in the process of creating a slave connection.
+ */
 int
 ble_gap_conn_slave_in_progress(void)
 {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c4ff5a8a/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 b115ee6..ec67adb 100644
--- a/net/nimble/host/src/ble_gap_conn.h
+++ b/net/nimble/host/src/ble_gap_conn.h
@@ -18,6 +18,7 @@
 #define H_BLE_GAP_CONN_
 
 #include <inttypes.h>
+#include "host/ble_gap.h"
 struct hci_le_conn_complete;
 struct ble_hs_ack;
 
@@ -28,4 +29,7 @@ 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/c4ff5a8a/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 ad15aeb..b94d75f 100644
--- a/net/nimble/host/src/test/ble_gap_test.c
+++ b/net/nimble/host/src/test/ble_gap_test.c
@@ -5,11 +5,11 @@
 #include "nimble/hci_transport.h"
 #include "host/ble_hs.h"
 #include "host/ble_hs_test.h"
+#include "host/ble_gap.h"
 #include "ble_hs_test_util.h"
 #include "ble_hs_conn.h"
 #include "ble_hs_work.h"
 #include "ble_gap_conn.h"
-#include "ble_gap.h"
 
 #ifdef ARCH_sim
 #define BLE_GAP_TEST_STACK_SIZE     1024
@@ -22,6 +22,8 @@
 static struct os_task ble_gap_test_task;
 static os_stack_t ble_gap_test_stack[OS_STACK_ALIGN(BLE_GAP_TEST_STACK_SIZE)];
 
+static uint8_t ble_gap_test_peer_addr[6] = { 1, 2, 3, 4, 5, 6 };
+
 static void
 ble_gap_test_misc_rx_ack(uint16_t ocf, uint8_t status)
 {
@@ -36,24 +38,52 @@ ble_gap_test_misc_rx_ack(uint16_t ocf, uint8_t status)
     TEST_ASSERT(rc == 0);
 }
 
+static void
+ble_gap_test_connect_cb(struct ble_gap_connect_desc *desc, void *arg)
+{
+    int *cb_called;
+
+    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);
+}
+
 static void 
 ble_gap_test_task_handler(void *arg) 
 {
     struct hci_le_conn_complete evt;
     uint8_t addr[6] = { 1, 2, 3, 4, 5, 6 };
+    int cb_called;
     int rc;
 
+    /* Set the connect callback so we can verify that it gets called with the
+     * proper arguments.
+     */
+    cb_called = 0;
+    ble_gap_set_connect_cb(ble_gap_test_connect_cb, &cb_called);
+
+    /* Make sure there are no created connections and no connections in
+     * progress.
+     */
     TEST_ASSERT(!ble_hs_work_busy);
     TEST_ASSERT(ble_hs_conn_first() == NULL);
 
+    /* Initiate a direct connection. */
     ble_gap_direct_connection_establishment(0, addr);
     TEST_ASSERT(ble_hs_work_busy);
     TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!cb_called);
 
+    /* Receive an ack for the HCI create-connection command. */
     ble_gap_test_misc_rx_ack(BLE_HCI_OCF_LE_CREATE_CONN, 0);
     TEST_ASSERT(!ble_hs_work_busy);
     TEST_ASSERT(ble_hs_conn_first() == NULL);
+    TEST_ASSERT(!cb_called);
 
+    /* Receive an HCI connection-complete event. */
     memset(&evt, 0, sizeof evt);
     evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
     evt.status = BLE_ERR_SUCCESS;
@@ -62,7 +92,9 @@ ble_gap_test_task_handler(void *arg)
     rc = ble_gap_conn_rx_conn_complete(&evt);
     TEST_ASSERT(rc == 0);
 
+    /* The connection should now be created. */
     TEST_ASSERT(ble_hs_conn_find(2) != NULL);
+    TEST_ASSERT(cb_called);
 
     tu_restart();
 }
@@ -92,4 +124,3 @@ ble_gap_test_all(void)
     ble_gap_test_suite();
     return tu_any_failed;
 }
-