You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ja...@apache.org on 2020/03/19 12:03:28 UTC

[mynewt-documentation] branch master updated: Fixed BLE Peripheral Project - Characteristic Access

This is an automated email from the ASF dual-hosted git repository.

janc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-documentation.git


The following commit(s) were added to refs/heads/master by this push:
     new 2b5a015  Fixed BLE Peripheral Project - Characteristic Access
2b5a015 is described below

commit 2b5a01588ec7b87a343e58cc281f9a1c297d0cad
Author: Krzysztof Kopyściński <kr...@codecoup.pl>
AuthorDate: Wed Mar 18 13:21:13 2020 +0100

    Fixed BLE Peripheral Project - Characteristic Access
    
    - Tutorial accomodated to changes from commit 8fe77a4
    - Functions updated to current version of mynewt-nimble/apps/bleprph
    - Edited table contents to fit rest of changes
    - Tutorial text changes commenting new syntax
    - Tutorial text deletions commenting removed/swapped code snippets
    - bleprph is part of nimble, not core
---
 .../ble/bleprph/bleprph-sections/bleprph-app.rst   |   2 +-
 .../bleprph-sections/bleprph-chr-access.rst        | 248 +++++++++------------
 docs/tutorials/ble/bleprph/bleprph.rst             |   2 +-
 3 files changed, 106 insertions(+), 146 deletions(-)

diff --git a/docs/tutorials/ble/bleprph/bleprph-sections/bleprph-app.rst b/docs/tutorials/ble/bleprph/bleprph-sections/bleprph-app.rst
index 9ded59d..4bd8498 100644
--- a/docs/tutorials/ble/bleprph/bleprph-sections/bleprph-app.rst
+++ b/docs/tutorials/ble/bleprph/bleprph-sections/bleprph-app.rst
@@ -34,7 +34,7 @@ Peripheral
     $ newt target set myperiph bsp=@apache-mynewt-core/hw/bsp/nrf52dk
     Target targets/myperiph successfully set target.bsp to @apache-mynewt-core/hw/bsp/nrf52dk
     $ newt target set myperiph app=@apache-mynewt-core/apps/bleprph
-    Target targets/myperiph successfully set target.app to @apache-mynewt-core/apps/bleprph
+    Target targets/myperiph successfully set target.app to @apache-mynewt-nimble/apps/bleprph
     $ newt target set myperiph build_profile=optimized
     Target targets/myperiph successfully set target.build_profile to optimized
     $ newt build myperiph
