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/01/24 06:43:24 UTC

[1/2] incubator-mynewt-larva git commit: Support for more advertisement data fields.

Repository: incubator-mynewt-larva
Updated Branches:
  refs/heads/master 044d34ad3 -> 2ffa2158b


Support for more advertisement data fields.


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

Branch: refs/heads/master
Commit: 14ef31cefec1d66dcba37e3aa83960e2a5a67eed
Parents: 044d34a
Author: Christopher Collins <cc...@gmail.com>
Authored: Sat Jan 23 20:48:04 2016 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Sat Jan 23 20:48:04 2016 -0800

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_hs.h      |  39 ---
 net/nimble/host/include/host/ble_hs_adv.h  | 171 ++++++++++++++
 net/nimble/host/src/ble_gap_conn.c         |   4 +-
 net/nimble/host/src/ble_hs_adv.c           | 275 ++++++++++++++++++++-
 net/nimble/host/src/ble_hs_adv.h           |  82 -------
 net/nimble/host/src/ble_hs_adv_priv.h      |  32 +++
 net/nimble/host/src/host_hci.c             |   2 +-
 net/nimble/host/src/test/ble_gap_test.c    |   2 +-
 net/nimble/host/src/test/ble_hs_adv_test.c | 302 ++++++++++++++++++++++--
 9 files changed, 768 insertions(+), 141 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/14ef31ce/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 2288607..4e43f4c 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -57,45 +57,6 @@ struct ble_hs_cfg {
 };
 extern struct ble_hs_cfg ble_hs_cfg;
 
-
-#define BLE_HS_ADV_LE_ROLE_PERIPH               0x00
-#define BLE_HS_ADV_LE_ROLE_CENTRAL              0x01
-#define BLE_HS_ADV_LE_ROLE_BOTH_PERIPH_PREF     0x02
-#define BLE_HS_ADV_LE_ROLE_BOTH_CENTRAL_PREF    0x03
-
-struct ble_hs_adv_fields {
-    /*** 0x01 - Flags. */
-    uint8_t flags;
-
-    /*** 0x02,0x03 - 16-bit service class UUIDs. */
-    uint16_t *uuids16;
-    uint8_t num_uuids16;
-    unsigned uuids16_is_complete:1;
-
-    /*** 0x04,0x05 - 32-bit service class UUIDs. */
-    uint32_t *uuids32;
-    uint8_t num_uuids32;
-    unsigned uuids32_is_complete:1;
-
-    /*** 0x06,0x07 - 128-bit service class UUIDs. */
-    void *uuids128;
-    uint8_t num_uuids128;
-    unsigned uuids128_is_complete:1;
-
-    /*** 0x08,0x09 - Local name. */
-    uint8_t *name;
-    uint8_t name_len;
-    unsigned name_is_complete:1;
-
-    /*** 0x0a - Tx power level. */
-    uint8_t tx_pwr_lvl;
-    unsigned tx_pwr_lvl_is_present:1;
-
-    /*** 0x1c - LE role. */
-    uint8_t le_role;
-    unsigned le_role_is_present:1;
-};
-
 int ble_hs_init(uint8_t prio);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/14ef31ce/net/nimble/host/include/host/ble_hs_adv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs_adv.h b/net/nimble/host/include/host/ble_hs_adv.h
