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 2016/04/07 01:52:06 UTC

[1/4] incubator-mynewt-core git commit: MYNEWT-265 BLE - advertise iBeacon

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop 738c6e7ca -> 03a60f654


MYNEWT-265 BLE - advertise iBeacon

Combine non/und/dir adv state machines.  Prior to this change, the slave
used separate state machines for different connectable modes.  The code
is simpler (and smaller) if all connectable modes use the same state
machine.


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

Branch: refs/heads/develop
Commit: 338fe0f5c84f7dbc53772639bb665223aadae249
Parents: 13747ab
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Apr 6 11:18:16 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 6 16:50:17 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_gap.c               | 148 ++++++++++-------------
 net/nimble/host/src/test/ble_gap_test.c     |   8 ++
 net/nimble/host/src/test/ble_hs_conn_test.c |   6 +
 3 files changed, 77 insertions(+), 85 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/338fe0f5/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 750c1aa..1b05856 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -32,9 +32,7 @@
 #define BLE_GAP_OP_M_DISC                               1
 #define BLE_GAP_OP_M_CONN                               2
 
-#define BLE_GAP_OP_S_NON                                1
-#define BLE_GAP_OP_S_UND                                2
-#define BLE_GAP_OP_S_DIR                                3
+#define BLE_GAP_OP_S_ADV                                1
 
 #define BLE_GAP_OP_W_SET                                1
 
@@ -49,18 +47,13 @@
 #define BLE_GAP_STATE_M_UNACKED                         1
 #define BLE_GAP_STATE_M_ACKED                           2
 
-/** Undirected slave states. */
-#define BLE_GAP_STATE_S_UND_PARAMS                      0
-#define BLE_GAP_STATE_S_UND_POWER                       1
-#define BLE_GAP_STATE_S_UND_ADV_DATA                    2
-#define BLE_GAP_STATE_S_UND_RSP_DATA                    3
-#define BLE_GAP_STATE_S_UND_ENABLE                      4
-#define BLE_GAP_STATE_S_UND_ADV                         5
-
-/** Directed slave states. */
-#define BLE_GAP_STATE_S_DIR_PARAMS                      0
-#define BLE_GAP_STATE_S_DIR_ENABLE                      1
-#define BLE_GAP_STATE_S_DIR_ADV                         2
+/** Slave states. */
+#define BLE_GAP_STATE_S_PARAMS                          0
+#define BLE_GAP_STATE_S_POWER                           1
+#define BLE_GAP_STATE_S_ADV_DATA                        2
+#define BLE_GAP_STATE_S_RSP_DATA                        3
+#define BLE_GAP_STATE_S_ENABLE                          4
+#define BLE_GAP_STATE_S_ADV                             5
 
 /** White list states. */
 #define BLE_GAP_STATE_W_CLEAR                           0