diff --git a/docs/tutorials/ble/bleprph/bleprph-sections/bleprph-chr-access.rst b/docs/tutorials/ble/bleprph/bleprph-sections/bleprph-chr-access.rst
index 0e34078..b2beacf 100644
--- a/docs/tutorials/ble/bleprph/bleprph-sections/bleprph-chr-access.rst
+++ b/docs/tutorials/ble/bleprph/bleprph-sections/bleprph-chr-access.rst
@@ -23,19 +23,20 @@ few characteristics in this service.
 
     static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
         {
-            /*** Service: GAP. */
+            /*** Service: Security test. */
             .type               = BLE_GATT_SVC_TYPE_PRIMARY,
-            .uuid128            = BLE_UUID16(BLE_GAP_SVC_UUID16),
+            .uuid               = &gatt_svr_svc_sec_test_uuid.u,
             .characteristics    = (struct ble_gatt_chr_def[]) { {
-                /*** Characteristic: Device Name. */
-                .uuid128            = BLE_UUID16(BLE_GAP_CHR_UUID16_DEVICE_NAME),
-                .access_cb          = gatt_svr_chr_access_gap,
-                .flags              = BLE_GATT_CHR_F_READ,
+                /*** Characteristic: Random number generator. */
+                .uuid               = &gatt_svr_chr_sec_test_rand_uuid.u,
+                .access_cb          = gatt_svr_chr_access_sec_test,
+                .flags              = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC,
             }, {
-                /*** Characteristic: Appearance. */
-                .uuid128            = BLE_UUID16(BLE_GAP_CHR_UUID16_APPEARANCE),
-                .access_cb          = gatt_svr_chr_access_gap,
-                .flags              = BLE_GATT_CHR_F_READ,
+                /*** Characteristic: Static value. */
+                .uuid               = gatt_svr_chr_sec_test_static_uuid.u,
+                .access_cb          = gatt_svr_chr_access_sec_test,
+                .flags              = BLE_GATT_CHR_F_READ |
+                                      BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC,
             }, {
         // [...]
 
@@ -48,55 +49,55 @@ characteristics use:
 .. code:: c
 
     static int
-    gatt_svr_chr_access_gap(uint16_t conn_handle, uint16_t attr_handle, uint8_t op,
-                            union ble_gatt_access_ctxt *ctxt, void *arg)
+    gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
+                                 struct ble_gatt_access_ctxt *ctxt,
+                                 void *arg)
     {
-        uint16_t uuid16;
-
-        uuid16 = ble_uuid_128_to_16(ctxt->chr_access.chr->uuid128);
-        assert(uuid16 != 0);
-
-        switch (uuid16) {
-        case BLE_GAP_CHR_UUID16_DEVICE_NAME:
-            assert(op == BLE_GATT_ACCESS_OP_READ_CHR);
-            ctxt->chr_access.data = (void *)bleprph_device_name;
-            ctxt->chr_access.len = strlen(bleprph_device_name);
-            break;
-
-        case BLE_GAP_CHR_UUID16_APPEARANCE:
-            assert(op == BLE_GATT_ACCESS_OP_READ_CHR);
-            ctxt->chr_access.data = (void *)&bleprph_appearance;
-            ctxt->chr_access.len = sizeof bleprph_appearance;
-            break;
-
-        case BLE_GAP_CHR_UUID16_PERIPH_PRIV_FLAG:
-            assert(op == BLE_GATT_ACCESS_OP_READ_CHR);
-            ctxt->chr_access.data = (void *)&bleprph_privacy_flag;
-            ctxt->chr_access.len = sizeof bleprph_privacy_flag;
-            break;
-
-        case BLE_GAP_CHR_UUID16_RECONNECT_ADDR:
-            assert(op == BLE_GATT_ACCESS_OP_WRITE_CHR);
-            if (ctxt->chr_access.len != sizeof bleprph_reconnect_addr) {
-                return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
+        const ble_uuid_t *uuid;
+        int rand_num;
+        int rc;
+
+        uuid = ctxt->chr->uuid;
+
+        /* Determine which characteristic is being accessed by examining its
+         * 128-bit UUID.
+         */
+
+        if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_rand_uuid.u) == 0) {
+            assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
+
+            /* Respond with a 32-bit random number. */
+            rand_num = rand();
+            rc = os_mbuf_append(ctxt->om, &rand_num, sizeof rand_num);
+            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
+        }
+
+        if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_static_uuid.u) == 0) {
+            switch (ctxt->op) {
+            case BLE_GATT_ACCESS_OP_READ_CHR:
+                rc = os_mbuf_append(ctxt->om, &gatt_svr_sec_test_static_val,
+                                    sizeof gatt_svr_sec_test_static_val);
+                return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
+
+            case BLE_GATT_ACCESS_OP_WRITE_CHR:
+                rc = gatt_svr_chr_write(ctxt->om,
+                                        sizeof gatt_svr_sec_test_static_val,
+                                        sizeof gatt_svr_sec_test_static_val,
+                                        &gatt_svr_sec_test_static_val, NULL);
+                return rc;
+
+            default:
+                assert(0);
+                return BLE_ATT_ERR_UNLIKELY;
             }
-            memcpy(bleprph_reconnect_addr, ctxt->chr_access.data,
-                   sizeof bleprph_reconnect_addr);
-            break;
-
-        case BLE_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS:
-            assert(op == BLE_GATT_ACCESS_OP_READ_CHR);
-            ctxt->chr_access.data = (void *)&bleprph_pref_conn_params;
-            ctxt->chr_access.len = sizeof bleprph_pref_conn_params;
-            break;
-
-        default:
-            assert(0);
-            break;
         }
 
-        return 0;
-    }
+    /* Unknown characteristic; the nimble stack should not have called this
+     * function.
+     */
+    assert(0);
+    return BLE_ATT_ERR_UNLIKELY;
+}
 
 After you've taken a moment to examine the structure of this function,
 let's explore some details.