new file mode 100644
index 0000000..c425269
--- /dev/null
+++ b/net/nimble/host/include/host/ble_hs_adv.h
@@ -0,0 +1,171 @@
+/**
+ * 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_HS_ADV_
+#define H_BLE_HS_ADV_
+
+#include <inttypes.h>
+
+struct ble_hs_adv_fields {
+    /*** 0x01 - Flags. */
+    uint8_t flags;
+    unsigned flags_is_present:1;
+
+    /*** 0x02,0x03 - 16-bit service class UUIDs. */
+    void *uuids16;
+    uint8_t num_uuids16;
+    unsigned uuids16_is_complete:1;
+
+    /*** 0x04,0x05 - 32-bit service class UUIDs. */
+    void *uuids32;
+    uint8_t num_uuids32;
+    unsigned uuids32_is_complete:1;
+
+    /*** 0x06,0x07 - 128-bit service class UUIDs. */
+    void *uuids128;
+    uint8_t num_uuids128;
+    unsigned uuids128_is_complete:1;
+
+    /*** 0x08,0x09 - Local name. */
+    uint8_t *name;
+    uint8_t name_len;
+    unsigned name_is_complete:1;
+
+    /*** 0x0a - Tx power level. */
+    uint8_t tx_pwr_lvl;
+    unsigned tx_pwr_lvl_is_present:1;
+
+    /*** 0x0d - Class of device. */
+    uint8_t *device_class;
+
+    /*** 0x0d - Slave connection interval range. */
+    uint8_t *slave_itvl_range;
+
+    /*** 0x16 - Service data - 16-bit UUID. */
+    uint8_t *svc_data_uuid16;
+    uint8_t svc_data_uuid16_len;
+
+    /*** 0x17 - Public target address. */
+    uint8_t *public_tgt_addr;
+    uint8_t num_public_tgt_addrs;
+
+    /*** 0x19 - Appearance. */
+    uint16_t appearance;
+    unsigned appearance_is_present:1;
+
+    /*** 0x1a - Advertising interval. */
+    uint16_t adv_itvl;
+    unsigned adv_itvl_is_present:1;
+
+    /*** 0x1b - LE bluetooth device address. */
+    uint8_t *le_addr;
+
+    /*** 0x1c - LE role. */
+    uint8_t le_role;
+    unsigned le_role_is_present:1;
+
+    /*** 0x20 - Service data - 32-bit UUID. */
+    uint8_t *svc_data_uuid32;
+    uint8_t svc_data_uuid32_len;
+
+    /*** 0x21 - Service data - 128-bit UUID. */
+    uint8_t *svc_data_uuid128;
+    uint8_t svc_data_uuid128_len;
+
+    /*** 0x24 - URI. */
+    uint8_t *uri;
+    uint8_t uri_len;
+
+    /*** 0xff - Manufacturer specific data. */
+    uint8_t *mfg_data;
+    uint8_t mfg_data_len;
+};
+
+#define BLE_HS_ADV_TYPE_FLAGS                   0x01
+#define BLE_HS_ADV_TYPE_INCOMP_UUIDS16          0x02
+#define BLE_HS_ADV_TYPE_COMP_UUIDS16            0x03
+#define BLE_HS_ADV_TYPE_INCOMP_UUIDS32          0x04
+#define BLE_HS_ADV_TYPE_COMP_UUIDS32            0x05
+#define BLE_HS_ADV_TYPE_INCOMP_UUIDS128         0x06
+#define BLE_HS_ADV_TYPE_COMP_UUIDS128           0x07
+#define BLE_HS_ADV_TYPE_INCOMP_NAME             0x08
+#define BLE_HS_ADV_TYPE_COMP_NAME               0x09
+#define BLE_HS_ADV_TYPE_TX_PWR_LVL              0x0a
+#define BLE_HS_ADV_TYPE_DEVICE_CLASS            0x0d
+#define BLE_HS_ADV_TYPE_SIMPLE_PAIR_HASH192     0x0e
+#define BLE_HS_ADV_TYPE_SIMPLE_PAIR_RAND192     0x0f
+#define BLE_HS_ADV_TYPE_SM_TK_VALUE             0x10
+#define BLE_HS_ADV_TYPE_SM_OOB_FLAGS            0x11
+#define BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE        0x12
+#define BLE_HS_ADV_TYPE_SOL_UUIDS16             0x14
+#define BLE_HS_ADV_TYPE_SOL_UUIDS128            0x15
+#define BLE_HS_ADV_TYPE_SVC_DATA_UUID16         0x16
+#define BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR         0x17
+#define BLE_HS_ADV_TYPE_RANDOM_TGT_ADDR         0x18
+#define BLE_HS_ADV_TYPE_APPEARANCE              0x19
+#define BLE_HS_ADV_TYPE_ADV_ITVL                0x1a
+#define BLE_HS_ADV_TYPE_LE_ADDR                 0x1b
+#define BLE_HS_ADV_TYPE_LE_ROLE                 0x1c
+#define BLE_HS_ADV_TYPE_SIMPLE_PAIR_HASH256     0x1d
+#define BLE_HS_ADV_TYPE_SIMPLE_PAIR_RAND256     0x1e
+#define BLE_HS_ADV_TYPE_SVC_DATA_UUID32         0x20
+#define BLE_HS_ADV_TYPE_SVC_DATA_UUID128        0x21
+#define BLE_HS_ADV_TYPE_LE_SECURE_CONFIRM       0x22
+#define BLE_HS_ADV_TYPE_LE_SECURE_RANDOM        0x23
+#define BLE_HS_ADV_TYPE_URI                     0x24
+#define BLE_HS_ADV_TYPE_INDOOR_POS              0x25
+#define BLE_HS_ADV_TYPE_TRANS_DISC_DATA         0x26
+#define BLE_HS_ADV_TYPE_3D_INFO_DATA            0x3d
+#define BLE_HS_ADV_TYPE_MFG_DATA                0xff
+
+#define BLE_HS_ADV_FLAGS_LEN                    1
+#define BLE_HS_ADV_F_DISC_LTD                   0x01
+#define BLE_HS_ADV_F_DISC_GEN                   0x02
+#define BLE_HS_ADV_F_BREDR_UNSUP                0x04
+
+#define BLE_HS_ADV_TX_PWR_LVL_LEN               1
+
+#define BLE_HS_ADV_DEVICE_CLASS_LEN             3
+
+#define BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN         4
+
+#define BLE_HS_ADV_SVC_DATA_UUID16_MIN_LEN      2
+
+#define BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN    6
+
+#define BLE_HS_ADV_APPEARANCE_LEN               2
+
+#define BLE_HS_ADV_ADV_ITVL_LEN                 2
+
+#define BLE_HS_ADV_LE_ADDR_LEN                  7
+
+#define BLE_HS_ADV_LE_ROLE_LEN                  1
+#define BLE_HS_ADV_LE_ROLE_PERIPH               0x00
+#define BLE_HS_ADV_LE_ROLE_CENTRAL              0x01
+#define BLE_HS_ADV_LE_ROLE_BOTH_PERIPH_PREF     0x02
+#define BLE_HS_ADV_LE_ROLE_BOTH_CENTRAL_PREF    0x03
+
+#define BLE_HS_ADV_SVC_DATA_UUID32_MIN_LEN      4
+
+#define BLE_HS_ADV_SVC_DATA_UUID128_MIN_LEN     16
+
+int ble_hs_adv_set_flat(uint8_t type, int data_len, void *data,
+                        uint8_t *dst, uint8_t *dst_len, uint8_t max_len);
+int ble_hs_adv_set_fields(struct ble_hs_adv_fields *adv_fields,
+                          uint8_t *dst, uint8_t *dst_len, uint8_t max_len);
+int ble_hs_adv_parse_fields(struct ble_hs_adv_fields *adv_fields, uint8_t *src,
+                            uint8_t src_len);
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/14ef31ce/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 0871aab..ca3982a 100644
--- a/net/nimble/host/src/ble_gap_conn.c
+++ b/net/nimble/host/src/ble_gap_conn.c
@@ -21,9 +21,9 @@
 #include "os/os.h"
 #include "ble_hs_priv.h"
 #include "host/host_hci.h"
+#include "ble_hs_adv_priv.h"
 #include "ble_hci_ack.h"
 #include "ble_hs_conn.h"
-#include "ble_hs_adv.h"
 #include "ble_hci_ack.h"
 #include "ble_hci_sched.h"
 #include "ble_gatt_priv.h"
@@ -1227,7 +1227,7 @@ ble_gap_conn_adv_data_tx(void *arg)
     }
 
     /* Encode the transmit power AD field. */
-    rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_TX_PWR_LEVEL, 1,
+    rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_TX_PWR_LVL, 1,
                              &ble_gap_conn_slave.tx_pwr_lvl,
                              ble_gap_conn_slave.adv_data,
                              &adv_data_len, BLE_HCI_MAX_ADV_DATA_LEN);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/14ef31ce/net/nimble/host/src/ble_hs_adv.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_adv.c b/net/nimble/host/src/ble_hs_adv.c
index c33c688..a21c10a 100644
--- a/net/nimble/host/src/ble_hs_adv.c
+++ b/net/nimble/host/src/ble_hs_adv.c
@@ -18,7 +18,7 @@
 #include <string.h>
 #include <errno.h>
 #include "nimble/ble.h"
-#include "ble_hs_adv.h"
+#include "ble_hs_adv_priv.h"
 #include "ble_hs_priv.h"
 
 static int
