blob: 94b0a28c53e39c13d061643568a81b5ce17c09f8 [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">
<!-- This is broken by doc revisioning.
-->
<link rel="shortcut icon" href="../../../img/favicon.ico">
<title>BLE Eddystone - Apache Mynewt</title>
<link href="../../../css/bootstrap-3.0.3.min.css" rel="stylesheet">
<link rel="stylesheet" href="../../../css/highlight.css">
<link href="../../../css/base.css" rel="stylesheet">
<link href="../../../css/custom.css" rel="stylesheet">
<link href="../../../css/v2.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<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="BLE Eddystone">
<div class="container">
<div class="row v2-main-banner">
<a class="logo-cell" href="/">
<img class="logo" src="/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>
<nav id="navbar" class="navbar navbar-inverse affix-top" data-spy="affix" data-offset-top="150" 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
class=""
>
<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
class=""
>
<a href="/about/">About</a>
</li>
<li
class=""
>
<a href="/talks/">Talks</a>
</li>
<li
class="active"
>
<a href="/documentation/">Documentation</a>
</li>
<li
class=""
>
<a href="/download/">Download</a>
</li>
<li
class=""
>
<a href="/community/">Community</a>
</li>
<li
class=""
>
<a href="/events/">Events</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-md-3 v2-sidebar sidebar-container"><div id="docSidebar" class="hidden-print" role="complementary">
<div class="top">
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
<div class="form-group">
<input type="text" name="q" class="form-control" placeholder="Search documentation" />
</div>
</form>
</div>
</div>
<ul class="toc-nav">
<li class="doc-version"><select class="form-control" onchange="if (this.value) window.location.href=this.value">
<option value="/latest">
Version: master
</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/" >
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" selected="selected" >
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></li>
<li ><a href="../../introduction/">Mynewt Documentation</a>
<ul>
<li ><a href="../../get_started/get_started/">Basic Setup</a>
</li>
<li >
<a href="../../get_started/vocabulary/">Concepts</a>
</li>
<li ><a href="../tutorials/">Tutorials</a>
<ul>
<li ><a href="../blinky/">Project Blinky</a>
</li>
<li ><a href="../repo/add_repos/">Work with repositories</a>
</li>
<li ><a href="../project-slinky/">Project Slinky for Remote Comms</a>
</li>
<li><a href="
../ble_bare_bones/
">Bluetooth Low Energy</a>
<ul>
<li >
<a href="../ble_bare_bones/">BLE Bare Bones Application</a>
</li>
<li >
<a href="../ibeacon/">BLE iBeacon</a>
</li>
<li class="active">
<a href="./">BLE Eddystone</a>
</li>
<li ><a href="../bleprph/bleprph-intro/">BLE Peripheral Project</a>
</li>
<li >
<a href="../blehci_project/">BLE HCI interface</a>
</li>
</ul>
</li>
<li><a href="
../event_queue/
">OS Fundamentals</a>
</li>
<li><a href="
../add_newtmgr/
">Remote Device Management</a>
</li>
<li><a href="
../sensors/sensors/
">Sensors</a>
</li>
<li><a href="
../segger_rtt/
">Tooling</a>
</li>
<li><a href="
../codesize/
">Other</a>
</li>
</ul>
</li>
<li ><a href="../../os_user_guide/">OS User Guide</a>
</li>
<li><a href="
../../../network/ble/ble_intro/
">BLE User Guide</a>
</li>
<li ><a href="../../../newt/newt_intro/">Newt Tool Guide</a>
</li>
<li ><a href="../../../newtmgr/overview/">Newt Manager Guide</a>
</li>
<li >
<a href="../../../known_issues/">Known Issues</a>
</li>
</ul>
</li>
<li><a href="
../../../faq/go_env/
">Appendix</a>
</li>
</ul>
</div></div>
<div class="col-md-9" role="main">
<div class="doc-header">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="/documentation/">Docs</a></li>
<li>&raquo; <a href="os/tutorials/ble_bare_bones/">Bluetooth Low Energy</a></li>
<li>&raquo; <a href="os/tutorials/tutorials/">Tutorials</a></li>
<li>&raquo; <a href="os/introduction/">Mynewt Documentation</a></li>
<li>&raquo; BLE Eddystone</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/apache/mynewt-site/blob/master/docs/os/tutorials/eddystone.md"
class="icon icon-github"> Edit on GitHub</a>
</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 1.1.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>
<h2 id="ble-eddystone">BLE Eddystone</h2>
<p><br></p>
<h3 id="eddystone-beacon-protocol">Eddystone Beacon Protocol</h3>
<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>
<li>Eddystone-UID: a unique, static ID with a 10-byte Namespace component and a 6-byte Instance component.</li>
<li>Eddystone-URL: a compressed URL that, once parsed and decompressed, is directly usable by the client.</li>
<li>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).</li>
<li>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. </li>
</ul>
<p><a 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>
<p><br></p>
<h3 id="create-an-empty-ble-application">Create an Empty BLE Application</h3>
<p>This tutorial picks up where the
<a href="../ble_bare_bones/">BLE bare bones application tutorial</a>
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>
<li>An app called "ble_app".</li>
<li>A target called "ble_tgt".</li>
<li>Successfully executed the app on your target device.</li>
</ul>
<h3 id="add-beaconing">Add beaconing</h3>
<p>Here is a brief specification of how we want our beaconing app to behave:</p>
<ol>
<li>Wait until the host and controller are in sync.</li>
<li>Configure the NimBLE stack with an address to put in its advertisements.</li>
<li>Advertise an eddystone URL beacon indefinitely.</li>
</ol>
<p>Let's take these one at a time.</p>
<p><br></p>
<h4 id="1-wait-for-host-controller-sync">1. Wait for host-controller sync</h4>
<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="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="background-color: #ffffcc"><span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
</span><span style="background-color: #ffffcc"><span style="color: #000000">ble_app_set_addr</span>()
</span><span style="background-color: #ffffcc">{ }
</span><span style="background-color: #ffffcc">
</span><span style="background-color: #ffffcc"><span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
</span><span style="background-color: #ffffcc"><span style="color: #000000">ble_app_advertise</span>();
</span><span style="background-color: #ffffcc">{ }
</span><span style="background-color: #ffffcc">
</span><span style="background-color: #ffffcc"><span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
</span><span style="background-color: #ffffcc"><span style="color: #000000">ble_app_on_sync</span>(<span style="color: #A90D91">void</span>)
</span><span style="background-color: #ffffcc">{
</span><span style="background-color: #ffffcc"> <span style="color: #177500">/* Generate a non-resolvable private address. */</span>
</span><span style="background-color: #ffffcc"> <span style="color: #000000">ble_app_set_addr</span>();
</span><span style="background-color: #ffffcc">
</span><span style="background-color: #ffffcc"> <span style="color: #177500">/* Advertise indefinitely. */</span>
</span><span style="background-color: #ffffcc"> <span style="color: #000000">ble_app_advertise</span>();
</span><span style="background-color: #ffffcc">}
</span>
<span style="color: #A90D91">int</span>
<span style="color: #000000">main</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">argc</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">**argv</span>)
{
<span style="color: #000000">sysinit</span>();
<span style="background-color: #ffffcc"> <span style="color: #000000">ble_hs_cfg</span>.<span style="color: #000000">sync_cb</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_app_on_sync</span>;
</span>
<span style="color: #177500">/* As the last thing, process events from default event queue. */</span>
<span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) {
<span style="color: #000000">os_eventq_run</span>(<span style="color: #000000">os_eventq_dflt_get</span>());
}
}
</code></pre></div>
<p><code>ble_hs_cfg.sync_cb</code> points to the function that should be called when sync
occurs. Our callback function, <code>ble_app_on_sync()</code>, kicks off the control flow
that we specified above. Now we need to fill in the two stub functions.</p>
<p><br></p>
<h4 id="2-configure-the-nimble-stack-with-an-address">2. Configure the NimBLE stack with an address</h4>
<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="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">ble_app_set_addr</span>(<span style="color: #A90D91">void</span>)
{
<span style="background-color: #ffffcc"> <span style="color: #000000">ble_addr_t</span> <span style="color: #000000">addr</span>;
</span><span style="background-color: #ffffcc"> <span style="color: #A90D91">int</span> <span style="color: #000000">rc</span>;
</span><span style="background-color: #ffffcc">
</span><span style="background-color: #ffffcc"> <span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_hs_id_gen_rnd</span>(<span style="color: #1C01CE">1</span>, <span style="color: #000000">&amp;addr</span>);
</span><span style="background-color: #ffffcc"> <span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
</span><span style="background-color: #ffffcc">
</span><span style="background-color: #ffffcc"> <span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_hs_id_set_rnd</span>(<span style="color: #000000">addr</span>.<span style="color: #000000">val</span>);
</span><span style="background-color: #ffffcc"> <span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
</span>}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">ble_app_advertise</span>();
{ }
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">ble_app_on_sync</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #177500">/* Generate a non-resolvable private address. */</span>
<span style="color: #000000">ble_app_set_addr</span>();
<span style="color: #177500">/* Advertise indefinitely. */</span>
<span style="color: #000000">ble_app_advertise</span>();
}
</code></pre></div>
<p>Our new function, <code>ble_app_set_addr()</code>, makes two calls into the stack:</p>
<ul>
<li><a href="../../../network/ble/ble_hs/ble_hs_id/functions/ble_hs_id_gen_rnd/"><code>ble_hs_id_gen_rnd</code></a>: Generate an nRPA.</li>
<li><a href="../../../network/ble/ble_hs/ble_hs_id/functions/ble_hs_id_set_rnd/"><code>ble_hs_id_set_rnd</code></a>: Configure NimBLE to use the newly-generated address.</li>
</ul>
<p>You can click either of the function names for more detailed documentation.</p>
<p><br></p>
<h4 id="3-advertise-indefinitely">3. Advertise indefinitely</h4>
<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>
<li><a href="../../../network/ble/ble_hs/other/functions/ble_eddystone_set_adv_data_uid/"><code>ble_eddystone_set_adv_data_uid</code></a></li>
<li><a href="../../../network/ble/ble_hs/other/functions/ble_eddystone_set_adv_data_url/"><code>ble_eddystone_set_adv_data_url</code></a></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="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">int</span>
<span style="color: #000000">ble_eddystone_set_adv_data_url</span>(
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_hs_adv_fields</span> <span style="color: #000000">*adv_fields</span>,
<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">url_scheme</span>,
<span style="color: #A90D91">char</span> <span style="color: #000000">*url_body</span>,
<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">url_body_len</span>,
<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">url_suffix</span>
)
</code></pre></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>url_scheme</code> and <code>url_suffix</code> fields implement
this compression; they are single byte fields which correspond to strings
commonly found in URLs. The following arguments translate to the
https://mynewt.apache.org URL:</p>
<table>
<thead>
<tr>
<th>Parameter</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>url_scheme</td>
<td><code>BLE_EDDYSTONE_URL_SCHEME_HTTPS</code></td>
</tr>
<tr>
<td>url_body</td>
<td>"mynewt.apache"</td>
</tr>
<tr>
<td>url_suffix</td>
<td><code>BLE_EDDYSTONE_URL_SUFFIX_ORG</code></td>
</tr>
</tbody>
</table>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">ble_app_advertise</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_hs_adv_fields</span> <span style="color: #000000">fields</span>;
<span style="color: #A90D91">int</span> <span style="color: #000000">rc</span>;
<span style="color: #177500">/* Configure an eddystone URL beacon to be advertised;</span>
<span style="color: #177500"> * URL: https://apache.mynewt.org </span>
<span style="color: #177500"> */</span>
<span style="color: #000000">fields</span> <span style="color: #000000">=</span> (<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_hs_adv_fields</span>){ <span style="color: #1C01CE">0</span> };
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_eddystone_set_adv_data_url</span>(<span style="color: #000000">&amp;fields</span>,
<span style="color: #000000">BLE_EDDYSTONE_URL_SCHEME_HTTPS</span>,
<span style="color: #C41A16">&quot;mynewt.apache&quot;</span>,
<span style="color: #1C01CE">13</span>,
<span style="color: #000000">BLE_EDDYSTONE_URL_SUFFIX_ORG</span>);
<span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
<span style="color: #177500">/* TODO: Begin advertising. */</span>
}
</code></pre></div>
<p>Now that the host knows what to advertise, the next step is to actually begin
advertising. The function to initiate advertising is:
<a href="../../../network/ble/ble_hs/ble_gap/functions/ble_gap_adv_start/"><code>ble_gap_adv_start</code></a>.
This function takes several parameters. For simplicity, we reproduce the
function prototype here:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">int</span>
<span style="color: #000000">ble_gap_adv_start</span>(
<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">own_addr_type</span>,
<span style="color: #A90D91">const</span> <span style="color: #000000">ble_addr_t</span> <span style="color: #000000">*direct_addr</span>,
<span style="color: #A90D91">int32_t</span> <span style="color: #000000">duration_ms</span>,
<span style="color: #A90D91">const</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_gap_adv_params</span> <span style="color: #000000">*adv_params</span>,
<span style="color: #000000">ble_gap_event_fn</span> <span style="color: #000000">*cb</span>,
<span style="color: #A90D91">void</span> <span style="color: #000000">*cb_arg</span>
)
</code></pre></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>
<thead>
<tr>
<th>Parameter</th>
<th>Value</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>own_addr_type</td>
<td>BLE_OWN_ADDR_RANDOM</td>
<td>Use the nRPA we generated earlier.</td>
</tr>
<tr>
<td>direct_addr</td>
<td>NULL</td>
<td>We are broadcasting, not targeting a peer.</td>
</tr>
<tr>
<td>duration_ms</td>
<td>BLE_HS_FOREVER</td>
<td>Advertise indefinitely.</td>
</tr>
<tr>
<td>adv_params</td>
<td>defaults</td>
<td>Can be used to specify low level advertising parameters.</td>
</tr>
<tr>
<td>cb</td>
<td>NULL</td>
<td>We are non-connectable, so no need for an event callback.</td>
</tr>
<tr>
<td>cb_arg</td>
<td>NULL</td>
<td>No callback implies no callback argument.</td>
</tr>
</tbody>
</table>
<p>These arguments are mostly self-explanatory. The exception is <code>adv_params</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>ble_gap_adv_params</code> struct as our
argument.</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">ble_app_advertise</span>(<span style="color: #A90D91">void</span>)
{
<span style="background-color: #ffffcc"> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_gap_adv_params</span> <span style="color: #000000">adv_params</span>;
</span> <span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_hs_adv_fields</span> <span style="color: #000000">fields</span>;
<span style="color: #A90D91">int</span> <span style="color: #000000">rc</span>;
<span style="color: #177500">/* Configure an eddystone URL beacon to be advertised;</span>
<span style="color: #177500"> * URL: https://apache.mynewt.org </span>
<span style="color: #177500"> */</span>
<span style="color: #000000">fields</span> <span style="color: #000000">=</span> (<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_hs_adv_fields</span>){ <span style="color: #1C01CE">0</span> };
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_eddystone_set_adv_data_url</span>(<span style="color: #000000">&amp;fields</span>,
<span style="color: #000000">BLE_EDDYSTONE_URL_SCHEME_HTTPS</span>,
<span style="color: #C41A16">&quot;mynewt.apache&quot;</span>,
<span style="color: #1C01CE">13</span>,
<span style="color: #000000">BLE_EDDYSTONE_URL_SUFFIX_ORG</span>);
<span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
<span style="background-color: #ffffcc"> <span style="color: #177500">/* Begin advertising. */</span>
</span><span style="background-color: #ffffcc"> <span style="color: #000000">adv_params</span> <span style="color: #000000">=</span> (<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_gap_adv_params</span>){ <span style="color: #1C01CE">0</span> };
</span><span style="background-color: #ffffcc"> <span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_gap_adv_start</span>(<span style="color: #000000">BLE_OWN_ADDR_RANDOM</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">BLE_HS_FOREVER</span>,
</span><span style="background-color: #ffffcc"> <span style="color: #000000">&amp;adv_params</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #A90D91">NULL</span>);
</span><span style="background-color: #ffffcc"> <span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
</span>}
</code></pre></div>
<h3 id="conclusion">Conclusion</h3>
<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>newt run</code> command.</p>
<h3 id="source-listing">Source Listing</h3>
<p>For reference, here is the complete application source:</p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #633820">#include</span> <span style="color: #177500">&quot;sysinit/sysinit.h&quot;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&quot;os/os.h&quot;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&quot;console/console.h&quot;</span>
<span style="color: #633820">#include</span> <span style="color: #177500">&quot;host/ble_hs.h&quot;</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">ble_app_set_addr</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #000000">ble_addr_t</span> <span style="color: #000000">addr</span>;
<span style="color: #A90D91">int</span> <span style="color: #000000">rc</span>;
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_hs_id_gen_rnd</span>(<span style="color: #1C01CE">1</span>, <span style="color: #000000">&amp;addr</span>);
<span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_hs_id_set_rnd</span>(<span style="color: #000000">addr</span>.<span style="color: #000000">val</span>);
<span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">ble_app_advertise</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_gap_adv_params</span> <span style="color: #000000">adv_params</span>;
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_hs_adv_fields</span> <span style="color: #000000">fields</span>;
<span style="color: #A90D91">int</span> <span style="color: #000000">rc</span>;
<span style="color: #177500">/* Configure an eddystone URL beacon to be advertised;</span>
<span style="color: #177500"> * URL: https://apache.mynewt.org </span>
<span style="color: #177500"> */</span>
<span style="color: #000000">fields</span> <span style="color: #000000">=</span> (<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_hs_adv_fields</span>){ <span style="color: #1C01CE">0</span> };
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_eddystone_set_adv_data_url</span>(<span style="color: #000000">&amp;fields</span>,
<span style="color: #000000">BLE_EDDYSTONE_URL_SCHEME_HTTPS</span>,
<span style="color: #C41A16">&quot;mynewt.apache&quot;</span>,
<span style="color: #1C01CE">13</span>,
<span style="color: #000000">BLE_EDDYSTONE_URL_SUFFIX_ORG</span>);
<span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
<span style="color: #177500">/* Begin advertising. */</span>
<span style="color: #000000">adv_params</span> <span style="color: #000000">=</span> (<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_gap_adv_params</span>){ <span style="color: #1C01CE">0</span> };
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_gap_adv_start</span>(<span style="color: #000000">BLE_OWN_ADDR_RANDOM</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">BLE_HS_FOREVER</span>,
<span style="color: #000000">&amp;adv_params</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #A90D91">NULL</span>);
<span style="color: #000000">assert</span>(<span style="color: #000000">rc</span> <span style="color: #000000">==</span> <span style="color: #1C01CE">0</span>);
}
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">ble_app_on_sync</span>(<span style="color: #A90D91">void</span>)
{
<span style="color: #177500">/* Generate a non-resolvable private address. */</span>
<span style="color: #000000">ble_app_set_addr</span>();
<span style="color: #177500">/* Advertise indefinitely. */</span>
<span style="color: #000000">ble_app_advertise</span>();
}
<span style="color: #A90D91">int</span>
<span style="color: #000000">main</span>(<span style="color: #A90D91">int</span> <span style="color: #000000">argc</span>, <span style="color: #A90D91">char</span> <span style="color: #000000">**argv</span>)
{
<span style="color: #000000">sysinit</span>();
<span style="color: #000000">ble_hs_cfg</span>.<span style="color: #000000">sync_cb</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_app_on_sync</span>;
<span style="color: #177500">/* As the last thing, process events from default event queue. */</span>
<span style="color: #A90D91">while</span> (<span style="color: #1C01CE">1</span>) {
<span style="color: #000000">os_eventq_run</span>(<span style="color: #000000">os_eventq_dflt_get</span>());
}
}
</code></pre></div>
<div class="row">
<ul class="nav nav-pills" style="margin-bottom: 10px">
<li>
</li>
<li class="pull-right">
</li>
</ul>
</div>
<footer 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">
<a href="https://www.apache.org/">
<img src="/img/asf_logo_wide_small.png" alt="Apache" title="Apache">
</a>
<p>
Copyright © 2015-2021 The Apache Software Foundation.<br>
<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>
</p>
<a href="">
<img src="https://www.countit.com/images/add_to_slack.png" alt="Slack Icon" title="Join our Slack Community" />
</a>
</div>
</div>
<a href="https://www.apache.org/licenses/">
<button class="button-footer-asf">
License
</button>
</a>
<a href="https://www.apache.org/foundation/sponsorship.html">
<button class="button-footer-asf">
Sponsorship
</button>
</a>
<a href="https://www.apache.org/foundation/thanks.html">
<button class="button-footer-asf">
Thanks
</button>
</a>
<a href="https://www.apache.org/security/">
<button class="button-footer-asf">
Security
</button>
</a>
<a href="https://apache.org/events/current-event">
<button class="button-footer-asf">
ASF Events
</button>
</a>
</footer>
</div>
</div>
</div>
<script src="../../../js/jquery-1.10.2.min.js"></script>
<script src="../../../js/bootstrap-3.0.3.min.js"></script>
<script src="../../../js/highlight.pack.js"></script>
<script src="../../../js/base.js"></script>
<script src="../../../js/custom.js"></script>
<script src="search/main.js"></script>
</body>
</html>