@@ -107,8 +108,8 @@ Function signature
 .. code:: c
 
     static int
-    gatt_svr_chr_access_gap(uint16_t conn_handle, uint16_t attr_handle, uint8_t op,
-                            union ble_gatt_access_ctxt *ctxt, void *arg)
+    gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
+                                 struct ble_gatt_access_ctxt *ctxt, void *arg)
 
 A characteristic access function always takes this same set of
 parameters and always returns an int. The parameters to this function
@@ -141,17 +142,6 @@ type are documented below.
 |                |              | a UUID     |
 |                |              | lookup.    |
 +----------------+--------------+------------+
-| op             | Indicates    | Valid      |
-|                | whether this | values     |
-|                | is a read or | are:\ *BLE |
-|                | write        | \_GATT\_AC |
-|                | operation    | CESS\_OP\_ |
-|                |              | READ\_CHR* |
-|                |              | \ \ *BLE\_ |
-|                |              | GATT\_ACCE |
-|                |              | SS\_OP\_WR |
-|                |              | ITE\_CHR*  |
-+----------------+--------------+------------+
 | ctxt           | Contains the | For        |
 |                | characterist | characteri |
 |                | ic           | stic       |
@@ -181,18 +171,11 @@ Determine characteristic being accessed
 
 .. code:: c
 
-    {
-        uint16_t uuid16;
-
-        uuid16 = ble_uuid_128_to_16(ctxt->chr_access.chr->uuid128);
-        assert(uuid16 != 0);
-
-        switch (uuid16) {
-            // [...]
+    ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_rand_uuid.u)
 
-This function uses the UUID to determine which characteristic is being
-accessed. There are two alternative methods *bleprph* could have used to
-accomplish this task:
+The function compares UUID with UUIDs of characteristic - if it fits,
+characteristic is being accessed. There are two alternative methods *bleprph*
+could have used to accomplish this task:
 
 -  Map characteristics to ATT handles during service registration; use
    the *attr\_handle* parameter as a key into this table during
@@ -200,87 +183,64 @@ accomplish this task:
 -  Implement a dedicated function for each characteristic; each function
    inherently knows which characteristic it corresponds to.
 
-All the GAP service characteristics have 16-bit UUIDs, so this function
-uses the *ble\_uuid\_128\_to\_16()* function to convert the 128-bit UUID
-to its corresponding 16-bit UUID. This conversion function returns the
-corresponding 16-bit UUID on success, or 0 on failure. Success is
-asserted here to ensure the NimBLE stack is doing its job properly; the
-stack should only call this function for accesses to characteristics
-that it is registered with, and all GAP service characteristics have
-valid 16-bit UUIDs.
-
 Read access
 ^^^^^^^^^^^
 
 .. code:: c
 
-        case BLE_GAP_CHR_UUID16_DEVICE_NAME:
-            assert(op == BLE_GATT_ACCESS_OP_READ_CHR);
-            ctxt->chr_access.data = (void *)bleprph_device_name;
-            ctxt->chr_access.len = strlen(bleprph_device_name);
-            break;
+        case BLE_GATT_ACCESS_OP_READ_CHR:
+            rc = os_mbuf_append(ctxt->om, &gatt_svr_sec_test_static_val,
+                                sizeof gatt_svr_sec_test_static_val);
+            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
+
 
-This code excerpt handles read accesses to the device name
-characteristic. The *assert()* here is another case of making sure the
+This code excerpt handles read accesses to the device characteristic.
+*ctxt->om* is chained memory buffer that for reads is being populated
+with characteristic data. Returned value is either 0 for success or
+*BLE_ATT_ERR_INSUFFICIENT_RES* if failed. The check makes sure the
 NimBLE stack is doing its job; this characteristic was registered as
 read-only, so the stack should have prevented write accesses.
 
-To fulfill a characteristic read request, the application needs to
-assign the *ctxt->chr\_access.data* field to point to the attribute data
-to respond with, and fill the *ctxt->chr\_access.len* field with the
-length of the attribute data. *bleprph* stores the device name in
-read-only memory as follows:
-
-.. code:: c
-
-    const char *bleprph_device_name = "nimble-bleprph";
-
-The cast to pointer-to-void is a necessary annoyance to remove the
-*const* qualifier from the device name variable. You will need to "cast
-away const" whenever you respond to read requests with read-only data.
-
-It is not shown in the above snippet, but this function ultimately
-returns 0. By returning 0, *bleprph* indicates that the characteristic
-data in *ctxt->chr\_access* is valid and that NimBLE should include it
-in its response to the peer.
-
-**A word of warning:** The attribute data that *ctxt->chr\_access.data*
-points to must remain valid after the access function returns, as the
-NimBLE stack needs to use it to form a GATT read response. In other
-words, you must not allocate the characteristic value data on the stack
-of the access function. Two characteristic accesses never occur at the
-same time, so it is OK to use the same memory for repeated accesses.
-
 Write access
 ^^^^^^^^^^^^
 
 .. code:: c
+    
+    static int
+    gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len,
+                       void *dst, uint16_t *len)
+    {
+        uint16_t om_len;
+        int rc;
 
-        case BLE_GAP_CHR_UUID16_RECONNECT_ADDR:
-            assert(op == BLE_GATT_ACCESS_OP_WRITE_CHR);
-            if (ctxt->chr_access.len != sizeof bleprph_reconnect_addr) {
-                return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
-            }
-            memcpy(bleprph_reconnect_addr, ctxt->chr_access.data,
-                   sizeof bleprph_reconnect_addr);
-            break;
+        om_len = OS_MBUF_PKTLEN(om);
+        if (om_len < min_len || om_len > max_len) {
+            return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
+        }
 
-This code excerpt handles writes to the reconnect address
-characteristic. This characteristic was registered as write-only, so the
-*assert()* here is just a safety precaution to ensure the NimBLE stack
+        rc = ble_hs_mbuf_to_flat(om, dst, max_len, len);
+        if (rc != 0) {
+            return BLE_ATT_ERR_UNLIKELY;
+        }
+
+        return 0;
+    }
+    // [...]
+    case BLE_GATT_ACCESS_OP_WRITE_CHR:
+        rc = gatt_svr_chr_write(ctxt->om,
+                                sizeof gatt_svr_sec_test_static_val,
+                                sizeof gatt_svr_sec_test_static_val,
+                                &gatt_svr_sec_test_static_val, NULL);
+        return rc;
+
+This code excerpt handles writes to the Static value
+characteristic. This characteristic was registered as read-write, so the
+*return rc* here is just a safety precaution to ensure the NimBLE stack
 is doing its job.
 