@@ -43,6 +43,8 @@ ble_hs_adv_set_flat(uint8_t type, int data_len, void *data,
 {
     int rc;
 
+    assert(data_len > 0);
+
     rc = ble_hs_adv_set_hdr(type, data_len, max_len, dst, dst_len);
     if (rc != 0) {
         return rc;
@@ -176,15 +178,136 @@ ble_hs_adv_set_fields(struct ble_hs_adv_fields *adv_fields,
 
     /*** 0x0a - Tx power level (written automatically by GAP). */
 
+    /*** 0x0d - Class of device. */
+    if (adv_fields->device_class != NULL) {
+        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_DEVICE_CLASS,
+                                 BLE_HS_ADV_DEVICE_CLASS_LEN,
+                                 adv_fields->device_class, dst, dst_len,
+                                 max_len);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
+    /*** 0x12 - Slave connection interval range. */
+    if (adv_fields->slave_itvl_range != NULL) {
+        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE,
+                                 BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN,
+                                 adv_fields->slave_itvl_range, dst, dst_len,
+                                 max_len);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
+    /*** 0x16 - Service data - 16-bit UUID. */
+    if (adv_fields->svc_data_uuid16 != NULL) {
+        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_SVC_DATA_UUID16,
+                                 adv_fields->svc_data_uuid16_len,
+                                 adv_fields->svc_data_uuid16, dst, dst_len,
+                                 max_len);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
+    /*** 0x17 - Public target address. */
+    if (adv_fields->public_tgt_addr != NULL &&
+        adv_fields->num_public_tgt_addrs != 0) {
+
+        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR,
+                                 BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN *
+                                     adv_fields->num_public_tgt_addrs,
+                                 adv_fields->public_tgt_addr, dst, dst_len,
+                                 max_len);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
+    /*** 0x19 - Appearance. */
+    if (adv_fields->appearance_is_present) {
+        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_APPEARANCE,
+                                 BLE_HS_ADV_APPEARANCE_LEN,
+                                 &adv_fields->appearance, dst, dst_len,
+                                 max_len);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
+    /*** 0x1a - Advertising interval. */
+    if (adv_fields->adv_itvl_is_present) {
+        rc = ble_hs_adv_set_array16(BLE_HS_ADV_TYPE_ADV_ITVL, 1,
+                                    &adv_fields->adv_itvl, dst, dst_len,
+                                    max_len);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
+    /*** 0x1b - LE bluetooth device address. */
+    if (adv_fields->le_addr != NULL) {
+        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_LE_ADDR,
+                                 BLE_HS_ADV_LE_ADDR_LEN,
+                                 adv_fields->le_addr, dst, dst_len,
+                                 max_len);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
     /*** 0x1c - LE role. */
     if (adv_fields->le_role_is_present) {
-        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_LE_ROLE, 1,
+        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_LE_ROLE,
+                                 BLE_HS_ADV_LE_ROLE_LEN,
                                  &adv_fields->le_role, dst, dst_len, max_len);
         if (rc != 0) {
             return rc;
         }
     }
 
+    /*** 0x20 - Service data - 32-bit UUID. */
+    if (adv_fields->svc_data_uuid32 != NULL) {
+        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_SVC_DATA_UUID32,
+                                 adv_fields->svc_data_uuid32_len,
+                                 adv_fields->svc_data_uuid32, dst, dst_len,
+                                 max_len);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
+    /*** 0x21 - Service data - 128-bit UUID. */
+    if (adv_fields->svc_data_uuid128 != NULL) {
+        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_SVC_DATA_UUID128,
+                                 adv_fields->svc_data_uuid128_len,
+                                 adv_fields->svc_data_uuid128, dst, dst_len,
+                                 max_len);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
+    /*** 0x24 - URI. */
+    if (adv_fields->uri != NULL) {
+        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_URI, adv_fields->uri_len,
+                                 adv_fields->uri, dst, dst_len, max_len);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
+    /*** 0xff - Manufacturer specific data. */
+    if (adv_fields->mfg_data != NULL) {
+        rc = ble_hs_adv_set_flat(BLE_HS_ADV_TYPE_MFG_DATA,
+                                 adv_fields->mfg_data_len,
+                                 adv_fields->mfg_data, dst, dst_len, max_len);
+        if (rc != 0) {
+            return rc;
+        }
+    }
+
     return 0;
 }
 
@@ -215,6 +338,61 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields,
             return BLE_HS_EBADDATA;
         }
         adv_fields->flags = *data;
+        adv_fields->flags_is_present = 1;
+        break;
+
+    case BLE_HS_ADV_TYPE_INCOMP_UUIDS16:
+        if (data_len % 2 != 0) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->uuids16 = data;
+        adv_fields->num_uuids16 = data_len / 2;
+        adv_fields->uuids16_is_complete = 0;
+        break;
+
+    case BLE_HS_ADV_TYPE_COMP_UUIDS16:
+        if (data_len % 2 != 0) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->uuids16 = data;
+        adv_fields->num_uuids16 = data_len / 2;
+        adv_fields->uuids16_is_complete = 1;
+        break;
+
+    case BLE_HS_ADV_TYPE_INCOMP_UUIDS32:
+        if (data_len % 4 != 0) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->uuids32 = data;
+        adv_fields->num_uuids32 = data_len / 4;
+        adv_fields->uuids32_is_complete = 0;
+        break;
+
+    case BLE_HS_ADV_TYPE_COMP_UUIDS32:
+        if (data_len % 4 != 0) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->uuids32 = data;
+        adv_fields->num_uuids32 = data_len / 4;
+        adv_fields->uuids32_is_complete = 1;
+        break;
+
+    case BLE_HS_ADV_TYPE_INCOMP_UUIDS128:
+        if (data_len % 16 != 0) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->uuids128 = data;
+        adv_fields->num_uuids128 = data_len / 16;
+        adv_fields->uuids128_is_complete = 0;
+        break;
+
+    case BLE_HS_ADV_TYPE_COMP_UUIDS128:
+        if (data_len % 16 != 0) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->uuids128 = data;
+        adv_fields->num_uuids128 = data_len / 16;
+        adv_fields->uuids128_is_complete = 1;
         break;
 
     case BLE_HS_ADV_TYPE_INCOMP_NAME:
@@ -229,6 +407,99 @@ ble_hs_adv_parse_one_field(struct ble_hs_adv_fields *adv_fields,
         adv_fields->name_is_complete = 1;
         break;
 
+    case BLE_HS_ADV_TYPE_TX_PWR_LVL:
+        if (data_len != BLE_HS_ADV_TX_PWR_LVL_LEN) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->tx_pwr_lvl = *data;
+        adv_fields->tx_pwr_lvl_is_present = 1;
+        break;
+
+    case BLE_HS_ADV_TYPE_DEVICE_CLASS:
+        if (data_len != BLE_HS_ADV_DEVICE_CLASS_LEN) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->device_class = data;
+        break;
+
+    case BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE:
+        if (data_len != BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->slave_itvl_range = data;
+        break;
+
+    case BLE_HS_ADV_TYPE_SVC_DATA_UUID16:
+        if (data_len < BLE_HS_ADV_SVC_DATA_UUID16_MIN_LEN) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->svc_data_uuid16 = data;
+        break;
+
+    case BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR:
+        if (data_len % BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN != 0) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->public_tgt_addr = data;
+        adv_fields->num_public_tgt_addrs =
+            data_len / BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN;
+        break;
+
+    case BLE_HS_ADV_TYPE_APPEARANCE:
+        if (data_len != BLE_HS_ADV_APPEARANCE_LEN) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->appearance = le16toh(data);
+        adv_fields->appearance_is_present = 1;
+        break;
+
+    case BLE_HS_ADV_TYPE_ADV_ITVL:
+        if (data_len != BLE_HS_ADV_ADV_ITVL_LEN) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->adv_itvl = le16toh(data);
+        adv_fields->adv_itvl_is_present = 1;
+        break;
+
+    case BLE_HS_ADV_TYPE_LE_ADDR:
+        if (data_len != BLE_HS_ADV_LE_ADDR_LEN) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->le_addr = data;
+        break;
+
+    case BLE_HS_ADV_TYPE_LE_ROLE:
+        if (data_len != BLE_HS_ADV_LE_ROLE_LEN) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->le_role = *data;
+        adv_fields->le_role_is_present = 1;
+        break;
+
+    case BLE_HS_ADV_TYPE_SVC_DATA_UUID32:
+        if (data_len < BLE_HS_ADV_SVC_DATA_UUID32_MIN_LEN) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->svc_data_uuid32 = data;
+        break;
+
+    case BLE_HS_ADV_TYPE_SVC_DATA_UUID128:
+        if (data_len < BLE_HS_ADV_SVC_DATA_UUID128_MIN_LEN) {
+            return BLE_HS_EBADDATA;
+        }
+        adv_fields->svc_data_uuid128 = data;
+        break;
+
+    case BLE_HS_ADV_TYPE_URI:
+        adv_fields->uri = data;
+        adv_fields->uri_len = data_len;
+        break;
+
+    case BLE_HS_ADV_TYPE_MFG_DATA:
+        adv_fields->mfg_data = data;
+        adv_fields->mfg_data_len = data_len;
+        break;
+
     default:
         break;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/14ef31ce/net/nimble/host/src/ble_hs_adv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_adv.h b/net/nimble/host/src/ble_hs_adv.h
deleted file mode 100644
index 36fefcd..0000000
--- a/net/nimble/host/src/ble_hs_adv.h
+++ /dev/null
@@ -1,82 +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_HS_ADV_
-#define H_BLE_HS_ADV_
-
-#include <inttypes.h>
-struct ble_hs_adv_fields;
-
-struct ble_hs_adv {
-    uint8_t event_type;
-    uint8_t addr_type;
-    uint8_t length_data;
-    int8_t rssi;
-    uint8_t addr[6];
-    uint8_t *data;
-    struct ble_hs_adv_fields *fields;
-};
-
-#define BLE_HS_ADV_TYPE_FLAGS                   0x01
-#define BLE_HS_ADV_TYPE_INCOMP_UUIDS16          0x02
-#define BLE_HS_ADV_TYPE_COMP_UUIDS16            0x03
-#define BLE_HS_ADV_TYPE_INCOMP_UUIDS32          0x04
-#define BLE_HS_ADV_TYPE_COMP_UUIDS32            0x05
-#define BLE_HS_ADV_TYPE_INCOMP_UUIDS128         0x06
-#define BLE_HS_ADV_TYPE_COMP_UUIDS128           0x07
-#define BLE_HS_ADV_TYPE_INCOMP_NAME             0x08
-#define BLE_HS_ADV_TYPE_COMP_NAME               0x09
-#define BLE_HS_ADV_TYPE_TX_PWR_LEVEL            0x0a
-#define BLE_HS_ADV_TYPE_DEVICE_CLASS            0x0d
-#define BLE_HS_ADV_TYPE_SIMPLE_PAIR_HASH192     0x0e
-#define BLE_HS_ADV_TYPE_SIMPLE_PAIR_RAND192     0x0f
-#define BLE_HS_ADV_TYPE_SM_TK_VALUE             0x10
-#define BLE_HS_ADV_TYPE_SM_OOB_FLAGS            0x11
-#define BLE_HS_ADV_TYPE_SLAVE_CONN_ITVL_RANGE   0x12
-#define BLE_HS_ADV_TYPE_SOL_UUIDS16             0x14
-#define BLE_HS_ADV_TYPE_SOL_UUIDS128            0x15
-#define BLE_HS_ADV_TYPE_SVC_DATA_UUID16         0x16
-#define BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDRESS      0x17
-#define BLE_HS_ADV_TYPE_RANDOM_TGT_ADDRESS      0x18
-#define BLE_HS_ADV_TYPE_APPEARANCE              0x19
-#define BLE_HS_ADV_TYPE_ADV_ITVL                0x1a
-#define BLE_HS_ADV_TYPE_LE_ADDRESS              0x1b
-#define BLE_HS_ADV_TYPE_LE_ROLE                 0x1c
-#define BLE_HS_ADV_TYPE_SIMPLE_PAIR_HASH256     0x1d
-#define BLE_HS_ADV_TYPE_SIMPLE_PAIR_RAND256     0x1e
-#define BLE_HS_ADV_TYPE_SVC_DATA_UUID32         0x20
-#define BLE_HS_ADV_TYPE_SVC_DATA_UUID128        0x21
-#define BLE_HS_ADV_TYPE_LE_SECURE_CONFIRM       0x22
-#define BLE_HS_ADV_TYPE_LE_SECURE_RANDOM        0x23
-#define BLE_HS_ADV_TYPE_URI                     0x24
-#define BLE_HS_ADV_TYPE_INDOOR_POS              0x25
-#define BLE_HS_ADV_TYPE_TRANS_DISC_DATA         0x26
-#define BLE_HS_ADV_TYPE_3D_INFO_DATA            0x3d
-#define BLE_HS_ADV_TYPE_MFG_DATA                0xff
-
-
-#define BLE_HS_ADV_FLAGS_LEN                    1
-#define BLE_HS_ADV_F_DISC_LTD                   0x01
-#define BLE_HS_ADV_F_DISC_GEN                   0x02
-#define BLE_HS_ADV_F_BREDR_UNSUP                0x04
-
-int ble_hs_adv_set_flat(uint8_t type, int data_len, void *data,
-                        uint8_t *dst, uint8_t *dst_len, uint8_t max_len);
-int ble_hs_adv_set_fields(struct ble_hs_adv_fields *adv_fields,
-                          uint8_t *dst, uint8_t *dst_len, uint8_t max_len);
-int ble_hs_adv_parse_fields(struct ble_hs_adv_fields *adv_fields, uint8_t *src,
-                            uint8_t src_len);
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/14ef31ce/net/nimble/host/src/ble_hs_adv_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_adv_priv.h b/net/nimble/host/src/ble_hs_adv_priv.h
new file mode 100644
index 0000000..9592ad3
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_adv_priv.h
@@ -0,0 +1,32 @@
+/**
+ * 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_HS_ADV_PRIV_
+#define H_BLE_HS_ADV_PRIV_
+
+#include "host/ble_hs_adv.h"
+
+struct ble_hs_adv {
+    uint8_t event_type;
+    uint8_t addr_type;
+    uint8_t length_data;
+    int8_t rssi;
+    uint8_t addr[6];
+    uint8_t *data;
+    struct ble_hs_adv_fields *fields;
+};
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/14ef31ce/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 41384b1..fb19ab6 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -29,7 +29,7 @@
 #include "ble_l2cap.h"
 #include "ble_hci_ack.h"
 #include "ble_gap_priv.h"
-#include "ble_hs_adv.h"
+#include "ble_hs_adv_priv.h"
 
 _Static_assert(sizeof (struct hci_data_hdr) == BLE_HCI_DATA_HDR_SZ,
                "struct hci_data_hdr must be 4 bytes");

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/14ef31ce/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 498cca4..56b08e4 100644
--- a/net/nimble/host/src/test/ble_gap_test.c
+++ b/net/nimble/host/src/test/ble_gap_test.c
@@ -22,7 +22,7 @@
 #include "host/ble_hs_test.h"
 #include "ble_hs_priv.h"
 #include "ble_hs_conn.h"
-#include "ble_hs_adv.h"
+#include "ble_hs_adv_priv.h"
 #include "ble_hci_sched.h"
 #include "ble_gatt_priv.h"
 #include "ble_gap_priv.h"

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/14ef31ce/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 691393d..38705f0 100644
--- a/net/nimble/host/src/test/ble_hs_adv_test.c
+++ b/net/nimble/host/src/test/ble_hs_adv_test.c
@@ -24,7 +24,7 @@
 #include "ble_l2cap.h"
 #include "ble_att_priv.h"
 #include "ble_hs_conn.h"
-#include "ble_hs_adv.h"
+#include "ble_hs_adv_priv.h"
 #include "ble_hci_ack.h"
 #include "ble_hci_sched.h"
 #include "ble_gap_priv.h"
@@ -144,7 +144,7 @@ TEST_CASE(ble_hs_adv_test_case_flags)
                 .val_len = 1,
             },
             {
-                .type = BLE_HS_ADV_TYPE_TX_PWR_LEVEL,
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
                 .val = (uint8_t[]){ 0x00 },
                 .val_len = 1,
             },
@@ -161,7 +161,7 @@ TEST_CASE(ble_hs_adv_test_case_flags)
                  },
                 .val_len = 1,
             }, {
-                .type = BLE_HS_ADV_TYPE_TX_PWR_LEVEL,
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
                 .val = (uint8_t[]){ 0x00 },
                 .val_len = 1,
             },
@@ -178,7 +178,7 @@ TEST_CASE(ble_hs_adv_test_case_flags)
                  },
                 .val_len = 1,
             }, {
-                .type = BLE_HS_ADV_TYPE_TX_PWR_LEVEL,
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
                 .val = (uint8_t[]){ 0x00 },
                 .val_len = 1,
             },
@@ -209,7 +209,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
                 .val_len = 1,
             },
             {
-                .type = BLE_HS_ADV_TYPE_TX_PWR_LEVEL,
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
                 .val = (uint8_t[]){ 0x00 },
                 .val_len = 1,
             },
@@ -235,7 +235,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
                 .val_len = 1,
             },
             {
-                .type = BLE_HS_ADV_TYPE_TX_PWR_LEVEL,
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
                 .val = (uint8_t[]){ 0x00 },
                 .val_len = 1,
             },
@@ -261,7 +261,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
                 .val_len = 1,
             },
             {
-                .type = BLE_HS_ADV_TYPE_TX_PWR_LEVEL,
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
                 .val = (uint8_t[]){ 0x00 },
                 .val_len = 1,
             },
@@ -287,7 +287,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
                 .val_len = 1,
             },
             {
-                .type = BLE_HS_ADV_TYPE_TX_PWR_LEVEL,
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
                 .val = (uint8_t[]){ 0x00 },
                 .val_len = 1,
             },
@@ -319,7 +319,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
                 .val_len = 1,
             },
             {
-                .type = BLE_HS_ADV_TYPE_TX_PWR_LEVEL,
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
                 .val = (uint8_t[]){ 0x00 },
                 .val_len = 1,
             },
@@ -351,7 +351,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
                 .val_len = 1,
             },
             {
-                .type = BLE_HS_ADV_TYPE_TX_PWR_LEVEL,
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
                 .val = (uint8_t[]){ 0x00 },
                 .val_len = 1,
             },
@@ -377,7 +377,7 @@ TEST_CASE(ble_hs_adv_test_case_user)
                 .val_len = 1,
             },
             {
-                .type = BLE_HS_ADV_TYPE_TX_PWR_LEVEL,
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
                 .val = (uint8_t[]){ 0x00 },
                 .val_len = 1,
             },
@@ -403,14 +403,186 @@ TEST_CASE(ble_hs_adv_test_case_user)
                 .val_len = 1,
             },
             {
-                .type = BLE_HS_ADV_TYPE_TX_PWR_LEVEL,
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
                 .val = (uint8_t[]){ 0x00 },
                 .val_len = 1,
             },
             { 0 },
         });
 
-    /*** LE role. */
+    /*** Class of device. */
+    memset(&fields, 0, sizeof fields);
+    fields.device_class = (uint8_t[]){ 1,2,3 };
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_DEVICE_CLASS,
+                .val = (uint8_t[]) { 1,2,3 },
+                .val_len = BLE_HS_ADV_DEVICE_CLASS_LEN,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0x00 },
+                .val_len = 1,
+            },
+            { 0 },
+        });
+
+    /*** Slave interval range. */
+    memset(&fields, 0, sizeof fields);
+    fields.slave_itvl_range = (uint8_t[]){ 1,2,3,4 };
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE,
+                .val = (uint8_t[]) { 1,2,3,4 },
+                .val_len = BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0x00 },
+                .val_len = 1,
+            },
+            { 0 },
+        });
+
+    /*** 0x16 - Service data - 16-bit UUID. */
+    memset(&fields, 0, sizeof fields);
+    fields.svc_data_uuid16 = (uint8_t[]){ 1,2,3,4 };
+    fields.svc_data_uuid16_len = 4;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_SVC_DATA_UUID16,
+                .val = (uint8_t[]) { 1,2,3,4 },
+                .val_len = 4,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0x00 },
+                .val_len = 1,
+            },
+            { 0 },
+        });
+
+    /*** 0x17 - Public target address. */
+    memset(&fields, 0, sizeof fields);
+    fields.public_tgt_addr = (uint8_t[]){ 1,2,3,4,5,6, 6,5,4,3,2,1 };
+    fields.num_public_tgt_addrs = 2;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR,
+                .val = (uint8_t[]){ 1,2,3,4,5,6, 6,5,4,3,2,1 },
+                .val_len = 2 * BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0x00 },
+                .val_len = 1,
+            },
+            { 0 },
+        });
+
+    /*** 0x19 - Appearance. */
+    memset(&fields, 0, sizeof fields);
+    fields.appearance = 0x1234;
+    fields.appearance_is_present = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_APPEARANCE,
+                .val = (uint8_t[]){ 0x34, 0x12 },
+                .val_len = BLE_HS_ADV_APPEARANCE_LEN,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0x00 },
+                .val_len = 1,
+            },
+            { 0 },
+        });
+
+    /*** 0x1a - Advertising interval. */
+    memset(&fields, 0, sizeof fields);
+    fields.adv_itvl = 0x1234;
+    fields.adv_itvl_is_present = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_ADV_ITVL,
+                .val = (uint8_t[]){ 0x34, 0x12 },
+                .val_len = BLE_HS_ADV_ADV_ITVL_LEN,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0x00 },
+                .val_len = 1,
+            },
+            { 0 },
+        });
+
+    /*** 0x1b - LE bluetooth device address. */
+    memset(&fields, 0, sizeof fields);
+    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, &fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_LE_ADDR,
+                .val = (uint8_t[]) { 1,2,3,4,5,6,7 },
+                .val_len = BLE_HS_ADV_LE_ADDR_LEN,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0x00 },
+                .val_len = 1,
+            },
+            { 0 },
+        });
+
+    /*** 0x1c - LE role. */
     memset(&fields, 0, sizeof fields);
     fields.le_role = BLE_HS_ADV_LE_ROLE_BOTH_PERIPH_PREF;
     fields.le_role_is_present = 1;
