Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master ecb584ed0 -> 7510bb5af


GAP slave modes.


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

Branch: refs/heads/master
Commit: 7510bb5af115e13dc8e9c8aafa3429cb2cb62205
Parents: ecb584e
Author: Christopher Collins <[email protected]>
Authored: Fri Dec 18 13:53:24 2015 -0800
Committer: Christopher Collins <[email protected]>
Committed: Fri Dec 18 15:44:02 2015 -0800

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_gap.h |   7 +-
 net/nimble/host/src/ble_gap_conn.c     | 488 +++++++++++++++++++++-------
 2 files changed, 378 insertions(+), 117 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/7510bb5a/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 c1cef02..d4a9f64 100644
--- a/net/nimble/host/include/host/ble_gap.h
+++ b/net/nimble/host/include/host/ble_gap.h
@@ -59,8 +59,13 @@ struct ble_gap_conn_event {
 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);
+int ble_gap_conn_non_discoverable(void);
+int ble_gap_conn_limited_discoverable(void);
+int ble_gap_conn_general_discoverable(void);
+int ble_gap_conn_non_connectable(void);
 int ble_gap_conn_direct_connectable(int addr_type, uint8_t *addr);
+int ble_gap_conn_undirect_connectable(void);
+int ble_gap_conn_gen_disc(uint32_t duration_ms);
 int ble_gap_conn_direct_connect(int addr_type, uint8_t *addr);
 int ble_gap_conn_terminate(uint16_t handle);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/7510bb5a/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 0f76fa5..dfa1a6f 100644
--- a/net/nimble/host/src/ble_gap_conn.c
+++ b/net/nimble/host/src/ble_gap_conn.c
@@ -72,6 +72,25 @@
 /** 10.24 seconds. */
 #define BLE_GAP_GEN_DISC_SCAN_MIN           (10.24 * 1000)
 
+#define BLE_GAP_CONN_S_TYPE_NONE                            (-1)
+#define BLE_GAP_CONN_S_TYPE_NON_DISC                        0
+#define BLE_GAP_CONN_S_TYPE_LTD_DISC                        1
+#define BLE_GAP_CONN_S_TYPE_GEN_DISC                        2
+#define BLE_GAP_CONN_S_TYPE_NON_CONN                        3
+#define BLE_GAP_CONN_S_TYPE_DIR_CONN                        4
+#define BLE_GAP_CONN_S_TYPE_UND_CONN                        5
+#define BLE_GAP_CONN_S_TYPE_MAX                             6
+
+#define BLE_GAP_CONN_M_TYPE_NONE                            (-1)
+#define BLE_GAP_CONN_M_TYPE_GEN_DISC                        1
+#define BLE_GAP_CONN_M_TYPE_DIR_CONN                        2
+
+static int ble_gap_conn_master_type;
+static int ble_gap_conn_slave_type;
+
+static struct hci_adv_params
+    ble_gap_conn_adv_params[BLE_GAP_CONN_S_TYPE_MAX];
+
 static ble_gap_connect_fn *ble_gap_conn_cb;
 static void *ble_gap_conn_arg;
 