@@ -143,6 +136,8 @@ static bssnz_t struct {
  */
 static bssnz_t struct {
     uint8_t op;
+
+    uint8_t conn_mode;
     uint8_t state;
     uint8_t disc_mode;
     uint8_t hci_handle;
@@ -197,18 +192,12 @@ static int ble_gap_wl_tx_add(void *arg);
 static int ble_gap_disc_tx_disable(void *arg);
 
 static ble_hci_sched_tx_fn * const ble_gap_dispatch_adv_und[] = {
-    [BLE_GAP_STATE_S_UND_PARAMS]   = ble_gap_adv_params_tx,
-    [BLE_GAP_STATE_S_UND_POWER]    = ble_gap_adv_power_tx,
-    [BLE_GAP_STATE_S_UND_ADV_DATA] = ble_gap_adv_data_tx,
-    [BLE_GAP_STATE_S_UND_RSP_DATA] = ble_gap_adv_rsp_data_tx,
-    [BLE_GAP_STATE_S_UND_ENABLE]   = ble_gap_adv_enable_tx,
-    [BLE_GAP_STATE_S_UND_ADV]      = NULL,
-};
-
-static ble_hci_sched_tx_fn * const ble_gap_dispatch_adv_dir[] = {
-    [BLE_GAP_STATE_S_DIR_PARAMS]   = ble_gap_adv_params_tx,
-    [BLE_GAP_STATE_S_DIR_ENABLE]   = ble_gap_adv_enable_tx,
-    [BLE_GAP_STATE_S_DIR_ADV]      = NULL,
+    [BLE_GAP_STATE_S_PARAMS]   = ble_gap_adv_params_tx,
+    [BLE_GAP_STATE_S_POWER]    = ble_gap_adv_power_tx,
+    [BLE_GAP_STATE_S_ADV_DATA] = ble_gap_adv_data_tx,
+    [BLE_GAP_STATE_S_RSP_DATA] = ble_gap_adv_rsp_data_tx,
+    [BLE_GAP_STATE_S_ENABLE]   = ble_gap_adv_enable_tx,
+    [BLE_GAP_STATE_S_ADV]      = NULL,
 };
 
 struct ble_gap_snapshot {
@@ -638,7 +627,8 @@ ble_gap_update_find(uint16_t conn_handle)
 }
 
 /**
- * Lock restrictions: None.
+ * Lock restrictions:
+ *     o Caller unlocks gap.
  */
 static struct ble_gap_update_entry *
 ble_gap_update_entry_alloc(uint16_t conn_handle,
@@ -1017,23 +1007,8 @@ ble_gap_wl_set_op(uint8_t op)
 static int
 ble_gap_currently_advertising(void)
 {
-    switch (ble_gap_slave.op) {
-    case BLE_GAP_OP_NULL:
-        return 0;
-
-    case BLE_GAP_OP_S_NON:
-        return ble_gap_slave.state == BLE_GAP_STATE_S_UND_ADV;
-
-    case BLE_GAP_OP_S_UND:
-        return ble_gap_slave.state == BLE_GAP_STATE_S_UND_ADV;
-
-    case BLE_GAP_OP_S_DIR:
-        return ble_gap_slave.state == BLE_GAP_STATE_S_DIR_ADV;
-
-    default:
-        BLE_HS_DBG_ASSERT(0);
-        return 0;
-    }
+    return ble_gap_slave.op == BLE_GAP_OP_S_ADV &&
+           ble_gap_slave.state == BLE_GAP_STATE_S_ADV;
 }
 
 /**
@@ -1144,17 +1119,16 @@ ble_gap_accept_slave_conn(uint8_t addr_type, uint8_t *addr)
     if (!ble_gap_currently_advertising()) {
         rc = BLE_HS_ENOENT;
     } else {
-        switch (ble_gap_slave.op) {
-        case BLE_GAP_OP_NULL:
-        case BLE_GAP_OP_S_NON:
+        switch (ble_gap_slave.conn_mode) {
+        case BLE_GAP_CONN_MODE_NON:
             rc = BLE_HS_ENOENT;
             break;
 
-        case BLE_GAP_OP_S_UND:
+        case BLE_GAP_CONN_MODE_UND:
             rc = 0;
             break;
 
-        case BLE_GAP_OP_S_DIR:
+        case BLE_GAP_CONN_MODE_DIR:
             if (ble_gap_slave.dir_addr_type != addr_type ||
                 memcmp(ble_gap_slave.dir_addr, addr, BLE_DEV_ADDR_LEN) != 0) {
 
@@ -1653,9 +1627,7 @@ ble_gap_adv_ack_disable(struct ble_hci_ack *ack, void *arg)
         /* Advertising should now be aborted. */
         ble_gap_call_slave_cb(BLE_GAP_EVENT_ADV_FINISHED, 0, 1);
     } else {
-
-        ble_gap_call_slave_cb(BLE_GAP_EVENT_ADV_STOP,
-                              ack->bha_status, 0);
+        ble_gap_call_slave_cb(BLE_GAP_EVENT_ADV_STOP, ack->bha_status, 0);
     }
 }
 
@@ -1671,8 +1643,7 @@ ble_gap_adv_disable_tx(void *arg)
     ble_hci_sched_set_ack_cb(ble_gap_adv_ack_disable, NULL);
     rc = host_hci_cmd_le_set_adv_enable(0);
     if (rc != BLE_ERR_SUCCESS) {
-        ble_gap_call_slave_cb(BLE_GAP_EVENT_ADV_STOP,
-                                   BLE_HS_HCI_ERR(rc), 0);
+        ble_gap_call_slave_cb(BLE_GAP_EVENT_ADV_STOP, BLE_HS_HCI_ERR(rc), 0);
         return 1;
     }
 
@@ -1747,8 +1718,6 @@ ble_gap_adv_itvls(uint8_t disc_mode, uint8_t conn_mode,
 
     default:
         BLE_HS_DBG_ASSERT(0);
-        *out_itvl_min = BLE_GAP_ADV_FAST_INTERVAL2_MIN;
-        *out_itvl_max = BLE_GAP_ADV_FAST_INTERVAL2_MAX;
         break;
     }
 }
