nimble/gap: Use raw data only in ble_gap_disc_desc struct

The main API to set adv data now accepts raw buffers with helper func
to create data from ble_hs_adv_fields.

This patch does the same for the data that host sends as an even to
application, i.e. ble_gap_disc_desc contains only raw buffer and there
are helpers to parse them into ble_hs_adv_fields struct or iterate
using a callback.


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

Branch: refs/heads/develop
Commit: 1fe117a67d65cb8e827f39048ce549d2e983776c
Parents: c5b5588
Author: Andrzej Kaczmarek <[email protected]>
Authored: Thu Jan 26 17:19:11 2017 +0100
Committer: Andrzej Kaczmarek <[email protected]>
Committed: Fri Jan 27 16:51:41 2017 +0100

----------------------------------------------------------------------
 apps/blecent/src/main.c                   | 20 ++++++--
 apps/bletiny/src/main.c                   |  5 +-
 net/nimble/host/include/host/ble_gap.h    |  4 +-
 net/nimble/host/include/host/ble_hs_adv.h | 15 ++++++
 net/nimble/host/src/ble_gap.c             | 20 +++-----
 net/nimble/host/src/ble_hs_adv.c          | 67 ++++++++++++++++++++++++++
 net/nimble/host/src/ble_hs_adv_priv.h     |  4 +-
 net/nimble/host/src/ble_hs_hci_evt.c      |  1 -
 net/nimble/host/test/src/ble_gap_test.c   |  2 +-
 9 files changed, 115 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1fe117a6/apps/blecent/src/main.c
----------------------------------------------------------------------
diff --git a/apps/blecent/src/main.c b/apps/blecent/src/main.c
index f6de476..64279a9 100755
--- a/apps/blecent/src/main.c
+++ b/apps/blecent/src/main.c
@@ -259,6 +259,8 @@ blecent_scan(void)
 static int
 blecent_should_connect(const struct ble_gap_disc_desc *disc)
 {
+    struct ble_hs_adv_fields fields;
+    int rc;
     int i;
 
     /* The device has to be advertising connectability. */
@@ -268,11 +270,16 @@ blecent_should_connect(const struct ble_gap_disc_desc 
*disc)
         return 0;
     }
 
+    rc = ble_hs_adv_parse_fields(&fields, disc->data, disc->length_data);
+    if (rc != 0) {
+        return rc;
+    }
+
     /* The device has to advertise support for the Alert Notification
      * service (0x1811).
      */
