blob: dd3afe97e9e822b300cb2231896edf3366c88c26 [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>Advertising - 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="Advertising">
<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" >
Version: 1.1.0
</option>
<option value="/v1_0_0/os/introduction" >
Version: 1.0.0
</option>
<option value="/v0_9_0/os/introduction" selected="selected" >
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="
../../arduino_zero/
">Project Blinky</a>
</li>
<li ><a href="../../repo/add_repos/">Work with repositories</a>
</li>
<li >
<a href="../../unit_test/">Write a Test Suite for a Package</a>
</li>
<li >
<a href="../../air_quality_sensor/">Air-quality Sensor project</a>
</li>
<li >
<a href="../../event_queue/">Add task to manage multiple events</a>
</li>
<li >
<a href="../../project-slinky/">Enable remote comms on sim device</a>
</li>
<li >
<a href="../../project-target-slinky/">Enable remote comms on STM32 board</a>
</li>
<li >
<a href="../../bletiny_project/">BLE app to check stats via console</a>
</li>
<li ><a href="../bleprph-intro/">BLE peripheral project</a>
<ul>
<li >
<a href="../bleprph-svc-reg/">Service Registration</a>
</li>
<li >
<a href="../bleprph-chr-access/">Characteristic Access</a>
</li>
<li class="active">
<a href="./">Advertising</a>
</li>
<li >
<a href="../bleprph-conn/">Connection Callbacks</a>
</li>
</ul>
</li>
<li >
<a href="../../ibeacon/">BLE iBeacon</a>
</li>
<li >
<a href="../../blehci_project/">BLE HCI interface</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/how_to_edit_docs/
">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/bleprph/bleprph-intro/">BLE peripheral project</a></li>
<li>&raquo; <a href="os/tutorials/tutorials/">Tutorials</a></li>
<li>&raquo; <a href="os/introduction/">Mynewt Documentation</a></li>
<li>&raquo; Advertising</li>
</ul>
</div>
</div>
<div class="alert alert-warning">
<p>
Version 0.9.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-peripheral-project">BLE Peripheral Project</h2>
<h3 id="advertising">Advertising</h3>
<p><br></p>
<h4 id="overview">Overview</h4>
<p>A peripheral announces its presence to the world by broadcasting
advertisements. An advertisement typically contains additional information
about the peripheral sending it, such as the device name and an abbreviated
list of supported services. The presence of this information helps a listening
central to determine whether it is interested in connecting to the peripheral.
Advertisements are quite limited in the amount of information they can contain,
so only the most important information should be included.</p>
<p>When a listening device receives an advertisement, it can choose to connect to
the peripheral, or query the sender for more information. This second action
is known as an <em>active scan</em>. A peripheral responds to an active scan with
some extra information that it couldn't fit in its advertisement. This
additional information is known as <em>scan response data</em>. <em>bleprph</em> does not
configure any scan response data, so this feature is not discussed in the
remainder of this tutorial.</p>
<p><em>bleprph</em> constantly broadcasts advertisements until a central connects to it.
When a connection is terminated, <em>bleprph</em> resumes advertising.</p>
<p>Let's take a look at <em>bleprph</em>'s advertisement code (<em>main.c</em>):</p>
<p><br></p>
<div class="codehilite" style="background: #ffffff"><pre style="line-height: 125%;"><span></span><code><span style="color: #177500">/**</span>
<span style="color: #177500"> * Enables advertising with the following parameters:</span>
<span style="color: #177500"> * o General discoverable mode.</span>
<span style="color: #177500"> * o Undirected connectable mode.</span>
<span style="color: #177500"> */</span>
<span style="color: #A90D91">static</span> <span style="color: #A90D91">void</span>
<span style="color: #000000">bleprph_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">/* Set the advertisement data included in our advertisements. */</span>
<span style="color: #000000">memset</span>(<span style="color: #000000">&amp;fields</span>, <span style="color: #1C01CE">0</span>, <span style="color: #A90D91">sizeof</span> <span style="color: #000000">fields</span>);
<span style="color: #000000">fields</span>.<span style="color: #000000">name</span> <span style="color: #000000">=</span> (<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">*</span>)<span style="color: #000000">bleprph_device_name</span>;
<span style="color: #000000">fields</span>.<span style="color: #000000">name_len</span> <span style="color: #000000">=</span> <span style="color: #000000">strlen</span>(<span style="color: #000000">bleprph_device_name</span>);
<span style="color: #000000">fields</span>.<span style="color: #000000">name_is_complete</span> <span style="color: #000000">=</span> <span style="color: #1C01CE">1</span>;
<span style="color: #000000">rc</span> <span style="color: #000000">=</span> <span style="color: #000000">ble_gap_adv_set_fields</span>(<span style="color: #000000">&amp;fields</span>);
<span style="color: #A90D91">if</span> (<span style="color: #000000">rc</span> <span style="color: #000000">!=</span> <span style="color: #1C01CE">0</span>) {
<span style="color: #000000">BLEPRPH_LOG</span>(<span style="color: #000000">ERROR</span>, <span style="color: #C41A16">&quot;error setting advertisement data; rc=%d\n&quot;</span>, <span style="color: #000000">rc</span>);
<span style="color: #A90D91">return</span>;
}
<span style="color: #177500">/* Begin advertising. */</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_GAP_DISC_MODE_GEN</span>, <span style="color: #000000">BLE_GAP_CONN_MODE_UND</span>,
<span style="color: #A90D91">NULL</span>, <span style="color: #1C01CE">0</span>, <span style="color: #A90D91">NULL</span>, <span style="color: #000000">bleprph_on_connect</span>, <span style="color: #A90D91">NULL</span>);
<span style="color: #A90D91">if</span> (<span style="color: #000000">rc</span> <span style="color: #000000">!=</span> <span style="color: #1C01CE">0</span>) {
<span style="color: #000000">BLEPRPH_LOG</span>(<span style="color: #000000">ERROR</span>, <span style="color: #C41A16">&quot;error enabling advertisement; rc=%d\n&quot;</span>, <span style="color: #000000">rc</span>);
<span style="color: #A90D91">return</span>;
}
}
</code></pre></div>
<p>Now let's examine this code in detail.</p>
<p><br></p>
<h4 id="setting-advertisement-data">Setting advertisement data</h4>
<p>A NimBLE peripheral specifies what information to include in its advertisements with the following function:</p>
<p><br></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_set_fields</span>(<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">ble_hs_adv_fields</span> <span style="color: #000000">*adv_fields</span>)
</code></pre></div>
<p><br></p>
<p>The <em>adv_fields</em> argument specifies the fields and their contents to include in
subsequent advertisements. The Bluetooth <a href="https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=302735">Core Specification
Supplement</a>
defines a set of standard fields that can be included in an advertisement; the
member variables of the <em>struct ble_hs_adv_fields</em> type correspond to these
standard fields. Information that doesn't fit neatly into a standard field
should be put in the <em>manufacturing specific data</em> field.</p>
<p>As you can see in the above code listing, the <code>struct ble_hs_adv_fields</code>
instance is allocated on the stack. It is OK to use the stack for this struct
and the data it references, as the <code>ble_gap_adv_set_fields()</code>
function makes a copy of all the advertisement data before it returns.
<em>bleprph</em> doesn't take full advantange of this; it stores its device name in a
static array.</p>
<p>The code sets three members of the <em>struct ble_hs_adv_fields</em> instance:</p>
<ul>
<li>name</li>
<li>name_len</li>
<li>name_is_complete</li>
</ul>
<p>The first two fields are used to communicate the device's name and are quite
straight-forward. The third field requires some explanation. Bluetooth
specifies two name-related advertisement fields: <em>Shortened Local Name</em> and
<em>Complete Local Name</em>. Setting the <code>name_is_complete</code> variable to 1 or 0 tells
NimBLE which of these two fields to include in advertisements. Some other
advertisement fields also correspond to multiple variables in the field struct,
so it is a good idea to review the <em>ble_hs_adv_fields</em> reference to
make sure you get the details right in your app.</p>
<p><br></p>
<h4 id="begin-advertising">Begin advertising</h4>
<p>An app starts advertising with the following function:</p>
<p><br></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">discoverable_mode</span>, <span style="color: #A90D91">uint8_t</span> <span style="color: #000000">connectable_mode</span>,
<span style="color: #A90D91">uint8_t</span> <span style="color: #000000">*peer_addr</span>, <span style="color: #A90D91">uint8_t</span> <span style="color: #000000">peer_addr_type</span>,
<span style="color: #A90D91">struct</span> <span style="color: #3F6E75">hci_adv_params</span> <span style="color: #000000">*adv_params</span>,
<span style="color: #000000">ble_gap_conn_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 allows a lot of flexibility, and it might seem daunting at first
glance. <em>bleprph</em> specifies a simple set of arguments that is appropriate for
most peripherals. When getting started on a typical peripheral, we recommend
you use the same arguments as <em>bleprph</em>, with the exception of the last two
(<em>cb</em> and <em>cb_arg</em>). These last two arguments will be specific to your app, so
let's talk about them.</p>
<p><em>cb</em> is a callback function. It gets executed when a central connects to your
peripheral after receiving an advertisement. The <em>cb_arg</em> argument gets passed
to the <em>cb</em> callback. If your callback doesn't need the <em>cb_arg</em> parameter,
you can do what <em>bleprph</em> does and pass <em>NULL</em>. Once a connection is
established, the <em>cb</em> callback becomes permanently associated with the
connection. All subsequent events related to the connection are communicated
to your app via calls to this callback function. Connection callbacks are an
important part of building a BLE app, and we examine <em>bleprph</em>'s connection
callback in detail in the next section of this tutorial.</p>
<p><br></p>
<p><strong>One final note:</strong> Your peripheral automatically stops advertising when a central connects to it. You can immediately resume advertising if you want to allow another central to connect, but you will need to do so explicitly by calling <code>ble_gap_adv_start()</code> again. Also, be aware NimBLE's default configuration only allows a single connection at a time. NimBLE supports multiple concurrent connections, but you must configure it to do so first.</p>
<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 (incubating) 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>