@@ -428,7 +600,109 @@ TEST_CASE(ble_hs_adv_test_case_user)
                 .val_len = 1,
             },
             {
-                .type = BLE_HS_ADV_TYPE_TX_PWR_LEVEL,
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0x00 },
+                .val_len = 1,
+            },
+            { 0 },
+        });
+
+    /*** 0x20 - Service data - 32-bit UUID. */
+    memset(&fields, 0, sizeof fields);
+    fields.svc_data_uuid32 = (uint8_t[]){ 1,2,3,4,5 };
+    fields.svc_data_uuid32_len = 5;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_SVC_DATA_UUID32,
+                .val = (uint8_t[]) { 1,2,3,4,5 },
+                .val_len = 5,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0x00 },
+                .val_len = 1,
+            },
+            { 0 },
+        });
+
+    /*** 0x21 - Service data - 128-bit UUID. */
+    memset(&fields, 0, sizeof fields);
+    fields.svc_data_uuid128 =
+        (uint8_t[]){ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 };
+    fields.svc_data_uuid128_len = 18;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_SVC_DATA_UUID128,
+                .val = (uint8_t[]){ 1,2,3,4,5,6,7,8,9,10,
+                                    11,12,13,14,15,16,17,18 },
+                .val_len = 18,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0x00 },
+                .val_len = 1,
+            },
+            { 0 },
+        });
+
+    /*** 0x24 - URI. */
+    memset(&fields, 0, sizeof fields);
+    fields.uri = (uint8_t[]){ 1,2,3,4 };
+    fields.uri_len = 4;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_URI,
+                .val = (uint8_t[]) { 1,2,3,4 },
+                .val_len = 4,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0x00 },
+                .val_len = 1,
+            },
+            { 0 },
+        });
+
+    /*** 0xff - Manufacturer specific data. */
+    memset(&fields, 0, sizeof fields);
+    fields.mfg_data = (uint8_t[]){ 1,2,3,4 };
+    fields.mfg_data_len = 4;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_MFG_DATA,
+                .val = (uint8_t[]) { 1,2,3,4 },
+                .val_len = 4,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
                 .val = (uint8_t[]){ 0x00 },
                 .val_len = 1,
             },