-    for (i = 0; i < disc->fields->num_uuids16; i++) {
-        if (disc->fields->uuids16[i] == BLECENT_SVC_ALERT_UUID) {
+    for (i = 0; i < fields.num_uuids16; i++) {
+        if (fields.uuids16[i] == BLECENT_SVC_ALERT_UUID) {
             return 1;
         }
     }
@@ -332,12 +339,19 @@ static int
 blecent_gap_event(struct ble_gap_event *event, void *arg)
 {
     struct ble_gap_conn_desc desc;
+    struct ble_hs_adv_fields fields;
     int rc;
 
     switch (event->type) {
     case BLE_GAP_EVENT_DISC:
+        rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
+                                     event->disc.length_data);
+        if (rc != 0) {
+            return 0;
+        }
+
         /* An advertisment report was received during GAP discovery. */
-        print_adv_fields(event->disc.fields);
+        print_adv_fields(&fields);
 
         /* Try to connect to the advertiser if it looks interesting. */
         blecent_connect_if_interesting(&event->disc);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1fe117a6/apps/bletiny/src/main.c
----------------------------------------------------------------------
diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c
index 5aa2f44..63b0535 100755
--- a/apps/bletiny/src/main.c
+++ b/apps/bletiny/src/main.c
@@ -879,6 +879,7 @@ static int
 bletiny_gap_event(struct ble_gap_event *event, void *arg)
 {
     struct ble_gap_conn_desc desc;
+    struct ble_hs_adv_fields fields;
     int conn_idx;
     int rc;
 
@@ -926,7 +927,9 @@ bletiny_gap_event(struct ble_gap_event *event, void *arg)
                                event->disc.length_data);
         print_bytes(event->disc.data, event->disc.length_data);
         console_printf(" fields:\n");
-        bletiny_print_adv_fields(event->disc.fields);
+        ble_hs_adv_parse_fields(&fields, event->disc.data,
+                                event->disc.length_data);
+        bletiny_print_adv_fields(&fields);
         console_printf("\n");
         return 0;
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1fe117a6/net/nimble/host/include/host/ble_gap.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gap.h 
b/net/nimble/host/include/host/ble_gap.h
index f24c4e0..fa84d3b 100644
--- a/net/nimble/host/include/host/ble_gap.h
+++ b/net/nimble/host/include/host/ble_gap.h
@@ -22,6 +22,7 @@
 
 #include <inttypes.h>
 #include "host/ble_hs.h"
+#include "host/ble_hs_adv.h"
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -222,10 +223,7 @@ struct ble_gap_disc_desc {
     uint8_t length_data;
     int8_t rssi;
     uint8_t addr[6];
-
-    /*** LE advertising report fields; both null if no data present. */
     uint8_t *data;
-    struct ble_hs_adv_fields *fields;
 
     /***
      * LE direct advertising report fields; direct_addr_type is

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1fe117a6/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
index d15c8ee..538fc7d 100644
--- a/net/nimble/host/include/host/ble_hs_adv.h
+++ b/net/nimble/host/include/host/ble_hs_adv.h
@@ -31,6 +31,15 @@ extern "C" {
 /** Max field payload size (account for 2-byte header). */
 #define BLE_HS_ADV_MAX_FIELD_SZ     (BLE_HS_ADV_MAX_SZ - 2)
 
+struct ble_hs_adv_field {
+    uint8_t length;
+    uint8_t type;
+    uint8_t value[];
+};
+
+typedef int (* ble_hs_adv_parse_func_t) (const struct ble_hs_adv_field *,
+                                         void *);
+
 struct ble_hs_adv_fields {
     /*** 0x01 - Flags. */
     uint8_t flags;
@@ -148,6 +157,12 @@ struct ble_hs_adv_fields {
 int ble_hs_adv_set_fields(const 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);
+
+int ble_hs_adv_parse(const uint8_t *data, uint8_t length,
+                     ble_hs_adv_parse_func_t func, void *user_data);
+
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1fe117a6/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 8d46aa4..3b9892c 100644
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@ -1056,7 +1056,7 @@ ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc)
     return;
 #endif
 
-    struct ble_hs_adv_fields fields;
+    const struct ble_hs_adv_field *flags;
     int rc;
 
     STATS_INC(ble_gap_stats, rx_adv_report);
@@ -1065,22 +1065,18 @@ ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc)
         return;
     }
 
-    rc = ble_hs_adv_parse_fields(&fields, desc->data, desc->length_data);
-    if (rc != 0) {
-        /* XXX: Increment stat. */
-        return;
-    }
-
     /* If a limited discovery procedure is active, discard non-limited
      * advertisements.
      */
-    if (ble_gap_master.disc.limited &&
-        !(fields.flags & BLE_HS_ADV_F_DISC_LTD)) {
-
-        return;
+    if (ble_gap_master.disc.limited) {
+        rc = ble_hs_adv_find_field(BLE_HS_ADV_TYPE_FLAGS, desc->data,
+                                   desc->length_data, &flags);
+        if ((rc == 0) && (flags->length == 2) &&
+            !(flags->value[0] & BLE_HS_ADV_F_DISC_LTD)) {
+            return;
+        }
     }
 
-    desc->fields = &fields;
     ble_gap_disc_report(desc);
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1fe117a6/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 1d65817..37236c8 100644
--- a/net/nimble/host/src/ble_hs_adv.c
+++ b/net/nimble/host/src/ble_hs_adv.c
@@ -23,6 +23,11 @@
 #include "host/ble_hs_adv.h"
 #include "ble_hs_priv.h"
 
+struct find_field_data {
+    uint8_t type;
+    const struct ble_hs_adv_field *field;
+};
+
 static uint16_t ble_hs_adv_uuids16[BLE_HS_ADV_MAX_FIELD_SZ / 2];
 static uint32_t ble_hs_adv_uuids32[BLE_HS_ADV_MAX_FIELD_SZ / 4];
 
@@ -561,3 +566,65 @@ ble_hs_adv_parse_fields(struct ble_hs_adv_fields 
*adv_fields, uint8_t *src,
 
     return 0;
 }
+
+int
+ble_hs_adv_parse(const uint8_t *data, uint8_t length,
+                 ble_hs_adv_parse_func_t func, void *user_data)
+{
+    const struct ble_hs_adv_field *field;
+
+    while (length > 1) {
+        field = (const void *) data;
+
+        if (field->length >= length) {
+            return BLE_HS_EBADDATA;
+        }
+
+        if (func(field, user_data) == 0) {
+            return 0;
+        }
+
+        length -= 1 + field->length;
+        length += 1 + field->length;
+    }
+
+    return 0;
+}
+
+static int
+find_field_func(const struct ble_hs_adv_field *field, void *user_data)
+{
+    struct find_field_data *ffd = user_data;
+
+    if (field->type != ffd->type) {
+        return BLE_HS_EAGAIN;
+    }
+
+    ffd->field = field;
+
+    return 0;
+}
+
+int
+ble_hs_adv_find_field(uint8_t type, const uint8_t *data, uint8_t length,
+                      const struct ble_hs_adv_field **out)
+{
+    int rc;
+    struct find_field_data ffd = {
+            .type = type,
+            .field = NULL,
+    };
+
+    rc = ble_hs_adv_parse(data, length, find_field_func, &ffd);
+    if (rc != 0) {
+        return rc;
+    }
+
+    if (!ffd.field) {
+        return BLE_HS_ENOENT;
+    }
+
+    *out = ffd.field;
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1fe117a6/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
index f913b09..5c8a6ec 100644
--- a/net/nimble/host/src/ble_hs_adv_priv.h
+++ b/net/nimble/host/src/ble_hs_adv_priv.h
@@ -26,8 +26,8 @@ extern "C" {
 
 int ble_hs_adv_set_flat(uint8_t type, int data_len, const void *data,
                         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);
+int ble_hs_adv_find_field(uint8_t type, const uint8_t *data, uint8_t length,
+                          const struct ble_hs_adv_field **out);
 
 #ifdef __cplusplus
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1fe117a6/net/nimble/host/src/ble_hs_hci_evt.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_hci_evt.c 
b/net/nimble/host/src/ble_hs_hci_evt.c
index 546e38b..4305124 100644
--- a/net/nimble/host/src/ble_hs_hci_evt.c
+++ b/net/nimble/host/src/ble_hs_hci_evt.c
@@ -434,7 +434,6 @@ ble_hs_hci_evt_le_dir_adv_rpt(uint8_t subevent, uint8_t 
*data, int len)
 
     /* Data fields not present in a direct advertising report. */
     desc.data = NULL;
-    desc.fields = NULL;
 
     for (i = 0; i < num_reports; i++) {
         suboff = 0;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/1fe117a6/net/nimble/host/test/src/ble_gap_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_gap_test.c 
b/net/nimble/host/test/src/ble_gap_test.c
index 7aaebee..a13640e 100644
--- a/net/nimble/host/test/src/ble_gap_test.c
+++ b/net/nimble/host/test/src/ble_gap_test.c
@@ -630,7 +630,7 @@ TEST_CASE(ble_gap_test_case_disc_ltd_mismatch)
     struct ble_gap_disc_desc desc = {
         .event_type = BLE_HCI_ADV_TYPE_ADV_IND,
         .addr_type = BLE_ADDR_TYPE_PUBLIC,
-        .length_data = 0,
+        .length_data = 3,
         .rssi = 0,
         .addr = { 1, 2, 3, 4, 5, 6 },
         .data = (uint8_t[BLE_HS_ADV_MAX_SZ]){

Reply via email to