-For writes, the roles of the *ctxt->chr\_access.data* and
-*ctxt->chr\_access.len* fields are the reverse of the read case. The
-NimBLE stack uses these fields to indicate the data written by the peer.
+Data is written to the *ctxt->om* buffer from *gatt_svr_sec_test_static_val*
+by ``ble_hs_mbuf_to_flat()`` function. If length of written data greater or 
+smaller than length of *gatt_svr_sec_test_static_val*, function return error.
 
 Many characteristics have strict length requirements for write
-operations. This characteristic has such a restriction; if the written
-data is not a 48-bit BR address, the application tells NimBLE to respond
-with an invalid attribute value length error.
-
-For writes, the *ctxt->chr\_access.data* pointer is only valid for the
-duration of the access function. If the application needs to save the
-written data, it should store it elsewhere before the function returns.
-In this case, *bleprph* stores the specified address in a global
-variable called *bleprph\_reconnect\_addr*.
+operations.
\ No newline at end of file
diff --git a/docs/tutorials/ble/bleprph/bleprph.rst b/docs/tutorials/ble/bleprph/bleprph.rst
index 0295535..84b37aa 100644
--- a/docs/tutorials/ble/bleprph/bleprph.rst
+++ b/docs/tutorials/ble/bleprph/bleprph.rst
@@ -20,7 +20,7 @@ Introduction
 Overview
 ^^^^^^^^
 
-*bleprph* is an example app included in the apache-mynewt-core
+*bleprph* is an example app included in the apache-mynewt-nimble
 repository. This app implements a simple BLE peripheral with the
 following properties: