BLE iBeacon
-----------

This tutorial guides you through the process of creating an iBeacon
application using NimBLE and Mynewt. At the conclusion of this tutorial,
you will have a fully functional iBeacon app.

.. contents::
  :local:
  :depth: 2

iBeacon Protocol
~~~~~~~~~~~~~~~~

A beaconing device announces its presence to the world by broadcasting
advertisements. The iBeacon protocol is built on top of the standard BLE
advertisement specification. `This
page <http://www.warski.org/blog/2014/01/how-ibeacons-work/>`__ provides
a good summary of the iBeacon sub-fields.

Create an Empty BLE Application
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This tutorial picks up where the :doc:`BLE bare bones application
tutorial <../ble_bare_bones>` document concludes.
The first step in creating a beaconing device is to create an empty BLE
app, as explained in that tutorial. Before proceeding, you should have:

-  An app called "ble\_app".
-  A target called "ble\_tgt".
-  Successfully executed the app on your target device.

Add beaconing
~~~~~~~~~~~~~

Here is a brief specification of how we want our beaconing app to
behave:

1. Wait until the host and controller are in sync.
2. Configure the NimBLE stack with an address to put in its
   advertisements.
3. Advertise indefinitely.

Let's take these one at a time.

1. Wait for host-controller sync
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


The first step, waiting for host-controller-sync, is mandatory in all
BLE applications. The NimBLE stack is inoperable while the two
components are out of sync. In a combined host-controller app, the sync
happens immediately at startup. When the host and controller are
separate, sync typically occurs in less than a second.

We achieve this by configuring the NimBLE host with a callback function
that gets called when sync takes place:

.. code-block:: console
    :emphasize-lines: 1,2,3,5,6,8,9,10,11,13,14,15,22 
    
    static
    void ble_app_set_addr() 
    { }
    
    static void ble_app_advertise(); 
    { }
    
    static void ble_app_on_sync(void) 
    { 
        /* Generate a non-resolvable private address. */ 
        ble_app_set_addr();
  
        /* Advertise indefinitely. */
        ble_app_advertise();
    }
    
    int 
    main(int argc, char \*\*argv) 
    {
        sysinit();
    
        ble_hs_cfg.sync_cb = ble_app_on_sync;
    
        /* As the last thing, process events from default event queue. */
        while (1) {
        os_eventq_run(os_eventq_dflt_get());
        }
    } 

``ble_hs_cfg.sync_cb`` points to the function that should be called when
sync occurs. Our callback function, ``ble_app_on_sync()``, kicks off the
control flow that we specified above. Now we need to fill in the two
stub functions.

2. Configure the NimBLE stack with an address
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


A BLE device needs an address to do just about anything. Some devices
have a public Bluetooth address burned into them, but this is not always
the case. Furthermore, the NimBLE controller might not know how to read
an address out of your particular hardware. For a beaconing device, we
generally don't care what address gets used since nothing will be
connecting to us.

A reliable solution is to generate a *non-resolvable private address*
(nRPA) each time the application runs. Such an address contains no
identifying information, and they are expected to change frequently.

.. code-block:: console
    :emphasize-lines: 4,5,6,7,8,9,10,11
    
    static void
    ble_app_set_addr(void)
    {
        ble_addr_t addr;
        int rc;
    
        rc = ble_hs_id_gen_rnd(1, &addr);
        assert(rc == 0);
    
        rc = ble_hs_id_set_rnd(addr.val);
        assert(rc == 0);
    }
    
    static void
    ble_app_advertise();
    { }
    
    static void
    ble_app_on_sync(void)
    {
        /* Generate a non-resolvable private address. */
        ble_app_set_addr();
    
        /* Advertise indefinitely. */
        ble_app_advertise();
    }


Our new function, ``ble_app_set_addr()``, makes two calls into the stack:

-  ``ble_hs_id_gen_rnd``: Generate an nRPA.
-  ``ble_hs_id_set_rnd``: Configure NimBLE to use the newly-generated address.

You can click either of the function names for more detailed
documentation.

3. Advertise indefinitely
^^^^^^^^^^^^^^^^^^^^^^^^^


The first step in advertising is to configure the host with advertising
data. This operation tells the host what data to use for the contents of
its advertisements. The NimBLE host provides a special helper function
for configuring iBeacon advertisement data:
``ble_ibeacon_set_adv_data`` 

If you follow the API link, you'll see that this function takes four
parameters: a 128-bit UUID, a major version,a minor version, and a RSSI value. This
corresponds with the iBeacon specification, as these three items are the
primary components in an iBeacon advertisement.

For now, we'll advertise the following:

-  *UUID*: ``11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11``
-  *Major*: 2
-  *Minor*: 10

.. code:: c

    static void
    ble_app_advertise(void)
    {
        uint8_t uuid128[16];
        int rc;

        /* Fill the UUID buffer with a string of 0x11 bytes. */
        memset(uuid128, 0x11, sizeof uuid128);

        /* Major version=2; minor version=10. */
        rc = ble_ibeacon_set_adv_data(uuid128, 2, 10, 0);
        assert(rc == 0);

        /* TODO: Begin advertising. */
    }