@@ -1759,19 +1728,34 @@ ble_gap_adv_itvls(uint8_t disc_mode, uint8_t conn_mode,
 static ble_hci_sched_tx_fn *
 ble_gap_adv_get_dispatch(void)
 {
-    switch (ble_gap_slave.op) {
-    case BLE_GAP_OP_S_NON:
-        return ble_gap_dispatch_adv_und[ble_gap_slave.state];
+    return ble_gap_dispatch_adv_und[ble_gap_slave.state];
+}
 
-    case BLE_GAP_OP_S_UND:
-        return ble_gap_dispatch_adv_und[ble_gap_slave.state];
+static int
+ble_gap_adv_should_exec_state(void)
+{
+    switch (ble_gap_slave.state) {
+    case BLE_GAP_STATE_S_PARAMS:
+        return 1;
+
+    case BLE_GAP_STATE_S_POWER:
+        return ble_gap_slave.adv_pwr_lvl;
+
+    case BLE_GAP_STATE_S_ADV_DATA:
+        return ble_gap_slave.conn_mode != BLE_GAP_CONN_MODE_DIR;
 
-    case BLE_GAP_OP_S_DIR:
-        return ble_gap_dispatch_adv_dir[ble_gap_slave.state];
+    case BLE_GAP_STATE_S_RSP_DATA:
+        return ble_gap_slave.conn_mode != BLE_GAP_CONN_MODE_DIR;
+
+    case BLE_GAP_STATE_S_ENABLE:
+        return 1;
+
+    case BLE_GAP_STATE_S_ADV:
+        return 1;
 
     default:
         BLE_HS_DBG_ASSERT(0);
-        return NULL;
+        return 1;
     }
 }
 
@@ -1785,7 +1769,10 @@ ble_gap_adv_next_state(void)
     ble_hci_sched_tx_fn *tx_fn;
     int rc;
 
-    ble_gap_slave.state++;
+    do {
+        ble_gap_slave.state++;
+    } while (!ble_gap_adv_should_exec_state());
+
     tx_fn = ble_gap_adv_get_dispatch();
     if (tx_fn != NULL) {
         rc = ble_hci_sched_enqueue(tx_fn, NULL, &ble_gap_slave.hci_handle);
@@ -1988,18 +1975,17 @@ ble_gap_adv_params_tx(void *arg)
 
     hap = ble_gap_slave.adv_params;
 
-    switch (ble_gap_slave.op) {
-    case BLE_GAP_OP_S_NON:
+    switch (ble_gap_slave.conn_mode) {
+    case BLE_GAP_CONN_MODE_NON:
         hap.adv_type = BLE_HCI_ADV_TYPE_ADV_NONCONN_IND;
         break;
 
-    case BLE_GAP_OP_S_DIR:
+    case BLE_GAP_CONN_MODE_DIR:
         hap.adv_type = BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD;
-        memcpy(hap.peer_addr, ble_gap_slave.dir_addr,
-               sizeof hap.peer_addr);
+        memcpy(hap.peer_addr, ble_gap_slave.dir_addr, sizeof hap.peer_addr);
         break;
 
-    case BLE_GAP_OP_S_UND:
+    case BLE_GAP_CONN_MODE_UND:
         hap.adv_type = BLE_HCI_ADV_TYPE_ADV_IND;
         break;
 
@@ -2064,14 +2050,11 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode,
     return BLE_HS_ENOTSUP;
 #endif
 
-    uint8_t op;
     int rc;
 
     STATS_INC(ble_gap_stats, adv_start);
 
-    if (discoverable_mode >= BLE_GAP_DISC_MODE_MAX ||
-        connectable_mode >= BLE_GAP_CONN_MODE_MAX) {
-
+    if (discoverable_mode >= BLE_GAP_DISC_MODE_MAX) {
         rc = BLE_HS_EINVAL;
         goto done;
     }
@@ -2088,11 +2071,7 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode,
 
     switch (connectable_mode) {
     case BLE_GAP_CONN_MODE_NON:
-        op = BLE_GAP_OP_S_NON;
-        break;
-
     case BLE_GAP_CONN_MODE_UND:
-        op = BLE_GAP_OP_S_UND;
         break;
 
     case BLE_GAP_CONN_MODE_DIR:
@@ -2102,16 +2081,14 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode,
             rc = BLE_HS_EINVAL;
             goto done;
         }
-
-        op = BLE_GAP_OP_S_DIR;
         break;
 
     default:
-        BLE_HS_DBG_ASSERT(0);
-        break;
+        rc = BLE_HS_EINVAL;
+        goto done;
     }
 
-    rc = ble_gap_slave_set_op(op);
+    rc = ble_gap_slave_set_op(BLE_GAP_OP_S_ADV);
     if (rc != 0) {
         goto done;
     }
@@ -2124,6 +2101,7 @@ ble_gap_adv_start(uint8_t discoverable_mode, uint8_t connectable_mode,
     ble_gap_slave.cb = cb;
     ble_gap_slave.cb_arg = cb_arg;
     ble_gap_slave.state = 0;
+    ble_gap_slave.conn_mode = connectable_mode;
     ble_gap_slave.disc_mode = discoverable_mode;
 
     if (adv_params != NULL) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/338fe0f5/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 a530952..25bd5d1 100644
--- a/net/nimble/host/src/test/ble_gap_test.c
+++ b/net/nimble/host/src/test/ble_gap_test.c
@@ -1205,6 +1205,7 @@ ble_gap_test_util_adv(uint8_t disc_mode, uint8_t conn_mode,
                       int cmd_fail_idx, uint8_t hci_status)
 {
     struct hci_le_conn_complete evt;
+    struct ble_hs_adv_fields adv_fields;
     int cmd_idx;
     int rc;
 
@@ -1213,6 +1214,13 @@ ble_gap_test_util_adv(uint8_t disc_mode, uint8_t conn_mode,
 
     TEST_ASSERT(!ble_gap_slave_in_progress());
 
+    if (conn_mode != BLE_GAP_CONN_MODE_DIR) {
+        memset(&adv_fields, 0, sizeof adv_fields);
+        adv_fields.tx_pwr_lvl_is_present = 1;
+        rc = ble_gap_adv_set_fields(&adv_fields);
+        TEST_ASSERT_FATAL(rc == 0);
+    }
+
     rc = ble_gap_adv_start(disc_mode, conn_mode, peer_addr, peer_addr_type,
                            NULL, ble_gap_test_util_connect_cb, NULL);
     TEST_ASSERT(rc == 0);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/338fe0f5/net/nimble/host/src/test/ble_hs_conn_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_conn_test.c b/net/nimble/host/src/test/ble_hs_conn_test.c
index e7e7990..a4334e0 100644
--- a/net/nimble/host/src/test/ble_hs_conn_test.c
+++ b/net/nimble/host/src/test/ble_hs_conn_test.c
@@ -214,6 +214,7 @@ TEST_CASE(ble_hs_conn_test_direct_connectable_hci_errors)
 
 TEST_CASE(ble_hs_conn_test_undirect_connectable_success)
 {
+    struct ble_hs_adv_fields adv_fields;
     struct hci_le_conn_complete evt;
     struct ble_l2cap_chan *chan;
     struct ble_hs_conn *conn;
@@ -228,6 +229,11 @@ TEST_CASE(ble_hs_conn_test_undirect_connectable_success)
     TEST_ASSERT(ble_hs_conn_first() == NULL);
 
     /* Initiate advertising. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    rc = ble_gap_adv_set_fields(&adv_fields);
+    TEST_ASSERT_FATAL(rc == 0);
+
     rc = ble_gap_adv_start(BLE_GAP_DISC_MODE_NON, BLE_GAP_CONN_MODE_UND,
                            NULL, 0, NULL, NULL, NULL);
     TEST_ASSERT(rc == 0);


[4/4] incubator-mynewt-core git commit: MYNEWT-265 BLE - advertise iBeacon

Posted by cc...@apache.org.
MYNEWT-265 BLE - advertise iBeacon


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

Branch: refs/heads/develop
Commit: 03a60f654edf91393ec217240e2ba1e2311ebaeb
Parents: 8fc5098
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Apr 6 16:49:56 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 6 16:50:43 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_hs.h |  1 +
 net/nimble/host/src/ble_ibeacon.c     | 68 ++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/03a60f65/net/nimble/host/include/host/ble_hs.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs.h b/net/nimble/host/include/host/ble_hs.h
index 1016ccd..dfffc97 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -105,6 +105,7 @@ struct ble_hs_cfg {
 
 extern const struct ble_hs_cfg ble_hs_cfg_dflt;
 
+int ble_ibeacon_set_adv_data(void *uuid128, uint16_t major, uint16_t minor);
 int ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/03a60f65/net/nimble/host/src/ble_ibeacon.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_ibeacon.c b/net/nimble/host/src/ble_ibeacon.c
new file mode 100644
index 0000000..92cf382
--- /dev/null
+++ b/net/nimble/host/src/ble_ibeacon.c
@@ -0,0 +1,68 @@
+/**
+ * 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 <string.h>
+#include "ble_hs_priv.h"
+
+#define BLE_IBEACON_MFG_DATA_SIZE       25
+
+int
+ble_ibeacon_set_adv_data(void *uuid128, uint16_t major, uint16_t minor)
+{
+    struct ble_hci_block_params params;
+    struct ble_hci_block_result result;
+    struct ble_hs_adv_fields fields;
+    uint8_t buf[BLE_IBEACON_MFG_DATA_SIZE];
+    int rc;
+
+    /** Company identifier (Apple). */
+    buf[0] = 0x4c;
+    buf[1] = 0x00;
+
+    /** iBeacon indicator. */
+    buf[2] = 0x02;
+    buf[3] = 0x15;
+
+    /** UUID. */
+    memcpy(buf + 4, uuid128, 16);
+
+    /** Version number. */
+    htole16(buf + 20, major);
+    htole16(buf + 22, minor);
+
+    /** Last byte (tx power level) filled in after HCI exchange. */
+
+    memset(&params, 0, sizeof params);
+    params.cmd_opcode = host_hci_opcode_join(BLE_HCI_OGF_LE,
+                                             BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR);
+    params.evt_buf = buf + 24;
+    params.evt_buf_len = 1;
+
+    rc = ble_hci_block_tx(&params, &result);
+    if (rc != 0) {
+        return rc;
+    }
+
+    memset(&fields, 0, sizeof fields);
+    fields.mfg_data = buf;
+    fields.mfg_data_len = sizeof buf;
+
+    rc = ble_gap_adv_set_fields(&fields);
+    return rc;
+}


[2/4] incubator-mynewt-core git commit: MYNEWT-265 BLE - advertise iBeacon

Posted by cc...@apache.org.
MYNEWT-265 BLE - advertise iBeacon

Only include AD tx-pwr field if requested.  The iBeacon advertisement
format requires that undirected advertisements not include the
tx-power-level AD field.  Prior to this change, this field was always
inserted into an undirected advertisement.


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

Branch: refs/heads/develop
Commit: 13747ab33342e7ccf050c1bff24703e1d653240f
Parents: 738c6e7
Author: Christopher Collins <cc...@apache.org>
Authored: Tue Apr 5 20:31:02 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 6 16:50:17 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/src/ble_gap.c              | 39 ++++++++++++++++++-------
 net/nimble/host/src/test/ble_hs_adv_test.c | 22 ++++++++++++++
 2 files changed, 50 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/13747ab3/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 4342103..750c1aa 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -75,10 +75,15 @@
 
 /**
  * The maximum amount of user data that can be put into the advertising data.
- * Six bytes are reserved at the end for the flags field and the transmit power
- * field.
+ * The stack may automatically insert some fields on its own, limiting the
+ * maximum amount of user data.  The following fields are automatically
+ * inserted:
+ *     o Flags (3 bytes)
+ *     o Tx-power-level (3 bytes) - Only if the application specified a
+ *       tx_pwr_llvl_present value of 1 in a call to ble_gap_set_adv_data().
  */
-#define BLE_GAP_ADV_DATA_LIMIT          (BLE_HCI_MAX_ADV_DATA_LEN - 6)
+#define BLE_GAP_ADV_DATA_LIMIT_PWR      (BLE_HCI_MAX_ADV_DATA_LEN - 6)
+#define BLE_GAP_ADV_DATA_LIMIT_NO_PWR   (BLE_HCI_MAX_ADV_DATA_LEN - 3)
 
 static const struct ble_gap_crt_params ble_gap_params_dflt = {
     .scan_itvl = 0x0010,
@@ -154,6 +159,8 @@ static bssnz_t struct {
     uint8_t adv_data_len;
     uint8_t rsp_data_len;
     int8_t tx_pwr_lvl;
+
+    unsigned adv_pwr_lvl:1;
 } ble_gap_slave;
 
 static bssnz_t struct {
@@ -1892,11 +1899,13 @@ ble_gap_adv_data_tx(void *arg)
     }
 
     /* Encode the transmit power AD field. */
-    rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_TX_PWR_LVL, 1,
-                             &ble_gap_slave.tx_pwr_lvl,
-                             ble_gap_slave.adv_data,
-                             &adv_data_len, BLE_HCI_MAX_ADV_DATA_LEN);
-    BLE_HS_DBG_ASSERT(rc == 0);
+    if (ble_gap_slave.adv_pwr_lvl) {
+        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_TX_PWR_LVL, 1,
+                                 &ble_gap_slave.tx_pwr_lvl,
+                                 ble_gap_slave.adv_data,
+                                 &adv_data_len, BLE_HCI_MAX_ADV_DATA_LEN);
+        BLE_HS_DBG_ASSERT(rc == 0);
+    }
 
     ble_hci_sched_set_ack_cb(ble_gap_adv_ack, NULL);
     rc = host_hci_cmd_le_set_adv_data(ble_gap_slave.adv_data,
@@ -2156,14 +2165,22 @@ ble_gap_adv_set_fields(struct ble_hs_adv_fields *adv_fields)
     return BLE_HS_ENOTSUP;
 #endif
 
+    int max_sz;
     int rc;
 
     STATS_INC(ble_gap_stats, adv_set_fields);
 
+    if (adv_fields->tx_pwr_lvl_is_present) {
+        max_sz = BLE_GAP_ADV_DATA_LIMIT_PWR;
+    } else {
+        max_sz = BLE_GAP_ADV_DATA_LIMIT_NO_PWR;
+    }
+
     rc = ble_hs_adv_set_fields(adv_fields, ble_gap_slave.adv_data,
-                               &ble_gap_slave.adv_data_len,
-                               BLE_GAP_ADV_DATA_LIMIT);
-    if (rc != 0) {
+                               &ble_gap_slave.adv_data_len, max_sz);
+    if (rc == 0) {
+        ble_gap_slave.adv_pwr_lvl = adv_fields->tx_pwr_lvl_is_present;
+    } else {
         STATS_INC(ble_gap_stats, adv_set_fields_fail);
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/13747ab3/net/nimble/host/src/test/ble_hs_adv_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_hs_adv_test.c b/net/nimble/host/src/test/ble_hs_adv_test.c
index 477afd6..b465fdf 100644
--- a/net/nimble/host/src/test/ble_hs_adv_test.c
+++ b/net/nimble/host/src/test/ble_hs_adv_test.c
@@ -176,6 +176,7 @@ TEST_CASE(ble_hs_adv_test_case_flags)
     memset(&rsp_fields, 0, sizeof rsp_fields);
 
     /* Default flags. */
+    adv_fields.tx_pwr_lvl_is_present = 1;
     ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON,
         &adv_fields,
         (struct ble_hs_adv_test_field[]) {
@@ -236,6 +237,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** Complete 16-bit service class UUIDs. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.uuids16 = (uint16_t[]) { 0x0001, 0x1234, 0x54ab };
     adv_fields.num_uuids16 = 3;
     adv_fields.uuids16_is_complete = 1;
@@ -262,6 +264,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** Incomplete 16-bit service class UUIDs. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.uuids16 = (uint16_t[]) { 0x0001, 0x1234, 0x54ab };
     adv_fields.num_uuids16 = 3;
     adv_fields.uuids16_is_complete = 0;
@@ -288,6 +291,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** Complete 32-bit service class UUIDs. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.uuids32 = (uint32_t[]) { 0x12345678, 0xabacadae };
     adv_fields.num_uuids32 = 2;
     adv_fields.uuids32_is_complete = 1;
@@ -314,6 +318,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** Incomplete 32-bit service class UUIDs. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.uuids32 = (uint32_t[]) { 0x12345678, 0xabacadae };
     adv_fields.num_uuids32 = 2;
     adv_fields.uuids32_is_complete = 0;
@@ -340,6 +345,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** Complete 128-bit service class UUIDs. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.uuids128 = (uint8_t[]) {
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -372,6 +378,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** Incomplete 128-bit service class UUIDs. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.uuids128 = (uint8_t[]) {
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -404,6 +411,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** Complete name. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.name = (uint8_t *)"myname";
     adv_fields.name_len = 6;
     adv_fields.name_is_complete = 1;
@@ -430,6 +438,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** Incomplete name. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.name = (uint8_t *)"myname";
     adv_fields.name_len = 6;
     adv_fields.name_is_complete = 0;
@@ -456,6 +465,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** Class of device. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.device_class = (uint8_t[]){ 1,2,3 };
 
     ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
@@ -480,6 +490,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** Slave interval range. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.slave_itvl_range = (uint8_t[]){ 1,2,3,4 };
 
     ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
@@ -504,6 +515,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** 0x16 - Service data - 16-bit UUID. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.svc_data_uuid16 = (uint8_t[]){ 1,2,3,4 };
     adv_fields.svc_data_uuid16_len = 4;
 
@@ -529,6 +541,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** 0x17 - Public target address. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.public_tgt_addr = (uint8_t[]){ 1,2,3,4,5,6, 6,5,4,3,2,1 };
     adv_fields.num_public_tgt_addrs = 2;
 
@@ -554,6 +567,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** 0x19 - Appearance. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.appearance = 0x1234;
     adv_fields.appearance_is_present = 1;
 
@@ -579,6 +593,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** 0x1a - Advertising interval. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.adv_itvl = 0x1234;
     adv_fields.adv_itvl_is_present = 1;
 
@@ -604,6 +619,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** 0x1b - LE bluetooth device address. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.le_addr = (uint8_t[]){ 1,2,3,4,5,6,7 };
 
     ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
@@ -628,6 +644,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** 0x1c - LE role. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.le_role = BLE_HS_ADV_LE_ROLE_BOTH_PERIPH_PREF;
     adv_fields.le_role_is_present = 1;
 
@@ -653,6 +670,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** 0x20 - Service data - 32-bit UUID. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.svc_data_uuid32 = (uint8_t[]){ 1,2,3,4,5 };
     adv_fields.svc_data_uuid32_len = 5;
 
@@ -678,6 +696,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** 0x21 - Service data - 128-bit UUID. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.svc_data_uuid128 =
         (uint8_t[]){ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 };
     adv_fields.svc_data_uuid128_len = 18;
@@ -705,6 +724,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** 0x24 - URI. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.uri = (uint8_t[]){ 1,2,3,4 };
     adv_fields.uri_len = 4;
 
@@ -730,6 +750,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
 
     /*** 0xff - Manufacturer specific data. */
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
     adv_fields.mfg_data = (uint8_t[]){ 1,2,3,4 };
     adv_fields.mfg_data_len = 4;
 
@@ -760,6 +781,7 @@ TEST_CASE(ble_hs_adv_test_case_user_rsp)
     struct ble_hs_adv_fields adv_fields;
 
     memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
 
     /*** Complete 16-bit service class UUIDs. */
     memset(&rsp_fields, 0, sizeof rsp_fields);


[3/4] incubator-mynewt-core git commit: MYNEWT-265 BLE - advertise iBeacon

Posted by cc...@apache.org.
MYNEWT-265 BLE - advertise iBeacon

Blocking HCI transmits.


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

Branch: refs/heads/develop
Commit: 8fc5098e8812da06e3e9b89eb75848ea8cb79cd5
Parents: 338fe0f
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Apr 6 16:49:17 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Apr 6 16:50:31 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/include/host/host_hci.h |   1 +
 net/nimble/host/src/ble_hci_block.c     | 159 +++++++++++++++++++++++++++
 net/nimble/host/src/ble_hs.c            |   4 +-
 net/nimble/host/src/ble_hs_priv.h       |  20 ++++
 net/nimble/host/src/host_hci.c          |   6 +
 5 files changed, 189 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8fc5098e/net/nimble/host/include/host/host_hci.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/host_hci.h b/net/nimble/host/include/host/host_hci.h
index 1a5876d..0991e72 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -26,6 +26,7 @@ struct os_mbuf;
 
 int host_hci_os_event_proc(struct os_event *ev);
 int host_hci_event_rx(uint8_t *data);
+uint16_t host_hci_opcode_join(uint8_t ogf, uint16_t ocf);
 int host_hci_cmd_send(uint8_t ogf, uint8_t ocf, uint8_t len, void *cmddata);
 int host_hci_cmd_set_event_mask(uint64_t event_mask);
 int host_hci_cmd_disconnect(uint16_t handle, uint8_t reason);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8fc5098e/net/nimble/host/src/ble_hci_block.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_block.c b/net/nimble/host/src/ble_hci_block.c
new file mode 100644
index 0000000..f4d0d86
--- /dev/null
+++ b/net/nimble/host/src/ble_hci_block.c
@@ -0,0 +1,159 @@
+/**
+ * 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.
+ */
+
+/**
+ * Provides a blocking HCI send interface.  These functions must not be called
+ * from the ble_hs task.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "os/os.h"
+#include "ble_hs_priv.h"
+
+#define BLE_HCI_BLOCK_TIMEOUT       (OS_TICKS_PER_SEC)
+
+/** Protects resources from 2+ application tasks. */
+static struct os_mutex ble_hci_block_mutex;
+
+/** Used to block on expected HCI acknowledgements. */
+static struct os_sem ble_hci_block_sem;
+
+/** Global state corresponding to the current blocking operation. */
+static struct ble_hci_block_params *ble_hci_block_params;
+static struct ble_hci_block_result *ble_hci_block_result;
+static uint8_t ble_hci_block_handle;
+static int ble_hci_block_status;
+
+/**
+ * Copies the parameters from an acknowledgement into the application event
+ * buffer.
+ */
+static void
+ble_hci_block_copy_evt_data(void *src_data, uint8_t src_data_len)
+{
+    if (ble_hci_block_params->evt_buf_len > src_data_len) {
+        ble_hci_block_result->evt_buf_len = ble_hci_block_params->evt_buf_len;
+    } else {
+        ble_hci_block_result->evt_buf_len = src_data_len;
+    }
+    ble_hci_block_result->evt_total_len = src_data_len;
+
+    if (ble_hci_block_result->evt_buf_len > 0) {
+        memcpy(ble_hci_block_params->evt_buf, src_data,
+               ble_hci_block_result->evt_buf_len);
+    }
+}
+
+/**
+ * Callback that gets executed upon receiving an HCI acknowledgement.
+ */
+static void
+ble_hci_block_ack_cb(struct ble_hci_ack *ack, void *arg)
+{
+    BLE_HS_DBG_ASSERT(ack->bha_hci_handle == ble_hci_block_handle);
+
+    /* +1/-1 to ignore the status byte. */
+    ble_hci_block_copy_evt_data(ack->bha_params + 1, ack->bha_params_len - 1);
+    ble_hci_block_status = ack->bha_status;
+
+    /* Wake the application task up now that the acknowledgement has been
+     * received.
+     */
+    os_sem_release(&ble_hci_block_sem);
+}
+
+/**
+ * Callback that gets executed when an HCI tx reservation is services.
+ * Transmits the HCI command specifed by the client task.
+ */
+static int
+ble_hci_block_tx_cb(void *arg)
+{
+    uint16_t ocf;
+    uint8_t ogf;
+    int rc;
+
+    ble_hci_sched_set_ack_cb(ble_hci_block_ack_cb, NULL);
+
+    ogf = BLE_HCI_OGF(ble_hci_block_params->cmd_opcode);
+    ocf = BLE_HCI_OCF(ble_hci_block_params->cmd_opcode);
+    rc = host_hci_cmd_send(ogf, ocf, ble_hci_block_params->cmd_len,
+                           ble_hci_block_params->cmd_data);
+    if (rc != 0) {
+        os_sem_release(&ble_hci_block_sem);
+        return rc;
+    }
+
+    return 0;
+}
+
+/**
+ * Performs a blocking HCI send.  Must not be called from the ble_hs task.
+ */
+int
+ble_hci_block_tx(struct ble_hci_block_params *params,
+                 struct ble_hci_block_result *result)
+{
+    int rc;
+
+    BLE_HS_DBG_ASSERT(os_sched_get_current_task() != &ble_hs_task);
+
+    os_mutex_pend(&ble_hci_block_mutex, OS_WAIT_FOREVER);
+
+    memset(result, 0, sizeof *result);
+
+    ble_hci_block_params = params;
+    ble_hci_block_result = result;
+
+    rc = ble_hci_sched_enqueue(ble_hci_block_tx_cb, NULL,
+                               &ble_hci_block_handle);
+    if (rc == 0) {
+        rc = os_sem_pend(&ble_hci_block_sem, BLE_HCI_BLOCK_TIMEOUT);
+        switch (rc) {
+        case 0:
+            rc = ble_hci_block_status;
+            break;
+
+        case OS_TIMEOUT:
+            rc = BLE_HS_ETIMEOUT;
+            break;
+
+        default:
+            BLE_HS_DBG_ASSERT(0);
+            rc = BLE_HS_EOS;
+            break;
+        }
+    }
+
+    os_mutex_release(&ble_hci_block_mutex);
+    return rc;
+}
+
+void
+ble_hci_block_init(void)
+{
+    int rc;
+
+    rc = os_mutex_init(&ble_hci_block_mutex);
+    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
+
+    rc = os_sem_init(&ble_hci_block_sem, 0);
+    BLE_HS_DBG_ASSERT_EVAL(rc == 0);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8fc5098e/net/nimble/host/src/ble_hs.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs.c b/net/nimble/host/src/ble_hs.c
index af30e0e..0a518d1 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -40,7 +40,7 @@ static struct log_handler ble_hs_log_console_handler;
 struct ble_hs_dev ble_hs_our_dev;
 struct log ble_hs_log;
 
-static struct os_task ble_hs_task;
+struct os_task ble_hs_task;
 static os_stack_t ble_hs_stack[BLE_HS_STACK_SIZE] bssnz_t;
 
 #define HCI_CMD_BUF_SIZE    (260)       /* XXX: temporary, Fix later */
@@ -371,6 +371,8 @@ ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg)
         goto err;
     }
 
+    ble_hci_block_init();
+
     ble_hs_kick_hci_ev.ev_queued = 0;
     ble_hs_kick_hci_ev.ev_type = BLE_HS_KICK_HCI_EVENT;
     ble_hs_kick_hci_ev.ev_arg = NULL;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8fc5098e/net/nimble/host/src/ble_hs_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_priv.h b/net/nimble/host/src/ble_hs_priv.h
index 68cfdaf..b76af74 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -67,6 +67,8 @@ struct ble_hs_dev {
     unsigned has_random_addr:1;
 };
 
+extern struct os_task ble_hs_task;
+
 extern struct ble_hs_dev ble_hs_our_dev;
 extern struct ble_hs_cfg ble_hs_cfg;
 
@@ -102,6 +104,24 @@ struct os_mbuf *ble_hs_misc_pkthdr(void);
 
 int ble_hs_misc_pullup_base(struct os_mbuf **om, int base_len);
 
+struct ble_hci_block_params {
+    uint16_t cmd_opcode;
+    uint8_t cmd_len;
+    void *cmd_data;
+
+    void *evt_buf;
+    uint8_t evt_buf_len;
+};
+
+struct ble_hci_block_result {
+    uint8_t evt_buf_len;
+    uint8_t evt_total_len;
+};
+
+int ble_hci_block_tx(struct ble_hci_block_params *params,
+                     struct ble_hci_block_result *result);
+void ble_hci_block_init(void);
+
 #define BLE_HS_LOG(lvl, ...) \
     LOG_ ## lvl(&ble_hs_log, LOG_MODULE_NIMBLE_HOST, __VA_ARGS__)
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/8fc5098e/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 a329684..a52d8b6 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -747,6 +747,12 @@ host_hci_data_rx(struct os_mbuf *om)
 }
 
 uint16_t
+host_hci_opcode_join(uint8_t ogf, uint16_t ocf)
+{
+    return (ogf << 10) | ocf;
+}
+
+uint16_t
 host_hci_handle_pb_bc_join(uint16_t handle, uint8_t pb, uint8_t bc)
 {
     BLE_HS_DBG_ASSERT(handle <= 0x0fff);