blob: ce43cef850f9408177787246423a26f71173aed7 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BLE Eddystone &mdash; Apache Mynewt latest documentation</title>
<link rel="shortcut icon" href="../../_static/mynewt-logo-only-newt32x32.png"/>
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/sphinx_theme.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/bootstrap-3.0.3.min.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/v2.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/custom.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/restructuredtext.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/overrides.css" type="text/css" />
<link rel="index" title="Index"
href="../../genindex.html"/>
<link rel="search" title="Search" href="../../search.html"/>
<link rel="top" title="Apache Mynewt latest documentation" href="../../index.html"/>
<link rel="up" title="Bluetooth Low Energy" href="ble.html"/>
<link rel="next" title="BLE Peripheral Project" href="bleprph/bleprph.html"/>
<link rel="prev" title="BLE iBeacon" href="ibeacon.html"/>
<script src="../../_static/js/modernizr.min.js"></script>
<script>
(function(i, s, o, g, r, a, m) {
i["GoogleAnalyticsObject"] = r;
(i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "//www.google-analytics.com/analytics.js", "ga");
ga("create", "UA-72162311-1", "auto");
ga("send", "pageview");
</script>
</head>
<body class="not-front page-documentation" role="document" >
<div id="wrapper">
<div class="container">
<div id="banner" class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="../../_static/img/logo.png">
</a>
<div class="tagline-cell">
<h4 class="tagline">An OS to build, deploy and securely manage billions of devices</h4>
</div>
<div class="news-cell">
<div class="well">
<h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.11.0, Apache NimBLE 1.6.0 </a> released September 7, 2023)
</div>
</div>
</div>
</div>
<header>
<nav id="navbar" class="navbar navbar-inverse" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav navbar-right">
<li>
<a href="/"><i class="fa fa-home" style="font-size: larger;"></i></a>
</li>
<li class="important">
<a href="/quick-start/">Quick Start</a>
</li>
<li>
<a href="/about/">About</a>
</li>
<li>
<a href="/talks/">Talks</a>
</li>
<li class="active">
<a href="/documentation/">Documentation</a>
</li>
<li>
<a href="/download/">Download</a>
</li>
<li>
<a href="/community/">Community</a>
</li>
<li>
<a href="/events/">Events</a>
</li>
</ul>
<!-- Search, Navigation and Repo links -->
<ul class="nav navbar-nav navbar-right">
</ul>
</div>
</div>
</nav>
</header>
<!-- STARTS MAIN CONTENT -->
<div id="main-content">
<div id="breadcrumb">
<div class="container">
<a href="/documentation/">Docs</a> /
<a href="../tutorials.html">Tutorials</a> /
<a href="ble.html">Bluetooth Low Energy</a> /
BLE Eddystone
<div class="sourcelink">
<a href="https://github.com/apache/mynewt-documentation/edit/master/docs/tutorials/ble/eddystone.rst" class="icon icon-github"
rel="nofollow"> Edit on GitHub</a>
</div>
</div>
</div>
<!-- STARTS CONTAINER -->
<div class="container">
<!-- STARTS .content -->
<div id="content" class="row">
<!-- STARTS .container-sidebar -->
<div class="container-sidebar col-xs-12 col-sm-3">
<div id="docSidebar" class="sticky-container">
<div role="search" class="sphinx-search">
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
<input type="text" name="q" placeholder="Search documentation" class="search-documentation" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<!-- Note: only works when deployed -->
<select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest" selected>
Version: latest
</option>
<option value="/v1_11_0" >
Version: 1.11.0
</option>
<option value="/v1_10_0" >
Version: 1.10.0
</option>
<option value="/v1_9_0" >
Version: 1.9.0
</option>
<option value="/v1_8_0" >
Version: 1.8.0
</option>
<option value="/v1_7_0" >
Version: 1.7.0
</option>
<option value="/v1_6_0" selected="selected" >
Version: 1.6.0
</option>
<option value="/v1_5_0" >
Version: 1.5.0
</option>
<option value="/v1_4_0" >
Version: 1.4.0
</option>
<option value="/v1_3_0/os/introduction" >
Version: 1.3.0
</option>
<option value="/v1_2_0/os/introduction" >
Version: 1.2.0
</option>
<option value="/v1_1_0/os/introduction" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" >
Version: 0.9.0
</option>
</select>
<div class="region region-sidebar">
<div class="docs-menu">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../index.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../get_started/index.html">Setup &amp; Get Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../concepts.html">Concepts</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../tutorials.html">Tutorials</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../blinky/blinky.html">Project Blinky</a></li>
<li class="toctree-l2"><a class="reference internal" href="../repo/add_repos.html">Working with repositories</a></li>
<li class="toctree-l2"><a class="reference internal" href="../slinky/project-slinky.html">Project Slinky for Remote Comms</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="ble.html">Bluetooth Low Energy</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="ble_bare_bones.html">Set up a bare bones NimBLE application</a></li>
<li class="toctree-l3"><a class="reference internal" href="ibeacon.html">BLE iBeacon</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">BLE Eddystone</a></li>
<li class="toctree-l3"><a class="reference internal" href="bleprph/bleprph.html">BLE Peripheral Project</a></li>
<li class="toctree-l3"><a class="reference internal" href="blehci_project.html">Use HCI access to NimBLE controller</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../lora/lorawanapp.html">LoRa</a></li>
<li class="toctree-l2"><a class="reference internal" href="../os_fundamentals/os_fundamentals.html">OS Fundamentals</a></li>
<li class="toctree-l2"><a class="reference internal" href="../devmgmt/devmgmt.html">Remote Device Management</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sensors/sensors.html">Sensors</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tooling/tooling.html">Tooling</a></li>
<li class="toctree-l2"><a class="reference internal" href="../other/other.html">Other</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../external_links.html">Third-party Resources</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../os/os_user_guide.html">OS User Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../network/index.html">BLE User Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../newt/index.html">Newt Tool Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../newtmgr/index.html">Newt Manager Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../mynewt_faq/index.html">Mynewt FAQ</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../misc/index.html">Appendix</a></li>
</ul>
</div>
</div>
</div>
<!-- ENDS STICKY CONTAINER -->
</div>
<!-- ENDS .container-sidebar -->
<div class="col-xs-12 col-sm-9">
<div class="alert alert-warning">
<p>
Version 1.6.0 is not the most recent version of the
Apache Mynewt documentation. Click <a href="/latest">here</a> to
read the latest version.
</p>
</div>
<div class="">
<div class="rst-content">
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="ble-eddystone">
<h1>BLE Eddystone<a class="headerlink" href="#ble-eddystone" title="Permalink to this headline"></a></h1>
<div class="section" id="eddystone-beacon-protocol">
<h2>Eddystone Beacon Protocol<a class="headerlink" href="#eddystone-beacon-protocol" title="Permalink to this headline"></a></h2>
<p>A beaconing device announces its presence to the world by broadcasting
advertisements. The Eddystone protocol is built on top of the standard
BLE advertisement specification. Eddystone supports multiple data packet
types:</p>
<ul class="simple">
<li><p>Eddystone-UID: a unique, static ID with a 10-byte Namespace component
and a 6-byte Instance component.</p></li>
<li><p>Eddystone-URL: a compressed URL that, once parsed and decompressed,
is directly usable by the client.</p></li>
<li><p>Eddystone-TLM: “telemetry” packets that are broadcast alongside the
Eddystone-UID or Eddystone-URL packets and contains beacon’s “health
status” (e.g., battery life).</p></li>
<li><p>Eddystone-EID to broadcast an ephemeral identifier that changes every
few minutes and allow only parties that can resolve the identifier to
use the beacon.</p></li>
</ul>
<p><a class="reference external" href="https://developers.google.com/beacons/eddystone">This page</a>
describes the Eddystone open beacon format developed by Google.</p>
<p>Apache Mynewt currently supports Eddystone-UID and Eddystone-URL formats
only. This tutorial will explain how to get an Eddystone-URL beacon
going on a peripheral device.</p>
</div>
<div class="section" id="create-an-empty-ble-application">
<h2>Create an Empty BLE Application<a class="headerlink" href="#create-an-empty-ble-application" title="Permalink to this headline"></a></h2>
<p>This tutorial picks up where the <span class="xref std std-doc">BLE bare bones application
tutorial</span> 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:</p>
<ul class="simple">
<li><p>An app called “ble_app”.</p></li>
<li><p>A target called “ble_tgt”.</p></li>
<li><p>Successfully executed the app on your target device.</p></li>
</ul>
</div>
<div class="section" id="add-beaconing">
<h2>Add beaconing<a class="headerlink" href="#add-beaconing" title="Permalink to this headline"></a></h2>
<p>Here is a brief specification of how we want our beaconing app to
behave:</p>
<ol class="arabic simple">
<li><p>Wait until the host and controller are in sync.</p></li>
<li><p>Configure the NimBLE stack with an address to put in its
advertisements.</p></li>
<li><p>Advertise an eddystone URL beacon indefinitely.</p></li>
</ol>
<p>Let’s take these one at a time.</p>
<div class="section" id="wait-for-host-controller-sync">
<h3>1. Wait for host-controller sync<a class="headerlink" href="#wait-for-host-controller-sync" title="Permalink to this headline"></a></h3>
<p>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.</p>
<p>We achieve this by configuring the NimBLE host with a callback function
that gets called when sync takes place:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="hll"><span class="go">static void</span>
</span><span class="hll"><span class="go">ble_app_set_addr()</span>
</span><span class="hll"><span class="go">{ }</span>
</span><span class="hll">
</span><span class="hll"><span class="go">static void</span>
</span><span class="hll"><span class="go">ble_app_advertise()</span>
</span><span class="hll"><span class="go">{ }</span>
</span><span class="hll">
</span><span class="hll"><span class="go">static void</span>
</span><span class="hll"><span class="go">ble_app_on_sync(void)</span>
</span><span class="hll"><span class="go">{</span>
</span><span class="hll"><span class="go"> /* Generate a non-resolvable private address. */</span>
</span><span class="hll"><span class="go"> ble\_app\_set\_addr();</span>
</span><span class="hll">
</span><span class="hll"><span class="go"> /* Advertise indefinitely. */</span>
</span><span class="hll"><span class="go"> ble_app_advertise();</span>
</span><span class="hll"><span class="go">}</span>
</span>
<span class="go">int</span>
<span class="go">main(int argc, char \*\*argv)</span>
<span class="go">{</span>
<span class="go"> sysinit();</span>
<span class="hll"><span class="go"> ble_hs_cfg.sync_cb = ble_app_on_sync;</span>
</span>
<span class="go"> /* As the last thing, process events from default event queue. */</span>
<span class="go"> while (1) {</span>
<span class="go"> os_eventq_run(os_eventq_dflt_get());</span>
<span class="go"> }</span>
<span class="go">}</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">ble_hs_cfg.sync_cb</span></code> points to the function that should be called when
sync occurs. Our callback function, <code class="docutils literal notranslate"><span class="pre">ble_app_on_sync()</span></code>, kicks off the
control flow that we specified above. Now we need to fill in the two
stub functions.</p>
</div>
<div class="section" id="configure-the-nimble-stack-with-an-address">
<h3>2. Configure the NimBLE stack with an address<a class="headerlink" href="#configure-the-nimble-stack-with-an-address" title="Permalink to this headline"></a></h3>
<p>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.</p>
<p>A reliable solution is to generate a <em>non-resolvable private address</em>
(nRPA) each time the application runs. Such an address contains no
identifying information, and they are expected to change frequently.</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">static void</span>
<span class="go">ble_app_set_addr(void)</span>
<span class="go">{</span>
<span class="hll"><span class="go"> ble_addr_t addr;</span>
</span><span class="hll"><span class="go"> int rc;</span>
</span><span class="hll">
</span><span class="hll"><span class="go"> rc = ble_hs_id_gen_rnd(1, &amp;addr);</span>
</span><span class="hll"><span class="go"> assert(rc == 0);</span>
</span><span class="hll">
</span><span class="hll"><span class="go"> rc = ble_hs_id_set_rnd(addr.val);</span>
</span><span class="hll"><span class="go"> assert(rc == 0);</span>
</span><span class="go">}</span>
<span class="go">static void ble_app_advertise()</span>
<span class="go">{ }</span>
<span class="go">static void ble_app_on_sync(void)</span>
<span class="go">{</span>
<span class="go"> /* Generate a non-resolvable private address. */</span>
<span class="go"> ble_app_set_addr();</span>
<span class="go"> /* Advertise indefinitely. */</span>
<span class="go"> ble_app_advertise();</span>
<span class="go">}</span>
</pre></div>
</div>
<p>Our new function, <code class="docutils literal notranslate"><span class="pre">ble_app_set_addr()</span></code>, makes two calls into the
stack:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">`ble_hs_id_gen_rnd</span></code> : Generate an nRPA.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">`ble_hs_id_set_rnd</span></code> : Configure NimBLE to use the newly-generated address.</p></li>
</ul>
<p>You can click either of the function names for more detailed
documentation.</p>
</div>
<div class="section" id="advertise-indefinitely">
<h3>3. Advertise indefinitely<a class="headerlink" href="#advertise-indefinitely" title="Permalink to this headline"></a></h3>
<p>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 special helper functions
for configuring eddystone advertisement data:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">`ble_eddystone_set_adv_data_uid</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">`ble_eddystone_set_adv_data_url</span></code></p></li>
</ul>
<p>Our application will advertise eddystone URL beacons, so we are
interested in the second function. We reproduce the function prototype
here:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span>
<span class="n">ble_eddystone_set_adv_data_url</span><span class="p">(</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">ble_hs_adv_fields</span><span class="w"> </span><span class="o">*</span><span class="n">adv_fields</span><span class="p">,</span>
<span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">url_scheme</span><span class="p">,</span>
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">url_body</span><span class="p">,</span>
<span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">url_body_len</span><span class="p">,</span>
<span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">url_suffix</span>
<span class="w"> </span><span class="kt">int8_t</span><span class="w"> </span><span class="n">measured_power</span>
<span class="p">)</span>
</pre></div>
</div>
<p>We’ll advertise the Mynewt URL: <em>https://mynewt.apache.org</em>. Eddystone
beacons use a form of URL compression to accommodate the limited space
available in Bluetooth advertisements. The <code class="docutils literal notranslate"><span class="pre">url_scheme</span></code> and
<code class="docutils literal notranslate"><span class="pre">url_suffix</span></code> fields implement this compression; they are single byte
fields which correspond to strings commonly found in URLs. The following
arguments translate to the <a class="reference external" href="https://mynewt.apache.org">https://mynewt.apache.org</a> URL:</p>
<table class="docutils align-default">
<colgroup>
<col style="width: 28%" />
<col style="width: 72%" />
</colgroup>
<thead>
<tr class="row-odd"><th class="head"><p>Parameter</p></th>
<th class="head"><p>Value</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>url_scheme</p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">BLE_EDDYSTONE_URL_SCHEME_HTTPS</span></code></p></td>
</tr>
<tr class="row-odd"><td><p>url_body</p></td>
<td><p>“mynewt.apache”</p></td>
</tr>
<tr class="row-even"><td><p>url_suffix</p></td>
<td><p><code class="docutils literal notranslate"><span class="pre">BLE_EDDYSTONE_URL_SUFFIX_ORG</span></code></p></td>
</tr>
</tbody>
</table>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="kt">void</span>
<span class="nf">ble_app_advertise</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">ble_hs_adv_fields</span><span class="w"> </span><span class="n">fields</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rc</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Configure an eddystone URL beacon to be advertised;</span>
<span class="cm"> * URL: https://apache.mynewt.org</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="n">fields</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">ble_hs_adv_fields</span><span class="p">){</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">};</span>
<span class="w"> </span><span class="n">rc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ble_eddystone_set_adv_data_url</span><span class="p">(</span><span class="o">&amp;</span><span class="n">fields</span><span class="p">,</span>
<span class="w"> </span><span class="n">BLE_EDDYSTONE_URL_SCHEME_HTTPS</span><span class="p">,</span>
<span class="w"> </span><span class="s">&quot;mynewt.apache&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="mi">13</span><span class="p">,</span>
<span class="w"> </span><span class="n">BLE_EDDYSTONE_URL_SUFFIX_ORG</span><span class="p">,</span>
<span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">rc</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* TODO: Begin advertising. */</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Now that the host knows what to advertise, the next step is to actually
begin advertising. The function to initiate advertising is:
<code class="docutils literal notranslate"><span class="pre">`ble_gap_adv_start</span></code>.
This function takes several parameters. For simplicity, we reproduce the
function prototype here:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="kt">int</span>
<span class="n">ble_gap_adv_start</span><span class="p">(</span>
<span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">own_addr_type</span><span class="p">,</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">ble_addr_t</span><span class="w"> </span><span class="o">*</span><span class="n">direct_addr</span><span class="p">,</span>
<span class="w"> </span><span class="kt">int32_t</span><span class="w"> </span><span class="n">duration_ms</span><span class="p">,</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">ble_gap_adv_params</span><span class="w"> </span><span class="o">*</span><span class="n">adv_params</span><span class="p">,</span>
<span class="w"> </span><span class="n">ble_gap_event_fn</span><span class="w"> </span><span class="o">*</span><span class="n">cb</span><span class="p">,</span>
<span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">cb_arg</span>
<span class="p">)</span>
</pre></div>
</div>
<p>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:</p>
<table class="docutils align-default">
<colgroup>
<col style="width: 28%" />
<col style="width: 39%" />
<col style="width: 33%" />
</colgroup>
<thead>
<tr class="row-odd"><th class="head"><p>Parameter</p></th>
<th class="head"><p>Value</p></th>
<th class="head"><p>Notes</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>own_addr_type</p></td>
<td><p>BLE_OWN_ADDR_RANDOM</p></td>
<td><p>Use the nRPA we
generated earlier.</p></td>
</tr>
<tr class="row-odd"><td><p>direct_addr</p></td>
<td><p>NULL</p></td>
<td><p>We are
broadcasting, not
targeting a peer.</p></td>
</tr>
<tr class="row-even"><td><p>duration_ms</p></td>
<td><p>BLE_HS_FOREVER</p></td>
<td><p>Advertise
indefinitely.</p></td>
</tr>
<tr class="row-odd"><td><p>adv_params</p></td>
<td><p>defaults</p></td>
<td><p>Can be used to
specify low level
advertising
parameters.</p></td>
</tr>
<tr class="row-even"><td><p>cb</p></td>
<td><p>NULL</p></td>
<td><p>We are
non-connectable,
so no need for an
event callback.</p></td>
</tr>
<tr class="row-odd"><td><p>cb_arg</p></td>
<td><p>NULL</p></td>
<td><p>No callback
implies no
callback argument.</p></td>
</tr>
</tbody>
</table>
<p>These arguments are mostly self-explanatory. The exception is
<code class="docutils literal notranslate"><span class="pre">adv_params</span></code>, 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 <code class="docutils literal notranslate"><span class="pre">ble_gap_adv_params</span></code> struct as our argument.</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">static void</span>
<span class="go">ble_app_advertise(void)</span>
<span class="go">{</span>
<span class="hll"><span class="go"> struct ble_gap_adv_params adv_params;</span>
</span><span class="go"> struct ble_hs_adv_fields fields; int rc;</span>
<span class="go"> /* Configure an eddystone URL beacon to be advertised;</span>
<span class="go"> * URL: https://apache.mynewt.org</span>
<span class="go"> */</span>
<span class="go"> fields = (struct ble_hs_adv_fields){ 0 };</span>
<span class="go"> rc = ble_eddystone_set_adv_data_url(&amp;fields,</span>
<span class="go"> BLE_EDDYSTONE_URL_SCHEME_HTTPS,</span>
<span class="go"> &quot;mynewt.apache&quot;,</span>
<span class="go"> 13,</span>
<span class="go"> BLE_EDDYSTONE_URL_SUFFIX_ORG,</span>
<span class="go"> 0);</span>
<span class="go"> assert(rc == 0);</span>
<span class="hll"><span class="go"> /* Begin advertising. */</span>
</span><span class="hll"><span class="go"> adv_params = (struct ble_gap_adv_params){ 0 };</span>
</span><span class="hll"><span class="go"> rc = ble_gap_adv_start(BLE_OWN_ADDR_RANDOM, NULL, BLE_HS_FOREVER,</span>
</span><span class="hll"><span class="go"> &amp;adv_params, NULL, NULL);</span>
</span><span class="hll"><span class="go"> assert(rc == 0);</span>
</span><span class="go">}</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="conclusion">
<h2>Conclusion<a class="headerlink" href="#conclusion" title="Permalink to this headline"></a></h2>
<p>That’s it! Now when you run this app on your board, you should be able
to see it with all your eddystone-aware devices. You can test it out
with the <code class="docutils literal notranslate"><span class="pre">newt</span> <span class="pre">run</span></code> command.</p>
</div>
<div class="section" id="source-listing">
<h2>Source Listing<a class="headerlink" href="#source-listing" title="Permalink to this headline"></a></h2>
<p>For reference, here is the complete application source:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&quot;sysinit/sysinit.h&quot;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&quot;os/os.h&quot;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&quot;console/console.h&quot;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&quot;host/ble_hs.h&quot;</span>
<span class="k">static</span><span class="w"> </span><span class="kt">void</span>
<span class="nf">ble_app_set_addr</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">ble_addr_t</span><span class="w"> </span><span class="n">addr</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rc</span><span class="p">;</span>
<span class="w"> </span><span class="n">rc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ble_hs_id_gen_rnd</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">addr</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">rc</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="w"> </span><span class="n">rc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ble_hs_id_set_rnd</span><span class="p">(</span><span class="n">addr</span><span class="p">.</span><span class="n">val</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">rc</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">static</span><span class="w"> </span><span class="kt">void</span>
<span class="nf">ble_app_advertise</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">ble_gap_adv_params</span><span class="w"> </span><span class="n">adv_params</span><span class="p">;</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">ble_hs_adv_fields</span><span class="w"> </span><span class="n">fields</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rc</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Configure an eddystone URL beacon to be advertised;</span>
<span class="cm"> * URL: https://apache.mynewt.org</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="n">fields</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">ble_hs_adv_fields</span><span class="p">){</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">};</span>
<span class="w"> </span><span class="n">rc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ble_eddystone_set_adv_data_url</span><span class="p">(</span><span class="o">&amp;</span><span class="n">fields</span><span class="p">,</span>
<span class="w"> </span><span class="n">BLE_EDDYSTONE_URL_SCHEME_HTTPS</span><span class="p">,</span>
<span class="w"> </span><span class="s">&quot;mynewt.apache&quot;</span><span class="p">,</span>
<span class="w"> </span><span class="mi">13</span><span class="p">,</span>
<span class="w"> </span><span class="n">BLE_EDDYSTONE_URL_SUFFIX_ORG</span><span class="p">,</span>
<span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">rc</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* Begin advertising. */</span>
<span class="w"> </span><span class="n">adv_params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">ble_gap_adv_params</span><span class="p">){</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">};</span>
<span class="w"> </span><span class="n">rc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ble_gap_adv_start</span><span class="p">(</span><span class="n">BLE_OWN_ADDR_RANDOM</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="n">BLE_HS_FOREVER</span><span class="p">,</span>
<span class="w"> </span><span class="o">&amp;</span><span class="n">adv_params</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">);</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">rc</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">static</span><span class="w"> </span><span class="kt">void</span>
<span class="nf">ble_app_on_sync</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="cm">/* Generate a non-resolvable private address. */</span>
<span class="w"> </span><span class="n">ble_app_set_addr</span><span class="p">();</span>
<span class="w"> </span><span class="cm">/* Advertise indefinitely. */</span>
<span class="w"> </span><span class="n">ble_app_advertise</span><span class="p">();</span>
<span class="p">}</span>
<span class="kt">int</span>
<span class="nf">main</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">**</span><span class="n">argv</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">sysinit</span><span class="p">();</span>
<span class="w"> </span><span class="n">ble_hs_cfg</span><span class="p">.</span><span class="n">sync_cb</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ble_app_on_sync</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* As the last thing, process events from default event queue. */</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">os_eventq_run</span><span class="p">(</span><span class="n">os_eventq_dflt_get</span><span class="p">());</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
<div class="rst-footer-buttons row" role="navigation" aria-label="footer navigation">
<a href="bleprph/bleprph.html" class="btn btn-neutral float-right" title="BLE Peripheral Project" accesskey="n">Next: BLE Peripheral Project <span class="fa fa-arrow-circle-right"></span></a>
<a href="ibeacon.html" class="btn btn-neutral" title="BLE iBeacon" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous: BLE iBeacon</a>
</div>
</div>
</div>
</div>
<!-- ENDS CONTENT SECTION -->
</div>
<!-- ENDS .content -->
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-xs-12">
<p class="copyright">Apache Mynewt is available under Apache License, version 2.0.</p>
</div>
<div class="col-xs-12">
<div class="logos">
<img src="../../_static/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
<small class="footnote">
Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt project logo are either
registered trademarks or trademarks of the Apache Software Foundation in the United States and other countries.
</small>
<a href="">
<img src="../../_static/img/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
</div>
</div>
</footer>
</div>
<!-- ENDS #wrapper -->
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT:'../../',
VERSION:'latest',
COLLAPSE_INDEX:false,
FILE_SUFFIX:'.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
LINK_SUFFIX: '.html'
};
</script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="../../_static/js/bootstrap-3.0.3.min.js"></script>
<script type="text/javascript" src="../../_static/js/affix.js"></script>
<script type="text/javascript" src="../../_static/js/main.js"></script>
</body>
</html>