[2/2] incubator-mynewt-larva git commit: bleshell - add advertisement data fields.

Posted by cc...@apache.org.
bleshell - add advertisement data fields.


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

Branch: refs/heads/master
Commit: 2ffa2158b3b3c97ecdd50e060268a5c87147cc82
Parents: 14ef31c
Author: Christopher Collins <cc...@gmail.com>
Authored: Sat Jan 23 21:42:27 2016 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Sat Jan 23 21:42:27 2016 -0800

----------------------------------------------------------------------
 project/bleshell/src/bleshell_priv.h |   2 +
 project/bleshell/src/cmd.c           | 209 +++++++++++++++++++++++++++++-
 project/bleshell/src/main.c          | 127 +++++++++++++++++-
 project/bleshell/src/parse.c         |   8 +-
 4 files changed, 338 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2ffa2158/project/bleshell/src/bleshell_priv.h
----------------------------------------------------------------------
diff --git a/project/bleshell/src/bleshell_priv.h b/project/bleshell/src/bleshell_priv.h
index a3de9d7..956bdd6 100644
--- a/project/bleshell/src/bleshell_priv.h
+++ b/project/bleshell/src/bleshell_priv.h
@@ -73,8 +73,10 @@ long parse_arg_long_bounds(char *name, long min, long max, int *out_status);
 long parse_arg_long(char *name, int *staus);
 uint16_t parse_arg_uint16(char *name, int *status);
 uint16_t parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status);