@@ -83,7 +102,7 @@ static struct os_callout_func ble_gap_conn_master_timer;
 static struct os_callout_func ble_gap_conn_slave_timer;
 
 /*****************************************************************************
- * @misc                                                                     *
+ * $misc                                                                     *
  *****************************************************************************/
 
 /**
@@ -149,6 +168,20 @@ ble_gap_conn_notify_terminate(uint16_t handle, uint8_t 
status, uint8_t reason)
     ble_gap_conn_call_cb(&event);
 }
 
+static void
+ble_gap_conn_master_reset_state(void)
+{
+    ble_gap_conn_master_state = BLE_GAP_CONN_STATE_IDLE;
+    ble_gap_conn_master_type = BLE_GAP_CONN_M_TYPE_NONE;
+}
+
+static void
+ble_gap_conn_slave_reset_state(void)
+{
+    ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_IDLE;
+    ble_gap_conn_slave_type = BLE_GAP_CONN_S_TYPE_NONE;
+}
+
 /**
  * Called when an error is encountered while the master-connection-fsm is
  * active.  Resets the state machine, clears the HCI ack callback, and notifies
@@ -164,7 +197,7 @@ ble_gap_conn_master_failed(uint8_t status)
     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_gap_conn_master_reset_state();
 
     switch (old_state) {
     case BLE_GAP_CONN_STATE_M_GEN_DISC_PENDING:
@@ -196,7 +229,7 @@ ble_gap_conn_slave_failed(uint8_t status)
 {
     os_callout_stop(&ble_gap_conn_slave_timer.cf_c);
 
-    ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_IDLE;
+    ble_gap_conn_slave_reset_state();
     ble_gap_conn_notify_connect(status, NULL);
 }
 
@@ -227,7 +260,7 @@ ble_gap_conn_rx_disconn_complete(struct 
hci_disconn_complete *evt)
 int
 ble_gap_conn_master_in_progress(void)
 {
-    return ble_gap_conn_master_state != BLE_GAP_CONN_STATE_IDLE;
+    return ble_gap_conn_master_type != BLE_GAP_CONN_M_TYPE_NONE;
 }
 
 /**
@@ -236,7 +269,7 @@ ble_gap_conn_master_in_progress(void)
 int
 ble_gap_conn_slave_in_progress(void)
 {
-    return ble_gap_conn_slave_state != BLE_GAP_CONN_STATE_IDLE;
+    return ble_gap_conn_slave_type != BLE_GAP_CONN_S_TYPE_NONE;
 }
 
 static int
@@ -246,7 +279,7 @@ ble_gap_conn_accept_new_conn(uint8_t *addr)
     case BLE_GAP_CONN_STATE_M_DIRECT_ACKED:
         if (memcmp(ble_gap_conn_master_addr, addr, BLE_DEV_ADDR_LEN) == 0) {
             os_callout_stop(&ble_gap_conn_master_timer.cf_c);
-            ble_gap_conn_master_state = BLE_GAP_CONN_STATE_IDLE;
+            ble_gap_conn_master_reset_state();
             return 0;
         }
     }
@@ -255,7 +288,7 @@ ble_gap_conn_accept_new_conn(uint8_t *addr)
     case BLE_GAP_CONN_STATE_S_ENABLE_ACKED:
         if (memcmp(ble_gap_conn_slave_addr, addr, BLE_DEV_ADDR_LEN) == 0) {
             os_callout_stop(&ble_gap_conn_master_timer.cf_c);
-            ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_IDLE;
+            ble_gap_conn_slave_reset_state();
             return 0;
         }
         break;
@@ -365,243 +398,385 @@ ble_gap_conn_slave_timer_exp(void *arg)
 }
 
 /*****************************************************************************
- * @general discovery procedure                                              *
+ * $advertise                                                                *
  *****************************************************************************/
 
 static void