Now that the host knows what to advertise, the next step is to actually
begin advertising. The function to initiate advertising is:
``ble_gap_adv_start``.
This function takes several parameters. For simplicity, we reproduce the
function prototype here:

.. code:: c
    
    int
    ble_gap_adv_start(
                                uint8_t  own_addr_type,
                       const ble_addr_t *direct_addr,
                                int32_t  duration_ms,
        const struct ble_gap_adv_params *adv_params,
                       ble_gap_event_fn *cb,
                                   void *cb_arg
    )

This function gives an application quite a bit of freedom in how
advertising is to be done. The default values are mostly fine for our
simple beaconing application. We will pass the following values to this
function:

+--------------+----------+----------+
| Parameter    | Value    | Notes    |
+==============+==========+==========+
| own\_addr\_t | BLE\_OWN | Use the  |
| ype          | \_ADDR\_ | nRPA we  |
|              | RANDOM   | generate |
|              |          | d        |
|              |          | earlier. |
+--------------+----------+----------+
| direct\_addr | NULL     | We are   |
|              |          | broadcas |
|              |          | ting,    |
|              |          | not      |
|              |          | targetin |
|              |          | g        |
|              |          | a peer.  |
+--------------+----------+----------+
| duration\_ms | BLE\_HS\ | Advertis |
|              | _FOREVER | e        |
|              |          | indefini |
|              |          | tely.    |
+--------------+----------+----------+
| adv\_params  | defaults | Can be   |
|              |          | used to  |
|              |          | specify  |
|              |          | low      |
|              |          | level    |
|              |          | advertis |
|              |          | ing      |
|              |          | paramete |
|              |          | rs.      |
+--------------+----------+----------+
| cb           | NULL     | We are   |
|              |          | non-conn |
|              |          | ectable, |
|              |          | so no    |
|              |          | need for |
|              |          | an event |
|              |          | callback |
|              |          | .        |
+--------------+----------+----------+
| cb\_arg      | NULL     | No       |
|              |          | callback |
|              |          | implies  |
|              |          | no       |
|              |          | callback |
|              |          | argument |
|              |          | .        |
+--------------+----------+----------+

These arguments are mostly self-explanatory. The exception is
``adv_params``, which can be used to specify a number of low-level
parameters. For a beaconing application, the default settings are
appropriate. We specify default settings by providing a zero-filled
instance of the ``ble_gap_adv_params`` struct as our argument.

.. code-block:: console
    :emphasize-lines: 4,15,16,17,18,19
    
    static void
    ble_app_advertise(void) 
    { 
        struct ble_gap_adv_params adv_params;
        uint8_t uuid128[16]; 
        int rc;

        /* Arbitrarily set the UUID to a string of 0x11 bytes. */
        memset(uuid128, 0x11, sizeof uuid128);
    
        /* Major version=2; minor version=10. */
        rc = ble_ibeacon_set_adv_data(uuid128, 2, 10, 0);
        assert(rc == 0);
    
        /* Begin advertising. */
        adv_params = (struct ble_gap_adv_params){ 0 };
        rc = ble_gap_adv_start(BLE_OWN_ADDR_RANDOM, NULL, BLE_HS_FOREVER,
                           &adv_params, NULL, NULL);
        assert(rc == 0);
    
    }

Conclusion
~~~~~~~~~~

That's it! Now when you run this app on your board, you should be able
to see it with all your iBeacon-aware devices. You can test it out with
the ``newt run`` command.

Source Listing
~~~~~~~~~~~~~~

For reference, here is the complete application source:

.. code:: c

    #include "sysinit/sysinit.h"
    #include "os/os.h"
    #include "console/console.h"
    #include "host/ble_hs.h"

    static void
    ble_app_set_addr(void)
    {
        ble_addr_t addr;
        int rc;

        rc = ble_hs_id_gen_rnd(1, &addr);
        assert(rc == 0);

        rc = ble_hs_id_set_rnd(addr.val);
        assert(rc == 0);
    }

    static void
    ble_app_advertise(void)
    {
        struct ble_gap_adv_params adv_params;
        uint8_t uuid128[16];
        int rc;

        /* Arbitrarily set the UUID to a string of 0x11 bytes. */
        memset(uuid128, 0x11, sizeof uuid128);

        /* Major version=2; minor version=10. */
        rc = ble_ibeacon_set_adv_data(uuid128, 2, 10, 0);
        assert(rc == 0);

        /* Begin advertising. */
        adv_params = (struct ble_gap_adv_params){ 0 };
        rc = ble_gap_adv_start(BLE_OWN_ADDR_RANDOM, NULL, BLE_HS_FOREVER,
                               &adv_params, NULL, NULL);
        assert(rc == 0);
    }

    static void
    ble_app_on_sync(void)
    {
        /* Generate a non-resolvable private address. */
        ble_app_set_addr();

        /* Advertise indefinitely. */
        ble_app_advertise();
    }

    int
    main(int argc, char **argv)
    {
        sysinit();

        ble_hs_cfg.sync_cb = ble_app_on_sync;

        /* As the last thing, process events from default event queue. */
        while (1) {
            os_eventq_run(os_eventq_dflt_get());
        }
    }