+uint32_t parse_arg_uint32(char *name, int *out_status);
 int parse_arg_kv(char *name, struct kv_pair *kvs);
 int parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len);
+int parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len);
 int parse_arg_mac(char *name, uint8_t *dst);
 int parse_arg_uuid(char *name, uint8_t *dst_uuid128);
 int parse_err_too_few_args(char *cmd_name);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2ffa2158/project/bleshell/src/cmd.c
----------------------------------------------------------------------
diff --git a/project/bleshell/src/cmd.c b/project/bleshell/src/cmd.c
index 84b1d96..516cfae 100644
--- a/project/bleshell/src/cmd.c
+++ b/project/bleshell/src/cmd.c
@@ -7,6 +7,7 @@
 #include "nimble/ble.h"
 #include "nimble/hci_common.h"
 #include "host/ble_gap.h"
+#include "host/ble_hs_adv.h"
 
 #include "bleshell_priv.h"
 
@@ -712,16 +713,46 @@ cmd_show(int argc, char **argv)
  * $set                                                                      *
  *****************************************************************************/
 
-#define CMD_ADV_DATA_MAX_UUIDS16    8
-//#define CMD_ADV_DATA_MAX_UUIDS128   8
+#define CMD_ADV_DATA_MAX_UUIDS16                8
+#define CMD_ADV_DATA_MAX_UUIDS32                8
+#define CMD_ADV_DATA_MAX_UUIDS128               8
+#define CMD_ADV_DATA_MAX_PUBLIC_TGT_ADDRS       8
+#define CMD_ADV_DATA_SVC_DATA_UUID16_MAX_LEN    32
+#define CMD_ADV_DATA_SVC_DATA_UUID32_MAX_LEN    32
+#define CMD_ADV_DATA_SVC_DATA_UUID128_MAX_LEN   32
+#define CMD_ADV_DATA_URI_MAX_LEN                32
+#define CMD_ADV_DATA_MFG_DATA_MAX_LEN           32
 
 static int
 cmd_set_adv_data(void)
 {
-    static uint16_t uuids16[8];
-    //static uint8_t uuids128[8][16];
+    static bssnz_t uint16_t uuids16[CMD_ADV_DATA_MAX_UUIDS16];
+    static bssnz_t uint32_t uuids32[CMD_ADV_DATA_MAX_UUIDS32];
+    static bssnz_t uint8_t uuids128[CMD_ADV_DATA_MAX_UUIDS128][16];
+    static bssnz_t uint8_t
+        public_tgt_addrs[CMD_ADV_DATA_MAX_PUBLIC_TGT_ADDRS]
+                        [BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN];
+    static bssnz_t uint8_t device_class[BLE_HS_ADV_DEVICE_CLASS_LEN];
+    static bssnz_t uint8_t slave_itvl_range[BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN];
+    static bssnz_t uint8_t
+        svc_data_uuid16[CMD_ADV_DATA_SVC_DATA_UUID16_MAX_LEN];
+    static bssnz_t uint8_t
+        svc_data_uuid32[CMD_ADV_DATA_SVC_DATA_UUID32_MAX_LEN];
+    static bssnz_t uint8_t
+        svc_data_uuid128[CMD_ADV_DATA_SVC_DATA_UUID128_MAX_LEN];
+    static bssnz_t uint8_t le_addr[BLE_HS_ADV_LE_ADDR_LEN];
+    static bssnz_t uint8_t uri[CMD_ADV_DATA_URI_MAX_LEN];
+    static bssnz_t uint8_t mfg_data[CMD_ADV_DATA_MFG_DATA_MAX_LEN];
     struct ble_hs_adv_fields adv_fields;
+    uint32_t uuid32;
     uint16_t uuid16;
+    uint8_t uuid128[16];
+    uint8_t public_tgt_addr[BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN];
+    int svc_data_uuid16_len;
+    int svc_data_uuid32_len;
+    int svc_data_uuid128_len;
+    int uri_len;
+    int mfg_data_len;
     int tmp;
     int rc;
 
@@ -752,19 +783,185 @@ cmd_set_adv_data(void)
         return rc;
     }
 
+    while (1) {
+        uuid32 = parse_arg_uint32("uuid32", &rc);
+        if (rc == 0) {
+            if (adv_fields.num_uuids32 >= CMD_ADV_DATA_MAX_UUIDS32) {
+                return EINVAL;
+            }
+            uuids32[adv_fields.num_uuids32] = uuid32;
+            adv_fields.num_uuids32++;
+        } else if (rc == ENOENT) {
+            break;
+        } else {
+            return rc;
+        }
+    }
+    if (adv_fields.num_uuids32 > 0) {
+        adv_fields.uuids32 = uuids32;
+    }
+
+    tmp = parse_arg_long("uuids32_is_complete", &rc);
+    if (rc == 0) {
+        adv_fields.uuids32_is_complete = !!tmp;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
+    while (1) {
+        rc = parse_arg_byte_stream_exact_length("uuid128", uuid128, 16);
+        if (rc == 0) {
+            if (adv_fields.num_uuids128 >= CMD_ADV_DATA_MAX_UUIDS128) {
+                return EINVAL;
+            }
+            memcpy(uuids128[adv_fields.num_uuids128], uuid128, 16);
+            adv_fields.num_uuids128++;
+        } else if (rc == ENOENT) {
+            break;
+        } else {
+            return rc;
+        }
+    }
+    if (adv_fields.num_uuids128 > 0) {
+        adv_fields.uuids128 = uuids128;
+    }
+
+    tmp = parse_arg_long("uuids128_is_complete", &rc);
+    if (rc == 0) {
+        adv_fields.uuids128_is_complete = !!tmp;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
     adv_fields.name = (uint8_t *)parse_arg_find("name");
     if (adv_fields.name != NULL) {
         adv_fields.name_len = strlen((char *)adv_fields.name);
     }
 
-    tmp = parse_arg_long_bounds("le_role", 0, 0xff, &rc);
+    tmp = parse_arg_long_bounds("tx_pwr_lvl", 0, 0xff, &rc);
+    if (rc == 0) {
+        adv_fields.tx_pwr_lvl = tmp;
+        adv_fields.tx_pwr_lvl_is_present = 1;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
+    rc = parse_arg_byte_stream_exact_length("device_class", device_class,
+                                            BLE_HS_ADV_DEVICE_CLASS_LEN);
+    if (rc == 0) {
+        adv_fields.device_class = device_class;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
+    rc = parse_arg_byte_stream_exact_length("slave_itvl_range",
+                                            slave_itvl_range,
+                                            BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
+    if (rc == 0) {
+        adv_fields.slave_itvl_range = slave_itvl_range;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
+    rc = parse_arg_byte_stream("svc_data_uuid16",
+                               CMD_ADV_DATA_SVC_DATA_UUID16_MAX_LEN,
+                               svc_data_uuid16, &svc_data_uuid16_len);
+    if (rc == 0) {
+        adv_fields.svc_data_uuid16 = svc_data_uuid16;
+        adv_fields.svc_data_uuid16_len = svc_data_uuid16_len;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
+    while (1) {
+        rc = parse_arg_byte_stream_exact_length(
+            "public_tgt_addr", public_tgt_addr,
+            BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN);
+        if (rc == 0) {
+            if (adv_fields.num_public_tgt_addrs >=
+                CMD_ADV_DATA_MAX_PUBLIC_TGT_ADDRS) {
+
+                return EINVAL;
+            }
+            memcpy(public_tgt_addrs[adv_fields.num_public_tgt_addrs],
+                   public_tgt_addr, BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN);
+            adv_fields.num_public_tgt_addrs++;
+        } else if (rc == ENOENT) {
+            break;
+        } else {
+            return rc;
+        }
+    }
+    if (adv_fields.num_public_tgt_addrs > 0) {
+        adv_fields.public_tgt_addr = (void *)public_tgt_addrs;
+    }
+
+    adv_fields.appearance = parse_arg_uint16("appearance", &rc);
+    if (rc == 0) {
+        adv_fields.appearance_is_present = 1;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
+    adv_fields.adv_itvl = parse_arg_uint16("adv_itvl", &rc);
+    if (rc == 0) {
+        adv_fields.adv_itvl_is_present = 1;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
+    rc = parse_arg_byte_stream_exact_length("le_addr", le_addr,
+                                            BLE_HS_ADV_LE_ADDR_LEN);
+    if (rc == 0) {
+        adv_fields.le_addr = le_addr;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
+    adv_fields.le_role = parse_arg_long_bounds("le_role", 0, 0xff, &rc);
     if (rc == 0) {
-        adv_fields.le_role = tmp;
         adv_fields.le_role_is_present = 1;
     } else if (rc != ENOENT) {
         return rc;
     }
 
+    rc = parse_arg_byte_stream("svc_data_uuid32",
+                               CMD_ADV_DATA_SVC_DATA_UUID32_MAX_LEN,
+                               svc_data_uuid32, &svc_data_uuid32_len);
+    if (rc == 0) {
+        adv_fields.svc_data_uuid32 = svc_data_uuid32;
+        adv_fields.svc_data_uuid32_len = svc_data_uuid32_len;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
+    rc = parse_arg_byte_stream("svc_data_uuid128",
+                               CMD_ADV_DATA_SVC_DATA_UUID128_MAX_LEN,
+                               svc_data_uuid128, &svc_data_uuid128_len);
+    if (rc == 0) {
+        adv_fields.svc_data_uuid128 = svc_data_uuid128;
+        adv_fields.svc_data_uuid128_len = svc_data_uuid128_len;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
+    rc = parse_arg_byte_stream("uri", CMD_ADV_DATA_URI_MAX_LEN, uri, &uri_len);
+    if (rc == 0) {
+        adv_fields.uri = uri;
+        adv_fields.uri_len = uri_len;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
+    rc = parse_arg_byte_stream("mfg_data", CMD_ADV_DATA_MFG_DATA_MAX_LEN,
+                               mfg_data, &mfg_data_len);
+    if (rc == 0) {
+        adv_fields.mfg_data = mfg_data;
+        adv_fields.mfg_data_len = mfg_data_len;
+    } else if (rc != ENOENT) {
+        return rc;
+    }
+
     rc = bleshell_set_adv_data(&adv_fields);
     if (rc != 0) {
         console_printf("error setting advertisement data; rc=%d\n", rc);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2ffa2158/project/bleshell/src/main.c
----------------------------------------------------------------------
diff --git a/project/bleshell/src/main.c b/project/bleshell/src/main.c
index eee88f6..3e81f17 100755
--- a/project/bleshell/src/main.c
+++ b/project/bleshell/src/main.c
@@ -30,6 +30,7 @@
 #include "nimble/ble.h"
 #include "host/host_hci.h"
 #include "host/ble_hs.h"
+#include "host/ble_hs_adv.h"
 #include "host/ble_uuid.h"
 #include "host/ble_att.h"
 #include "host/ble_gap.h"
@@ -139,6 +140,129 @@ bleshell_print_conn_desc(struct ble_gap_conn_desc *desc)
                    desc->supervision_timeout);
 }
 
+static void
+bleshell_print_adv_fields(struct ble_hs_adv_fields *fields)
+{
+    uint32_t u32;
+    uint16_t u16;
+    uint8_t *u8p;
+    int i;
+
+    if (fields->flags_is_present) {
+        console_printf("    flags=0x%02x\n", fields->flags);
+    }
+
+    if (fields->uuids16 != NULL) {
+        console_printf("    uuids16(%scomplete)=",
+                       fields->uuids16_is_complete ? "" : "in");
+        u8p = fields->uuids16;
+        for (i = 0; i < fields->num_uuids16; i++) {
+            memcpy(&u16, u8p + i * 2, 2);
+            console_printf("0x%04x ", u16);
+        }
+        console_printf("\n");
+    }
+
+    if (fields->uuids32 != NULL) {
+        console_printf("    uuids32(%scomplete)=",
+                       fields->uuids32_is_complete ? "" : "in");
+        u8p = fields->uuids32;
+        for (i = 0; i < fields->num_uuids32; i++) {
+            memcpy(&u32, u8p + i * 4, 4);
+            console_printf("0x%08x ", (unsigned)u32);
+        }
+        console_printf("\n");
+    }
+
+    if (fields->uuids128 != NULL) {
+        console_printf("    uuids128(%scomplete)=",
+                       fields->uuids128_is_complete ? "" : "in");
+        u8p = fields->uuids128;
+        for (i = 0; i < fields->num_uuids128; i++) {
+            print_uuid(u8p);
+            console_printf(" ");
+            u8p += 16;
+        }
+        console_printf("\n");
+    }
+
+    if (fields->name != NULL) {
+        console_printf("    name(%scomplete)=",
+                       fields->name_is_complete ? "" : "in");
+        console_printf("%*s\n", fields->name_len, fields->name);
+    }
+
+    if (fields->tx_pwr_lvl_is_present) {
+        console_printf("    tx_pwr_lvl=%d\n", fields->tx_pwr_lvl);
+    }
+
+    if (fields->device_class != NULL) {
+        console_printf("    device_class=");
+        bleshell_print_bytes(fields->device_class,
+                             BLE_HS_ADV_DEVICE_CLASS_LEN);
+    }
+
+    if (fields->slave_itvl_range != NULL) {
+        console_printf("    slave_itvl_range=");
+        bleshell_print_bytes(fields->slave_itvl_range,
+                             BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
+    }
+
+    if (fields->svc_data_uuid16 != NULL) {
+        console_printf("    svc_data_uuid16=");
+        bleshell_print_bytes(fields->svc_data_uuid16,
+                             fields->svc_data_uuid16_len);
+    }
+
+    if (fields->public_tgt_addr != NULL) {
+        console_printf("    public_tgt_addr=");
+        u8p = fields->public_tgt_addr;
+        for (i = 0; i < fields->num_public_tgt_addrs; i++) {
+            print_addr(u8p);
+            u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN;
+        }
+    }
+
+    if (fields->appearance_is_present) {
+        console_printf("    appearance=0x%04x\n", fields->appearance);
+    }
+
+    if (fields->adv_itvl_is_present) {
+        console_printf("    adv_itvl=0x%04x\n", fields->adv_itvl);
+    }
+
+    if (fields->le_addr != NULL) {
+        console_printf("    le_addr=");
+        bleshell_print_bytes(fields->le_addr, BLE_HS_ADV_LE_ADDR_LEN);
+    }
+
+    if (fields->le_role_is_present) {
+        console_printf("    le_role=0x%02x\n", fields->le_role);
+    }
+
+    if (fields->svc_data_uuid32 != NULL) {
+        console_printf("    svc_data_uuid32=");
+        bleshell_print_bytes(fields->svc_data_uuid32,
+                             fields->svc_data_uuid32_len);
+    }
+
+    if (fields->svc_data_uuid128 != NULL) {
+        console_printf("    svc_data_uuid128=");
+        bleshell_print_bytes(fields->svc_data_uuid128,
+                             fields->svc_data_uuid128_len);
+    }
+
+    if (fields->uri != NULL) {
+        console_printf("    uri=");
+        bleshell_print_bytes(fields->uri, fields->uri_len);
+    }
+
+    if (fields->mfg_data != NULL) {
+        console_printf("    mfg_data=");
+        bleshell_print_bytes(fields->mfg_data, fields->mfg_data_len);
+    }
+}
+
 static int
 bleshell_conn_find_idx(uint16_t handle)
 {
@@ -720,7 +844,8 @@ bleshell_on_scan(int event, int status, struct ble_gap_disc_desc *desc,
         console_printf(" length_data=%d rssi=%d data=", desc->length_data,
                        desc->rssi);
         bleshell_print_bytes(desc->data, desc->length_data);
-        /* XXX: Print fields. */
+        console_printf(" fields:\n");
+        bleshell_print_adv_fields(desc->fields);
         console_printf("\n");
         break;
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/2ffa2158/project/bleshell/src/parse.c
----------------------------------------------------------------------
diff --git a/project/bleshell/src/parse.c b/project/bleshell/src/parse.c
index 3d6817f..a198b33 100644
--- a/project/bleshell/src/parse.c
+++ b/project/bleshell/src/parse.c
@@ -137,6 +137,12 @@ parse_arg_uint16(char *name, int *out_status)
     return parse_arg_long_bounds(name, 0, UINT16_MAX, out_status);
 }
 
+uint32_t
+parse_arg_uint32(char *name, int *out_status)
+{
+    return parse_arg_long_bounds(name, 0, UINT32_MAX, out_status);
+}
+
 uint16_t
 parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status)
 {
@@ -259,7 +265,7 @@ parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len)
     }
 }
 
-static int
+int
 parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len)
 {
     int actual_len;