-ble_gap_conn_gen_disc_ack_enable(struct ble_hci_ack *ack, void *arg)
+ble_gap_conn_adv_ack_enable(struct ble_hci_ack *ack, void *arg)
 {
-    assert(ble_gap_conn_master_state == BLE_GAP_CONN_STATE_M_GEN_DISC_ENABLE);
+    assert(ble_gap_conn_slave_state == BLE_GAP_CONN_STATE_S_ENABLE);
 
-    if (ack->bha_status != 0) {
-        ble_gap_conn_master_failed(ack->bha_status);
+    if (ack->bha_status != BLE_ERR_SUCCESS) {
+        ble_gap_conn_slave_failed(ack->bha_status);
     } else {
-        ble_gap_conn_master_state = BLE_GAP_CONN_STATE_M_GEN_DISC_ENABLE_ACKED;
+        ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_S_ENABLE_ACKED;
     }
 }
 
 static int
-ble_gap_conn_gen_disc_tx_enable(void *arg)
+ble_gap_conn_adv_tx_enable(void *arg)
 {
     int rc;
 
-    assert(ble_gap_conn_master_state ==
-           BLE_GAP_CONN_STATE_M_GEN_DISC_PARAMS_ACKED);
-
-    ble_gap_conn_master_state = BLE_GAP_CONN_STATE_M_GEN_DISC_ENABLE;
-    ble_hci_ack_set_callback(ble_gap_conn_gen_disc_ack_enable, NULL);
+    assert(ble_gap_conn_slave_state == BLE_GAP_CONN_STATE_S_PARAMS_ACKED);
 
-    rc = host_hci_cmd_le_set_scan_enable(1, 0);
-    if (rc != 0) {
-        ble_gap_conn_master_failed(rc);
-        return rc;
+    rc = host_hci_cmd_le_set_adv_enable(1);
+    if (rc != BLE_ERR_SUCCESS) {
+        ble_gap_conn_slave_failed(rc);
+        return 1;
     }
 
+    ble_hci_ack_set_callback(ble_gap_conn_adv_ack_enable, NULL);
+    ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_S_ENABLE;
+
     return 0;
 }
 
 static void
-ble_gap_conn_gen_disc_ack_params(struct ble_hci_ack *ack, void *arg)
+ble_gap_conn_adv_ack_params(struct ble_hci_ack *ack, void *arg)
 {
     int rc;
 
-    assert(ble_gap_conn_master_state == BLE_GAP_CONN_STATE_M_GEN_DISC_PARAMS);
+    assert(ble_gap_conn_slave_state == BLE_GAP_CONN_STATE_S_PARAMS);
 
-    if (ack->bha_status != 0) {
-        ble_gap_conn_master_failed(ack->bha_status);
+    if (ack->bha_status != BLE_ERR_SUCCESS) {
+        ble_gap_conn_slave_failed(ack->bha_status);
         return;
     }
 
-    ble_gap_conn_master_state = BLE_GAP_CONN_STATE_M_GEN_DISC_PARAMS_ACKED;
+    ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_S_PARAMS_ACKED;
 
-    rc = ble_hci_sched_enqueue(ble_gap_conn_gen_disc_tx_enable, NULL);
+    rc = ble_hci_sched_enqueue(ble_gap_conn_adv_tx_enable,
+                               NULL);
     if (rc != 0) {
-        ble_gap_conn_master_failed(rc);
+        ble_gap_conn_slave_failed(rc);
         return;
     }
 }
 
 static int
-ble_gap_conn_gen_disc_tx_params(void *arg)
+ble_gap_conn_adv_tx_params(void *arg)
 {
+    struct hci_adv_params hap;
     int rc;
 
-    assert(ble_gap_conn_master_state == BLE_GAP_CONN_STATE_M_GEN_DISC_PENDING);
+    assert(ble_gap_conn_slave_state == BLE_GAP_CONN_STATE_S_PENDING);
 
-    ble_gap_conn_master_state = BLE_GAP_CONN_STATE_M_GEN_DISC_PARAMS;
-    ble_hci_ack_set_callback(ble_gap_conn_gen_disc_ack_params, NULL);
+    hap = ble_gap_conn_adv_params[ble_gap_conn_slave_type];
+    memcpy(hap.peer_addr, ble_gap_conn_slave_addr, sizeof hap.peer_addr);
 
-    rc = host_hci_cmd_le_set_scan_params(BLE_HCI_SCAN_TYPE_ACTIVE,
-                                         BLE_GAP_SCAN_FAST_INTERVAL_MIN,
-                                         BLE_GAP_SCAN_FAST_WINDOW,
-                                         BLE_HCI_ADV_OWN_ADDR_PUBLIC,
-                                         BLE_HCI_SCAN_FILT_NO_WL);
+    ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_S_PARAMS;
+    ble_hci_ack_set_callback(ble_gap_conn_adv_ack_params, NULL);
+
+    rc = host_hci_cmd_le_set_adv_params(&hap);
     if (rc != 0) {
-        ble_gap_conn_master_failed(rc);
+        ble_gap_conn_slave_failed(rc);
+        return 1;
+    }
+
+    return 0;
+}
+
+static int
+ble_gap_conn_adv_initiate(void)
+{
+    int rc;
+
+    assert(ble_gap_conn_slave_in_progress());
+
+    ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_S_PENDING;
+
+    rc = ble_hci_sched_enqueue(ble_gap_conn_adv_tx_params, NULL);
+    if (rc != 0) {
+        ble_gap_conn_slave_reset_state();
         return rc;
     }
 
     return 0;
 }
 
+/*****************************************************************************
+ * $non-discoverable mode                                                    *
+ *****************************************************************************/
+
 /**
- * Performs the General Discovery Procedure, as described in
- * vol. 3, part C, section 9.2.6.
+ * Enables Non-Discoverable Mode, as described in vol. 3, part C, section
+ * 9.2.2.
  *
  * @return                      0 on success; nonzero on failure.
  */
 int
-ble_gap_conn_gen_disc(uint32_t duration_ms)
+ble_gap_conn_non_discoverable(void)
 {
     int rc;
 
-    /* Make sure no master connection attempt is already in progress. */
-    if (ble_gap_conn_master_in_progress()) {
+    /* Make sure no slave connection attempt is already in progress. */
+    if (ble_gap_conn_slave_in_progress()) {
         return BLE_HS_EALREADY;
     }
 
-    if (duration_ms == 0) {
-        duration_ms = BLE_GAP_GEN_DISC_SCAN_MIN;
+    ble_gap_conn_slave_type = BLE_GAP_CONN_S_TYPE_NON_DISC;
+
+    rc = ble_gap_conn_adv_initiate();
+    return rc;
+}
+
+/*****************************************************************************
+ * $limited-discoverable mode                                                *
+ *****************************************************************************/
+
+/**
+ * Enables Limited-Discoverable Mode, as described in vol. 3, part C, section
+ * 9.2.3.
+ *
+ * @return                      0 on success; nonzero on failure.
+ */
+int
+ble_gap_conn_limited_discoverable(void)
+{
+    int rc;
+
+    /* Make sure no slave connection attempt is already in progress. */
+    if (ble_gap_conn_slave_in_progress()) {
+        return BLE_HS_EALREADY;
     }
 
-    ble_gap_conn_master_state = BLE_GAP_CONN_STATE_M_GEN_DISC_PENDING;
-    memset(ble_gap_conn_master_addr, 0, BLE_DEV_ADDR_LEN);
+    ble_gap_conn_slave_type = BLE_GAP_CONN_S_TYPE_LTD_DISC;
 
-    rc = ble_hci_sched_enqueue(ble_gap_conn_gen_disc_tx_params, NULL);
-    if (rc != 0) {
-        ble_gap_conn_master_state = BLE_GAP_CONN_STATE_IDLE;
-        return rc;
+    rc = ble_gap_conn_adv_initiate();
+    return rc;
+}
+
+/*****************************************************************************
+ * $general-discoverable mode                                                *
+ *****************************************************************************/
+
+/**
+ * Enables General-Discoverable Mode, as described in vol. 3, part C, section
+ * 9.2.4.
+ *
+ * @return                      0 on success; nonzero on failure.
+ */
+int
+ble_gap_conn_general_discoverable(void)
+{
+    int rc;
+
+    /* Make sure no slave connection attempt is already in progress. */
+    if (ble_gap_conn_slave_in_progress()) {
+        return BLE_HS_EALREADY;
     }
 
-    os_callout_reset(&ble_gap_conn_master_timer.cf_c,
-                     duration_ms * OS_TICKS_PER_SEC / 1000);
+    ble_gap_conn_slave_type = BLE_GAP_CONN_S_TYPE_GEN_DISC;
 
-    return 0;
+    rc = ble_gap_conn_adv_initiate();
+    return rc;
+}
+
+/*****************************************************************************
+ * $non-connectable mode                                                     *
+ *****************************************************************************/
+
+/**
+ * Enables Non-Connectable Mode, as described in vol. 3, part C, section 9.3.2.
+ *
+ * @return                      0 on success; nonzero on failure.
+ */
+int
+ble_gap_conn_non_connectable(void)
+{
+    int rc;
+
+    /* Make sure no slave connection attempt is already in progress. */
+    if (ble_gap_conn_slave_in_progress()) {
+        return BLE_HS_EALREADY;
+    }
+
+    ble_gap_conn_slave_type = BLE_GAP_CONN_S_TYPE_NON_CONN;
+
+    rc = ble_gap_conn_adv_initiate();
+    return rc;
+}
+
+/*****************************************************************************
+ * $directed connectable mode                                                *
+ *****************************************************************************/
+
+/**
+ * Enables Directed Connectable Mode, as described in vol. 3, part C, section
+ * 9.3.3.
+ *
+ * @param addr_type             The peer's address type; one of:
+ *                                  o BLE_HCI_ADV_PEER_ADDR_PUBLIC
+ *                                  o BLE_HCI_ADV_PEER_ADDR_RANDOM
+ *                                  o BLE_HCI_ADV_PEER_ADDR_PUBLIC_IDENT
+ *                                  o BLE_HCI_ADV_PEER_ADDR_RANDOM_IDENT
+ * @param addr                  The address of the peer to connect to.
+ *
+ * @return                      0 on success; nonzero on failure.
+ */
+int
+ble_gap_conn_direct_connectable(int addr_type, uint8_t *addr)
+{
+    int rc;
+
+    /* Make sure no slave connection attempt is already in progress. */
+    if (ble_gap_conn_slave_in_progress()) {
+        return BLE_HS_EALREADY;
+    }
+
+    ble_gap_conn_slave_type = BLE_GAP_CONN_S_TYPE_DIR_CONN;
+    memcpy(ble_gap_conn_slave_addr, addr, BLE_DEV_ADDR_LEN);
+
+    rc = ble_gap_conn_adv_initiate();
+    return rc;
 }
 
 /*****************************************************************************
- * @directed connectable mode                                                *
+ * $undirected connectable mode                                              *
+ *****************************************************************************/
+
+/**
+ * Enables Undirected Connectable Mode, as described in vol. 3, part C, section
+ * 9.3.4.
+ *
+ * @return                      0 on success; nonzero on failure.
+ */
+int
+ble_gap_conn_undirect_connectable(void)
+{
+    int rc;
+
+    /* Make sure no slave connection attempt is already in progress. */
+    if (ble_gap_conn_slave_in_progress()) {
+        return BLE_HS_EALREADY;
+    }
+
+    ble_gap_conn_slave_type = BLE_GAP_CONN_S_TYPE_UND_CONN;
+
+    rc = ble_gap_conn_adv_initiate();
+    return rc;
+}
+
+/*****************************************************************************
+ * $general discovery procedure                                              *
  *****************************************************************************/
 
 static void
-ble_gap_conn_direct_connectable_ack_enable(struct ble_hci_ack *ack, void *arg)
+ble_gap_conn_gen_disc_ack_enable(struct ble_hci_ack *ack, void *arg)
 {
-    assert(ble_gap_conn_slave_state == BLE_GAP_CONN_STATE_S_ENABLE);
+    assert(ble_gap_conn_master_state == BLE_GAP_CONN_STATE_M_GEN_DISC_ENABLE);
 
-    if (ack->bha_status != BLE_ERR_SUCCESS) {
-        ble_gap_conn_slave_failed(ack->bha_status);
+    if (ack->bha_status != 0) {
+        ble_gap_conn_master_failed(ack->bha_status);
     } else {
-        ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_S_ENABLE_ACKED;
+        ble_gap_conn_master_state = BLE_GAP_CONN_STATE_M_GEN_DISC_ENABLE_ACKED;
     }
 }
 
 static int
-ble_gap_conn_direct_connectable_tx_enable(void *arg)
+ble_gap_conn_gen_disc_tx_enable(void *arg)
 {
     int rc;
 
-    assert(ble_gap_conn_slave_state == BLE_GAP_CONN_STATE_S_PARAMS_ACKED);
+    assert(ble_gap_conn_master_state ==
+           BLE_GAP_CONN_STATE_M_GEN_DISC_PARAMS_ACKED);
 
-    rc = host_hci_cmd_le_set_adv_enable(1);
-    if (rc != BLE_ERR_SUCCESS) {
-        ble_gap_conn_slave_failed(rc);
-        return 1;
-    }
+    ble_gap_conn_master_state = BLE_GAP_CONN_STATE_M_GEN_DISC_ENABLE;
+    ble_hci_ack_set_callback(ble_gap_conn_gen_disc_ack_enable, NULL);
 
-    ble_hci_ack_set_callback(ble_gap_conn_direct_connectable_ack_enable, NULL);
-    ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_S_ENABLE;
+    rc = host_hci_cmd_le_set_scan_enable(1, 0);
+    if (rc != 0) {
+        ble_gap_conn_master_failed(rc);
+        return rc;
+    }
 
     return 0;
 }
 
 static void
-ble_gap_conn_direct_connectable_ack_params(struct ble_hci_ack *ack, void *arg)
+ble_gap_conn_gen_disc_ack_params(struct ble_hci_ack *ack, void *arg)
 {
     int rc;
 
-    assert(ble_gap_conn_slave_state == BLE_GAP_CONN_STATE_S_PARAMS);
+    assert(ble_gap_conn_master_state == BLE_GAP_CONN_STATE_M_GEN_DISC_PARAMS);
 
-    if (ack->bha_status != BLE_ERR_SUCCESS) {
-        ble_gap_conn_slave_failed(ack->bha_status);
+    if (ack->bha_status != 0) {
+        ble_gap_conn_master_failed(ack->bha_status);
         return;
     }
 
-    ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_S_PARAMS_ACKED;
+    ble_gap_conn_master_state = BLE_GAP_CONN_STATE_M_GEN_DISC_PARAMS_ACKED;
 
-    rc = ble_hci_sched_enqueue(ble_gap_conn_direct_connectable_tx_enable,
-                               NULL);
+    rc = ble_hci_sched_enqueue(ble_gap_conn_gen_disc_tx_enable, NULL);
     if (rc != 0) {
-        ble_gap_conn_slave_failed(rc);
+        ble_gap_conn_master_failed(rc);
         return;
     }
 }
 
 static int
-ble_gap_conn_direct_connectable_tx_params(void *arg)
+ble_gap_conn_gen_disc_tx_params(void *arg)
 {
-    struct hci_adv_params hap;
     int rc;
 
-    assert(ble_gap_conn_slave_state == BLE_GAP_CONN_STATE_S_PENDING);
-
-    hap.adv_itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN;
-    hap.adv_itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MAX;
-    hap.adv_type = BLE_HCI_ADV_TYPE_ADV_IND;
-    hap.own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC;
-    hap.peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC;
-    memcpy(hap.peer_addr, ble_gap_conn_slave_addr, sizeof hap.peer_addr);
-    hap.adv_channel_map = BLE_HCI_ADV_CHANMASK_DEF;
-    hap.adv_filter_policy = BLE_HCI_ADV_FILT_DEF;
+    assert(ble_gap_conn_master_state == BLE_GAP_CONN_STATE_M_GEN_DISC_PENDING);
 
-    ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_S_PARAMS;
-    ble_hci_ack_set_callback(ble_gap_conn_direct_connectable_ack_params, NULL);
+    ble_gap_conn_master_state = BLE_GAP_CONN_STATE_M_GEN_DISC_PARAMS;
+    ble_hci_ack_set_callback(ble_gap_conn_gen_disc_ack_params, NULL);
 
-    rc = host_hci_cmd_le_set_adv_params(&hap);
+    rc = host_hci_cmd_le_set_scan_params(BLE_HCI_SCAN_TYPE_ACTIVE,
+                                         BLE_GAP_SCAN_FAST_INTERVAL_MIN,
+                                         BLE_GAP_SCAN_FAST_WINDOW,
+                                         BLE_HCI_ADV_OWN_ADDR_PUBLIC,
+                                         BLE_HCI_SCAN_FILT_NO_WL);
     if (rc != 0) {
-        ble_gap_conn_slave_failed(rc);
-        return 1;
+        ble_gap_conn_master_failed(rc);
+        return rc;
     }
 
     return 0;
 }
 
 /**
- * Enables Directed Connectable Mode, as described in vol. 3, part C, section
- * 9.3.3.
- *
- * @param addr_type             The peer's address type; one of:
- *                                  o BLE_HCI_ADV_PEER_ADDR_PUBLIC
- *                                  o BLE_HCI_ADV_PEER_ADDR_RANDOM
- *                                  o BLE_HCI_ADV_PEER_ADDR_PUBLIC_IDENT
- *                                  o BLE_HCI_ADV_PEER_ADDR_RANDOM_IDENT
- * @param addr                  The address of the peer to connect to.
+ * Performs the General Discovery Procedure, as described in
+ * vol. 3, part C, section 9.2.6.
  *
  * @return                      0 on success; nonzero on failure.
  */
 int
-ble_gap_conn_direct_connectable(int addr_type, uint8_t *addr)
+ble_gap_conn_gen_disc(uint32_t duration_ms)
 {
     int rc;
 
-    /* Make sure no slave connection attempt is already in progress. */
-    if (ble_gap_conn_slave_in_progress()) {
+    /* Make sure no master connection attempt is already in progress. */
+    if (ble_gap_conn_master_in_progress()) {
         return BLE_HS_EALREADY;
     }
 
-    ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_S_PENDING;
-    memcpy(ble_gap_conn_slave_addr, addr, BLE_DEV_ADDR_LEN);
+    ble_gap_conn_master_type = BLE_GAP_CONN_M_TYPE_GEN_DISC;
 
-    rc = ble_hci_sched_enqueue(ble_gap_conn_direct_connectable_tx_params,
-                               NULL);
+    if (duration_ms == 0) {
+        duration_ms = BLE_GAP_GEN_DISC_SCAN_MIN;
+    }
+
+    ble_gap_conn_master_state = BLE_GAP_CONN_STATE_M_GEN_DISC_PENDING;
+    memset(ble_gap_conn_master_addr, 0, BLE_DEV_ADDR_LEN);
+
+    rc = ble_hci_sched_enqueue(ble_gap_conn_gen_disc_tx_params, NULL);
     if (rc != 0) {
+        ble_gap_conn_master_reset_state();
         return rc;
     }
 
+    os_callout_reset(&ble_gap_conn_master_timer.cf_c,
+                     duration_ms * OS_TICKS_PER_SEC / 1000);
+
     return 0;
 }
 
 /*****************************************************************************
- * @direct connection establishment procedure                                *
+ * $direct connection establishment procedure                                *
  *****************************************************************************/
 
 /**
@@ -678,12 +853,13 @@ ble_gap_conn_direct_connect(int addr_type, uint8_t *addr)
         return BLE_HS_EALREADY;
     }
 
+    ble_gap_conn_master_type = BLE_GAP_CONN_M_TYPE_DIR_CONN;
     ble_gap_conn_master_state = BLE_GAP_CONN_STATE_M_DIRECT_PENDING;
     memcpy(ble_gap_conn_master_addr, addr, BLE_DEV_ADDR_LEN);
 
     rc = ble_hci_sched_enqueue(ble_gap_conn_direct_connect_tx, NULL);
     if (rc != 0) {
-        ble_gap_conn_master_state = BLE_GAP_CONN_STATE_IDLE;
+        ble_gap_conn_master_reset_state();
         return rc;
     }
 
@@ -691,7 +867,7 @@ ble_gap_conn_direct_connect(int addr_type, uint8_t *addr)
 }
 
 /*****************************************************************************
- * @terminate connection procedure                                           *
+ * $terminate connection procedure                                           *
  *****************************************************************************/
 
 static void
@@ -743,18 +919,98 @@ ble_gap_conn_terminate(uint16_t handle)
 }
 
 /*****************************************************************************
- * @init                                                                     *
+ * $init                                                                     *
  *****************************************************************************/
 
+static void
+ble_gap_conn_init_slave_params(void)
+{
+    ble_gap_conn_adv_params[BLE_GAP_CONN_S_TYPE_NON_DISC] =
+        (struct hci_adv_params) {
+
+        .adv_itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN,
+        .adv_itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MAX,
+        .adv_type = BLE_HCI_ADV_TYPE_ADV_IND,
+        .own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC,
+        .peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC,
+        .adv_channel_map = BLE_HCI_ADV_CHANMASK_DEF,
+        .adv_filter_policy = BLE_HCI_ADV_FILT_DEF,
+    };
+
+    ble_gap_conn_adv_params[BLE_GAP_CONN_S_TYPE_LTD_DISC] =
+        (struct hci_adv_params) {
+
+        .adv_itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN,
+        .adv_itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MAX,
+        .adv_type = BLE_HCI_ADV_TYPE_ADV_IND,
+        .own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC,
+        .peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC,
+        .adv_channel_map = BLE_HCI_ADV_CHANMASK_DEF,
+        .adv_filter_policy = BLE_HCI_ADV_FILT_DEF,
+    };
+
+    ble_gap_conn_adv_params[BLE_GAP_CONN_S_TYPE_GEN_DISC] =
+        (struct hci_adv_params) {
+
+        .adv_itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN,
+        .adv_itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MAX,
+        .adv_type = BLE_HCI_ADV_TYPE_ADV_IND,
+        .own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC,
+        .peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC,
+        .adv_channel_map = BLE_HCI_ADV_CHANMASK_DEF,
+        .adv_filter_policy = BLE_HCI_ADV_FILT_DEF,
+    };
+
+    ble_gap_conn_adv_params[BLE_GAP_CONN_S_TYPE_NON_CONN] =
+        (struct hci_adv_params) {
+
+        .adv_itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN,
+        .adv_itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MAX,
+        .adv_type = BLE_HCI_ADV_TYPE_ADV_IND,
+        .own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC,
+        .peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC,
+        .adv_channel_map = BLE_HCI_ADV_CHANMASK_DEF,
+        .adv_filter_policy = BLE_HCI_ADV_FILT_DEF,
+    };
+
+    ble_gap_conn_adv_params[BLE_GAP_CONN_S_TYPE_DIR_CONN] =
+        (struct hci_adv_params) {
+
+        .adv_itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN,
+        .adv_itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MAX,
+        .adv_type = BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD,
+        .own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC,
+        .peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC,
+        .adv_channel_map = BLE_HCI_ADV_CHANMASK_DEF,
+        .adv_filter_policy = BLE_HCI_ADV_FILT_DEF,
+    };
+
+    ble_gap_conn_adv_params[BLE_GAP_CONN_S_TYPE_UND_CONN] =
+        (struct hci_adv_params) {
+
+        .adv_itvl_min = BLE_GAP_ADV_FAST_INTERVAL1_MIN,
+        .adv_itvl_max = BLE_GAP_ADV_FAST_INTERVAL1_MAX,
+        .adv_type = BLE_HCI_ADV_TYPE_ADV_IND,
+        .own_addr_type = BLE_HCI_ADV_OWN_ADDR_PUBLIC,
+        .peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC,
+        .adv_channel_map = BLE_HCI_ADV_CHANMASK_DEF,
+        .adv_filter_policy = BLE_HCI_ADV_FILT_DEF,
+    };
+}
+
 int
 ble_gap_conn_init(void)
 {
     ble_gap_conn_cb = NULL;
+    ble_gap_conn_master_type = BLE_GAP_CONN_M_TYPE_NONE;
+    ble_gap_conn_slave_type = BLE_GAP_CONN_S_TYPE_NONE;
     ble_gap_conn_master_state = BLE_GAP_CONN_STATE_IDLE;
     ble_gap_conn_slave_state = BLE_GAP_CONN_STATE_IDLE;
     memset(ble_gap_conn_master_addr, 0, sizeof ble_gap_conn_master_addr);
     memset(ble_gap_conn_slave_addr, 0, sizeof ble_gap_conn_slave_addr);
 
+    ble_gap_conn_init_slave_params();
+
     os_callout_func_init(&ble_gap_conn_master_timer, &ble_hs_evq,
                          ble_gap_conn_master_timer_exp, NULL);
     os_callout_func_init(&ble_gap_conn_slave_timer, &ble_hs_evq,

Reply via email to