esp-nimble-cpp/md__migration__guide.html
2024-12-17 01:50:27 +00:00

481 lines
40 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>esp-nimble-cpp: Migrating from Bluedroid to NimBLE</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">esp-nimble-cpp<span id="projectnumber">&#160;2.0.1</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.8 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function(){initNavTree('md__migration__guide.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>
<div><div class="header">
<div class="headertitle"><div class="title">Migrating from Bluedroid to NimBLE</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><a class="anchor" id="migrating-from-bluedroid-to-nimble"></a> This guide describes the required changes to existing projects migrating from the original bluedroid API to NimBLE.</p>
<p><b>The changes listed here are only the required changes that must be made</b>, and a short overview of options for migrating existing applications.</p>
<p>For more information on the improvements and additions please refer to the <a href="https://h2zero.github.io/esp-nimble-cpp/annotated.html">class documentation</a></p>
<ul>
<li><a class="el" href="md__migration__guide.html#general-information">General Changes</a></li>
<li><a class="el" href="md__migration__guide.html#server-api">Server</a><ul>
<li><a class="el" href="md_1_8x__to2_8x__migration__guide.html#services">Services</a></li>
<li><a class="el" href="md_1_8x__to2_8x__migration__guide.html#characteristics">Characteristics</a></li>
<li><a class="el" href="md_1_8x__to2_8x__migration__guide.html#characteristic-callbacks">Characteristic Callbacks</a></li>
<li><a class="el" href="md__migration__guide.html#descriptors">Descriptors</a></li>
<li><a class="el" href="md__migration__guide.html#descriptor-callbacks">Descriptor Callbacks</a></li>
<li><a class="el" href="md_1_8x__to2_8x__migration__guide.html#server-security">Security</a></li>
</ul>
</li>
<li><a class="el" href="md__migration__guide.html#advertising-api">Advertising</a></li>
<li><a class="el" href="md__migration__guide.html#client-api">Client</a><ul>
<li><a class="el" href="md_1_8x__to2_8x__migration__guide.html#remote-services">Remote Services</a></li>
<li><a class="el" href="md_1_8x__to2_8x__migration__guide.html#remote-characteristics">Remote characteristics</a></li>
<li><a class="el" href="md_1_8x__to2_8x__migration__guide.html#client-callbacks">Client Callbacks</a></li>
<li><a class="el" href="md__migration__guide.html#client-security">Security</a></li>
</ul>
</li>
<li><a class="el" href="md__migration__guide.html#ble-scan">BLE scan</a></li>
<li><a class="el" href="md__migration__guide.html#security-api">General Security</a></li>
<li><a class="el" href="md__migration__guide.html#arduino-configuration">Configuration</a> <br />
</li>
</ul>
<h1><a class="anchor" id="general-information"></a>
General Information</h1>
<h2><a class="anchor" id="header-files"></a>
Header Files</h2>
<p>All classes are accessible by including <code><a class="el" href="_nim_b_l_e_device_8h_source.html">NimBLEDevice.h</a></code> in your application, no further headers need to be included.</p>
<p>(Mainly for Arduino) You may choose to include <code><a class="el" href="_nim_b_l_e_log_8h_source.html">NimBLELog.h</a></code> in your application if you want to use the <code>NIMBLE_LOGx</code> macros for debugging. These macros are used the same way as the <code>ESP_LOGx</code> macros. <br />
<br />
</p>
<h2><a class="anchor" id="class-names"></a>
Class Names</h2>
<p>Class names remain the same as the original with the addition of a "Nim" prefix. For example <code>BLEDevice</code> is now <code><a class="el" href="class_nim_b_l_e_device.html" title="A model of a BLE Device from which all the BLE roles are created.">NimBLEDevice</a></code> and <code>BLEServer</code> is now <code><a class="el" href="class_nim_b_l_e_server.html" title="The model of a BLE server.">NimBLEServer</a></code> etc.</p>
<p>For convenience definitions have been added to allow applications to use either name for all classes this means <b>no class names need to be changed in existing code</b> and makes migrating easier. <br />
<br />
</p>
<h2><a class="anchor" id="ble-addresses-1"></a>
BLE Addresses</h2>
<p><code>BLEAddress</code> (<code><a class="el" href="class_nim_b_l_e_address.html" title="A BLE device address.">NimBLEAddress</a></code>) When constructing an address the constructor now takes an *(optional)* <code>uint8_t type</code> parameter to specify the address type. Default is (0) Public static address.</p>
<p>For example <code>BLEAddress addr(11:22:33:44:55:66, 1)</code> will create the address object with an address type of: 1 (Random).</p>
<p>As this parameter is optional no changes to existing code are needed, it is mentioned here for information.</p>
<p><code>BLEAddress::getNative</code> is now named <code><a class="el" href="class_nim_b_l_e_address.html#a31b466293f6cb752d5aba6b6ffb95351" title="Get the NimBLE base struct of the address.">NimBLEAddress::getBase</a></code> and returns a pointer to <code>const ble_addr_t</code> instead of a pointer to the address value. <br />
<br />
</p>
<h1><a class="anchor" id="server-api"></a>
Server API</h1>
<p>Creating a <code>BLEServer</code> instance is the same as original, no changes required. For example <code>BLEDevice::createServer()</code> will work just as it did before.</p>
<p><code>BLEServerCallbacks</code> (<code><a class="el" href="class_nim_b_l_e_server_callbacks.html" title="Callbacks associated with the operation of a BLE server.">NimBLEServerCallbacks</a></code>) has new methods for handling security operations. <br />
<br />
</p>
<p><code>BLEServerCallbacks::onConnect</code> (<code><a class="el" href="class_nim_b_l_e_server_callbacks.html#a11d48696c2121eb301a76301555df2c5" title="Handle a client connection. This is called when a client connects.">NimBLEServerCallbacks::onConnect</a></code>) only has a single callback declaration which takes an additional (required) parameter <code><a class="el" href="class_nim_b_l_e_conn_info.html" title="Connection information.">NimBLEConnInfo</a> &amp; connInfo</code>, which has methods to get information about the connected peer. </p><div class="fragment"><div class="line">void onConnect(NimBLEServer* pServer, NimBLEConnInfo&amp; connInfo)`</div>
</div><!-- fragment --><p> <br />
</p>
<p><code>BLEServerCallbacks::onDisconnect</code> (<code><a class="el" href="class_nim_b_l_e_server_callbacks.html#a4622b24e5553cc7961c04ab25b63d943" title="Handle a client disconnection. This is called when a client disconnects.">NimBLEServerCallbacks::onDisconnect</a></code>) only has a single callback declaration which takes 2 additional (required) parameters <code><a class="el" href="class_nim_b_l_e_conn_info.html" title="Connection information.">NimBLEConnInfo</a> &amp; connInfo</code>, which provides information about the peer and <code>int reason</code>, which gives the reason code for disconnection.</p>
<div class="fragment"><div class="line">void onDisconnect(NimBLEServer* pServer, NimBLEConnInfo&amp; connInfo, int reason)`</div>
</div><!-- fragment --><p> <br />
</p>
<p><code>BLEServerCallbacks::onMtuChanged</code> is now (<code>NimBLEServerCallbacks::onMtuChange</code>) and takes the parameter <code><a class="el" href="class_nim_b_l_e_conn_info.html" title="Connection information.">NimBLEConnInfo</a> &amp; connInfo</code> instead of <code>esp_ble_gatts_cb_param_t</code>, which has methods to get information about the connected peer.</p>
<div class="fragment"><div class="line">onMTUChange(uint16_t MTU, NimBLEConnInfo&amp; connInfo)</div>
</div><!-- fragment --><p><b>Note:</b> All callback methods have default implementations which allows the application to implement only the methods applicable. <br />
<br />
</p>
<h2><a class="anchor" id="services-1"></a>
Services</h2>
<p>Creating a <code>BLEService</code> (<code><a class="el" href="class_nim_b_l_e_service.html" title="The model of a BLE service.">NimBLEService</a></code>) instance is the same as original, no changes required. For example <code>BLEServer::createService(SERVICE_UUID)</code> will work just as it did before. <br />
<br />
</p>
<h2><a class="anchor" id="characteristics-1"></a>
Characteristics</h2>
<p><code>BLEService::createCharacteristic</code> (<code><a class="el" href="class_nim_b_l_e_service.html#a415e1b836946831c6f9edd74adba8763" title="Create a new BLE Characteristic associated with this service.">NimBLEService::createCharacteristic</a></code>) is used the same way as originally except the properties parameter has changed.</p>
<p>When creating a characteristic the properties are now set with <code>NIMBLE_PROPERTY::XXXX</code> instead of <code>BLECharacteristic::XXXX</code>.</p>
<h3><a class="anchor" id="originally"></a>
Originally</h3>
<blockquote class="doxtable">
<p>&zwj;BLECharacteristic::PROPERTY_READ | <br />
</p>
</blockquote>
<p>BLECharacteristic::PROPERTY_WRITE</p>
<h3><a class="anchor" id="is-now"></a>
Is Now</h3>
<blockquote class="doxtable">
<p>&zwj;NIMBLE_PROPERTY::READ | <br />
</p>
</blockquote>
<p>NIMBLE_PROPERTY::WRITE <br />
</p>
<h3><a class="anchor" id="the-full-list-of-properties"></a>
The full list of properties</h3>
<blockquote class="doxtable">
<p>&zwj;NIMBLE_PROPERTY::READ <br />
</p>
</blockquote>
<p>NIMBLE_PROPERTY::READ_ENC <br />
NIMBLE_PROPERTY::READ_AUTHEN <br />
NIMBLE_PROPERTY::READ_AUTHOR <br />
NIMBLE_PROPERTY::WRITE <br />
NIMBLE_PROPERTY::WRITE_NR <br />
NIMBLE_PROPERTY::WRITE_ENC <br />
NIMBLE_PROPERTY::WRITE_AUTHEN <br />
NIMBLE_PROPERTY::WRITE_AUTHOR <br />
NIMBLE_PROPERTY::BROADCAST <br />
NIMBLE_PROPERTY::NOTIFY <br />
NIMBLE_PROPERTY::INDICATE <br />
</p>
<p><br />
</p>
<p><b>Example:</b> </p><div class="fragment"><div class="line">BLECharacteristic *pCharacteristic = pService-&gt;createCharacteristic(</div>
<div class="line"> CHARACTERISTIC_UUID,</div>
<div class="line"> BLECharacteristic::PROPERTY_READ |</div>
<div class="line"> BLECharacteristic::PROPERTY_WRITE</div>
<div class="line"> );</div>
</div><!-- fragment --><p> Needs to be changed to: </p><div class="fragment"><div class="line">BLECharacteristic *pCharacteristic = pService-&gt;createCharacteristic(</div>
<div class="line"> CHARACTERISTIC_UUID,</div>
<div class="line"> NIMBLE_PROPERTY::READ |</div>
<div class="line"> NIMBLE_PROPERTY::WRITE</div>
<div class="line"> );</div>
</div><!-- fragment --><p> <br />
</p>
<h3><a class="anchor" id="characteristic-callbacks-1"></a>
Characteristic callbacks</h3>
<p><code>BLECharacteristicCallbacks</code> (<code><a class="el" href="class_nim_b_l_e_characteristic_callbacks.html" title="Callbacks that can be associated with a BLE characteristic to inform of events.">NimBLECharacteristicCallbacks</a></code>) has a new method <code><a class="el" href="class_nim_b_l_e_characteristic_callbacks.html#a024951384bb777d7ee71bfd1d5eff185" title="Callback function called when a client changes subscription status.">NimBLECharacteristicCallbacks::onSubscribe</a></code> which is called when a client subscribes to notifications/indications.</p>
<p><code>BLECharacteristicCallbacks::onRead</code> (<code><a class="el" href="class_nim_b_l_e_characteristic_callbacks.html#a120d3dade06fbc941a93edbdc0e4d830" title="Callback function to support a read request.">NimBLECharacteristicCallbacks::onRead</a></code>) only has a single callback declaration, which takes an additional (required) parameter of <code><a class="el" href="class_nim_b_l_e_conn_info.html" title="Connection information.">NimBLEConnInfo</a>&amp; connInfo</code>, which provides connection information about the peer.</p>
<p><code>BLECharacteristicCallbacks::onWrite</code> (<code><a class="el" href="class_nim_b_l_e_characteristic_callbacks.html#ab4edbb758f0212fd190dedad6c9b8ec9" title="Callback function to support a write request.">NimBLECharacteristicCallbacks::onWrite</a></code>) only has a single callback declaration, which takes an additional (required) parameter of <code><a class="el" href="class_nim_b_l_e_conn_info.html" title="Connection information.">NimBLEConnInfo</a>&amp; connInfo</code>, which provides connection information about the peer. <br />
</p>
<p><code>BLECharacteristicCallbacks::onStatus</code> (<code><a class="el" href="class_nim_b_l_e_characteristic_callbacks.html#a6f9b1f0f15492e3d47662e5e2ff0baee" title="Callback function to support a Notify/Indicate Status report.">NimBLECharacteristicCallbacks::onStatus</a></code>) has had the status parameter removed as it was unnecessary since the status code from the BLE stack was also provided. The status code for success is 0 for notifications and BLE_HS_EDONE for indications, any other value is an error.</p>
<p><b>Note:</b> All callback methods have default implementations which allows the application to implement only the methods applicable. <br />
<br />
</p>
<blockquote class="doxtable">
<p>&zwj;BLECharacteristic::getData </p>
</blockquote>
<p><b>Has been removed from the API.</b> Originally this returned a <code>uint8_t*</code> to the internal data, which is volatile. To prevent possibly throwing exceptions this has been removed and <code>NimBLECharacteristic::getValue</code> should be used to get a copy of the data first which can then safely be accessed via pointer.</p>
<p><b>Example:</b> </p><div class="fragment"><div class="line">std::string value = pCharacteristic-&gt;getValue();</div>
<div class="line">uint8_t *pData = (uint8_t*)value.data();</div>
</div><!-- fragment --><p> Alternatively use the <code>getValue</code> template: </p><div class="fragment"><div class="line">my_struct_t myStruct = pChr-&gt;getValue&lt;my_struct_t&gt;();</div>
</div><!-- fragment --><p> <br />
</p>
<h2><a class="anchor" id="descriptors"></a>
Descriptors</h2>
<p>Descriptors are now created using the <code><a class="el" href="class_nim_b_l_e_characteristic.html#aa9817ffdcc2d57e65e4ec3d88836af3f" title="Create a new BLE Descriptor associated with this characteristic.">NimBLECharacteristic::createDescriptor</a></code> method.</p>
<p>BLE2902 or NimBLE2902 class has been removed. NimBLE automatically creates the 0x2902 descriptor if a characteristic has a notification or indication property assigned to it.</p>
<p>It was no longer useful to have a class for the 0x2902 descriptor as a new callback <code><a class="el" href="class_nim_b_l_e_characteristic_callbacks.html#a024951384bb777d7ee71bfd1d5eff185" title="Callback function called when a client changes subscription status.">NimBLECharacteristicCallbacks::onSubscribe</a></code> was added to handle callback functionality and the client subscription status is handled internally.</p>
<p><b>Note:</b> Attempting to create a 0x2902 descriptor will trigger a warning message and flag it internally as removed and will not be functional.</p>
<p>All other descriptors are now created just as characteristics are by using the <code><a class="el" href="class_nim_b_l_e_characteristic.html#aa9817ffdcc2d57e65e4ec3d88836af3f" title="Create a new BLE Descriptor associated with this characteristic.">NimBLECharacteristic::createDescriptor</a></code> method (except 0x2904, see below). Which are defined as: </p><div class="fragment"><div class="line">NimBLEDescriptor* createDescriptor(const char* uuid,</div>
<div class="line"> uint32_t properties =</div>
<div class="line"> NIMBLE_PROPERTY::READ |</div>
<div class="line"> NIMBLE_PROPERTY::WRITE,</div>
<div class="line"> uint16_t max_len = 100);</div>
<div class="line"> </div>
<div class="line">NimBLEDescriptor* createDescriptor(NimBLEUUID uuid,</div>
<div class="line"> uint32_t properties =</div>
<div class="line"> NIMBLE_PROPERTY::READ |</div>
<div class="line"> NIMBLE_PROPERTY::WRITE,</div>
<div class="line"> uint16_t max_len = 100);</div>
</div><!-- fragment --> <h3><a class="anchor" id="example"></a>
Example</h3>
<div class="fragment"><div class="line">pDescriptor = pCharacteristic-&gt;createDescriptor(&quot;ABCD&quot;,</div>
<div class="line"> NIMBLE_PROPERTY::READ |</div>
<div class="line"> NIMBLE_PROPERTY::WRITE |</div>
<div class="line"> NIMBLE_PROPERTY::WRITE_ENC,</div>
<div class="line"> 25);</div>
</div><!-- fragment --><p> Would create a descriptor with the UUID 0xABCD, publicly readable but only writable if paired/bonded (encrypted) and has a max value length of 25 bytes. <br />
</p>
<p>For the 0x2904, there is a specialized class that is created through <code><a class="el" href="class_nim_b_l_e_characteristic.html#acc3402da680a988f6fa38100d9c98275" title="Create a Characteristic Presentation Format Descriptor for this characteristic.">NimBLECharacteristic::create2904</a></code> which returns a pointer to a <code><a class="el" href="class_nim_b_l_e2904.html" title="Descriptor for Characteristic Presentation Format.">NimBLE2904</a></code> instance which has specific functions for handling the data expect in the Characteristic Presentation Format Descriptor specification. <br />
<br />
</p>
<h3><a class="anchor" id="descriptor-callbacks"></a>
Descriptor callbacks</h3>
<blockquote class="doxtable">
<p>&zwj;<code>BLEDescriptorCallbacks::onRead</code> (<code><a class="el" href="class_nim_b_l_e_descriptor_callbacks.html#a061576b56702a6aca62a38f2ba27ba98" title="Callback function to support a read request.">NimBLEDescriptorCallbacks::onRead</a></code>) <code>BLEDescriptorCallbacks::onWrite</code> (<code><a class="el" href="class_nim_b_l_e_descriptor_callbacks.html#a2872d9e602d4e23cc63f55f5b2f76dd7" title="Callback function to support a write request.">NimBLEDescriptorCallbacks::onWrite</a></code>) </p>
</blockquote>
<p>The above descriptor callbacks take an additional (required) parameter <code><a class="el" href="class_nim_b_l_e_conn_info.html" title="Connection information.">NimBLEConnInfo</a>&amp; connInfo</code>, which contains the connection information of the peer. <br />
</p>
<h2><a class="anchor" id="server-security-1"></a>
Server Security</h2>
<p>Security is set on the characteristic or descriptor properties by applying one of the following: </p><blockquote class="doxtable">
<p>&zwj;NIMBLE_PROPERTY::READ_ENC <br />
</p>
</blockquote>
<p>NIMBLE_PROPERTY::READ_AUTHEN <br />
NIMBLE_PROPERTY::READ_AUTHOR <br />
NIMBLE_PROPERTY::WRITE_ENC <br />
NIMBLE_PROPERTY::WRITE_AUTHEN <br />
NIMBLE_PROPERTY::WRITE_AUTHOR <br />
</p>
<p><br />
</p>
<p>When a peer wants to read or write a characteristic or descriptor with any of these properties applied it will trigger the pairing process. By default the "just-works" pairing will be performed automatically.</p>
<p>This can be changed to use passkey authentication or numeric comparison. See <a class="el" href="md__migration__guide.html#security-api">Security API</a> for details. <br />
<br />
</p>
<h1><a class="anchor" id="advertising-api"></a>
Advertising API</h1>
<p>Advertising works the same as the original API except:</p>
<p>Calling <code><a class="el" href="class_nim_b_l_e_advertising.html#ab8afd94479ebac3996fa3712d3d92325" title="Set the advertisement data that is to be broadcast in a regular advertisement.">NimBLEAdvertising::setAdvertisementData</a></code> will entirely replace any data set with <code><a class="el" href="class_nim_b_l_e_advertising.html#a67c9589dff7e0ee3ec24f2c930d56c06" title="Add a service uuid to exposed list of services.">NimBLEAdvertising::addServiceUUID</a></code>, or <code><a class="el" href="class_nim_b_l_e_advertising.html#a1f4e1ae9552400fb2bb3cd73b2a483b0" title="Set the device appearance in the advertising data.">NimBLEAdvertising::setAppearance</a></code> or similar methods. You should set all the data you wish to advertise within the <code><a class="el" href="class_nim_b_l_e_advertisement_data.html" title="Advertisement data set by the programmer to be published by the BLE server.">NimBLEAdvertisementData</a></code> instead. <br />
<br />
</p>
<blockquote class="doxtable">
<p>&zwj;BLEAdvertising::start (<a class="el" href="class_nim_b_l_e_advertising.html#a8a5c880ee36fd44e0c72c14c47c8e15e" title="Start advertising.">NimBLEAdvertising::start</a>) </p>
</blockquote>
<p>Now takes 2 optional parameters, the first is the duration to advertise for (in milliseconds), the second <code><a class="el" href="class_nim_b_l_e_address.html" title="A BLE device address.">NimBLEAddress</a></code> to direct advertising to a specific device. <br />
<br />
</p>
<h1><a class="anchor" id="client-api"></a>
Client API</h1>
<p>Client instances are created just as before with <code>BLEDevice::createClient</code> (<code><a class="el" href="class_nim_b_l_e_device.html#a010b12177917f33e7d3633736c0cc553" title="Creates a new client object, each client can connect to 1 peripheral device.">NimBLEDevice::createClient</a></code>).</p>
<p>Multiple client instances can be created, up to the maximum number of connections set in the config file (default: 3). To delete a client instance you must use <code><a class="el" href="class_nim_b_l_e_device.html#a83aa0a3d9d57358d35082a442edf8549" title="Delete the client object and remove it from the list. Checks if it is connected or trying to connect ...">NimBLEDevice::deleteClient</a></code>.</p>
<p><code>BLEClient::connect</code>(<code><a class="el" href="class_nim_b_l_e_client.html#a2b49bc73802bf716cf3df3b5a93f0543" title="Connect to an advertising device.">NimBLEClient::connect</a></code>) Has had it's parameters altered. Defined as: </p><blockquote class="doxtable">
<p>&zwj;<a class="el" href="class_nim_b_l_e_client.html#a2b49bc73802bf716cf3df3b5a93f0543" title="Connect to an advertising device.">NimBLEClient::connect</a>(bool deleteServices = true, , bool asyncConnect = false, bool exchangeMTU = true); <br />
<a class="el" href="class_nim_b_l_e_client.html#a2b49bc73802bf716cf3df3b5a93f0543" title="Connect to an advertising device.">NimBLEClient::connect</a>(const <a class="el" href="class_nim_b_l_e_address.html" title="A BLE device address.">NimBLEAddress</a>&amp; address, bool deleteAttributes = true, bool asyncConnect = false, bool exchangeMTU = true); <br />
<a class="el" href="class_nim_b_l_e_client.html#a2b49bc73802bf716cf3df3b5a93f0543" title="Connect to an advertising device.">NimBLEClient::connect</a>(const NimBLEAdvertisedDevice* device, bool deleteServices = true, bool asyncConnect = false, bool exchangeMTU = true); </p>
</blockquote>
<p>The type parameter has been removed and a new bool parameter has been added to indicate if the client should delete the attribute database previously retrieved (if applicable) for the peripheral, default value is true.</p>
<p>If set to false the client will use the attribute database it retrieved from the peripheral when previously connected. This allows for faster connections and power saving if the devices dropped connection and are reconnecting. <br />
</p>
<p>The parameter <code>bool asyncConnect</code> if true, will cause the client to send the connect command to the stack and return immediately without blocking. The return value will represent wether the command was sent successfully or not and the <code><a class="el" href="class_nim_b_l_e_client_callbacks.html#a96de53d9745f243d544cd89498f979ae" title="Called after client connects.">NimBLEClientCallbacks::onConnect</a></code> or <code><a class="el" href="class_nim_b_l_e_client_callbacks.html#ad0eb6bee07ef8c41dd8924aaca3bc71e" title="Called when a connection attempt fails.">NimBLEClientCallbacks::onConnectFail</a></code> will be called when the operation is complete. <br />
</p>
<p>The parameter <code>bool exchangeMTU</code> if true, will cause the client to perform the exchange MTU process upon connecting. If false the MTU exchange will need to be performed by the application by calling <code><a class="el" href="class_nim_b_l_e_client.html#a19d97b47f01f0862e04f3011752b2f2f" title="Begin the MTU exchange process with the server.">NimBLEClient::exchangeMTU</a></code>. If the connection is only sending small payloads it may be advantageous to not exchange the MTU to gain performance in the connection process. <br />
<br />
</p>
<blockquote class="doxtable">
<p>&zwj;<code>BLEClient::getServices</code> (<code><a class="el" href="class_nim_b_l_e_client.html#adefe48b87e8a814e1643cdb8c3759298" title="Get a pointer to the vector of found services.">NimBLEClient::getServices</a></code>) </p>
</blockquote>
<p>This method now takes an optional (bool) parameter to indicate if the services should be retrieved from the server (true) or the currently known database returned (false : default). Also now returns a pointer to <code>std::vector</code> instead of <code>std::map</code>. <br />
<br />
</p>
<p><b>Removed:</b> the automatic discovery of all peripheral attributes as they consumed time and resources for data the user may not be interested in.</p>
<p><b>Added:</b> <code><a class="el" href="class_nim_b_l_e_client.html#a1019178a12799ca2c3a84f523b3a7db9" title="Retrieves the full database of attributes that the peripheral has available.">NimBLEClient::discoverAttributes</a></code> for the user to discover all the peripheral attributes to replace the the removed automatic functionality. <br />
<br />
</p>
<h2><a class="anchor" id="remote-services-1"></a>
Remote Services</h2>
<p><code>BLERemoteService</code> (<code><a class="el" href="class_nim_b_l_e_remote_service.html" title="A model of a remote BLE service.">NimBLERemoteService</a></code>) Methods remain mostly unchanged with the exceptions of:</p>
<blockquote class="doxtable">
<p>&zwj;BLERemoteService::getCharacteristicsByHandle </p>
</blockquote>
<p>This method has been removed. <br />
<br />
</p>
<blockquote class="doxtable">
<p>&zwj;<code>BLERemoteService::getCharacteristics</code> (<code><a class="el" href="class_nim_b_l_e_remote_service.html#a5b07f0756c401d40396886e80d64b03b" title="Get a pointer to the vector of found characteristics.">NimBLERemoteService::getCharacteristics</a></code>) </p>
</blockquote>
<p>This method now takes an optional (bool) parameter to indicate if the characteristics should be retrieved from the server (true) or the currently known database returned, default = false. <br />
Also now returns a pointer to <code>std::vector</code> instead of <code>std::map</code>. <br />
<br />
</p>
<h2><a class="anchor" id="remote-characteristics-1"></a>
Remote Characteristics</h2>
<p><code>BLERemoteCharacteristic</code> (<code><a class="el" href="class_nim_b_l_e_remote_characteristic.html" title="A model of a remote BLE characteristic.">NimBLERemoteCharacteristic</a></code>) There have been a few changes to the methods in this class:</p>
<blockquote class="doxtable">
<p>&zwj;<code>BLERemoteCharacteristic::writeValue</code> (<code>NimBLERemoteCharacteristic::writeValue</code>) </p>
</blockquote>
<p>Now returns true or false to indicate success or failure so you can choose to disconnect or try again. <br />
<br />
</p>
<blockquote class="doxtable">
<p>&zwj;<code>BLERemoteCharacteristic::registerForNotify</code> </p>
</blockquote>
<p>Has been removed.</p>
<blockquote class="doxtable">
<p>&zwj;<code><a class="el" href="class_nim_b_l_e_remote_characteristic.html#adf445e6bd9dee047a61c708ae943304a" title="Subscribe for notifications or indications.">NimBLERemoteCharacteristic::subscribe</a></code> <br />
<code><a class="el" href="class_nim_b_l_e_remote_characteristic.html#a64a74ffc6612cf4a42f33836e34887f0" title="Unsubscribe for notifications or indications.">NimBLERemoteCharacteristic::unsubscribe</a></code> <br />
</p>
</blockquote>
<p>Are the new methods added to replace it. <br />
<br />
</p>
<blockquote class="doxtable">
<p>&zwj;<code>BLERemoteCharacteristic::readUInt8</code> (<code>NimBLERemoteCharacteristic::readUInt8</code>) <br />
<code>BLERemoteCharacteristic::readUInt16</code> (<code>NimBLERemoteCharacteristic::readUInt16</code>) <br />
<code>BLERemoteCharacteristic::readUInt32</code> (<code>NimBLERemoteCharacteristic::readUInt32</code>) <br />
<code>BLERemoteCharacteristic::readFloat</code> (<code>NimBLERemoteCharacteristic::readFloat</code>) </p>
</blockquote>
<p>Are <b>removed</b> a template: <code>NimBLERemoteCharacteristic::readValue&lt;type\&gt;(time_t\*, bool)</code> has been added to replace them. <br />
<br />
</p>
<blockquote class="doxtable">
<p>&zwj;<code>BLERemoteCharacteristic::readRawData</code> </p>
</blockquote>
<p><b>Has been removed from the API</b> Originally it stored an unnecessary copy of the data and was returning a <code>uint8_t</code> pointer to volatile internal data. The user application should use <code>NimBLERemoteCharacteristic::readValue</code> or <code>NimBLERemoteCharacteristic::getValue</code>. To obtain a copy of the data as a <code><a class="el" href="class_nim_b_l_e_att_value.html" title="A specialized container class to hold BLE attribute values.">NimBLEAttValue</a></code> instance and use the <code><a class="el" href="class_nim_b_l_e_att_value.html#a86acbb5ab3a35b3d5692c2e05fdccadd" title="Returns a pointer to the internal buffer of the value.">NimBLEAttValue::data</a></code> member function to obtain the pointer. </p><div class="fragment"><div class="line">NimBLEAttValue value = pChr-&gt;readValue();</div>
<div class="line">const uint8_t *data = value.data();</div>
</div><!-- fragment --><p> Alternatively use the <code>readValue</code> template: </p><div class="fragment"><div class="line">my_struct_t myStruct = pChr-&gt;readValue&lt;my_struct_t&gt;();</div>
</div><!-- fragment --><p> <br />
</p>
<blockquote class="doxtable">
<p>&zwj;<code>BLERemoteCharacteristic::getDescriptors</code> (<code><a class="el" href="class_nim_b_l_e_remote_characteristic.html#a27746c8b2405beb1d44567e2c1f85f87" title="Get a pointer to the vector of found descriptors.">NimBLERemoteCharacteristic::getDescriptors</a></code>) </p>
</blockquote>
<p>This method now takes an optional (bool) parameter to indicate if the descriptors should be retrieved from the server (true) or the currently known database returned, default = false. Also now returns a pointer to <code>std::vector</code> instead of <code>std::map</code>. <br />
<br />
</p>
<h2><a class="anchor" id="client-callbacks-1"></a>
Client callbacks</h2>
<blockquote class="doxtable">
<p>&zwj;<code>BLEClientCallbacks::onDisconnect</code> (<code><a class="el" href="class_nim_b_l_e_client_callbacks.html#ad618179ade926482a7f2d94b0deabd69" title="Called when disconnected from the server.">NimBLEClientCallbacks::onDisconnect</a></code>) </p>
</blockquote>
<p>This now takes a second parameter <code>int reason</code> which provides the reason code for disconnection. <br />
<br />
</p>
<h2><a class="anchor" id="client-security"></a>
Client Security</h2>
<p>The client will automatically initiate security when the peripheral responds that it's required. The default configuration will use "just-works" pairing with no bonding, if you wish to enable bonding see below. <br />
<br />
</p>
<h1><a class="anchor" id="ble-scan"></a>
BLE Scan</h1>
<p>The scan API is mostly unchanged from the original except for <code><a class="el" href="class_nim_b_l_e_scan.html#ac1307f30a881688d3a4d57bac7abe02c" title="Start scanning.">NimBLEScan::start</a></code>, which has the following changes: <br />
</p><ul>
<li>The duration parameter is now in milliseconds instead of seconds.</li>
<li>The callback parameter has been removed.</li>
<li><p class="startli">A new parameter <code>bool restart</code> has been added, when set to true to restart the scan if already in progress and clear the duplicate cache.</p>
<p class="startli">The blocking overload of <code><a class="el" href="class_nim_b_l_e_scan.html#ac1307f30a881688d3a4d57bac7abe02c" title="Start scanning.">NimBLEScan::start</a></code> has been replaced by an overload of <code><a class="el" href="class_nim_b_l_e_scan.html#a2ae53719546e2d410c816e12c56aad61" title="Get the results of the scan.">NimBLEScan::getResults</a></code> with the same parameters. <br />
</p>
</li>
</ul>
<h1><a class="anchor" id="security-api"></a>
Security API</h1>
<p>Security operations have been moved to <code>BLEDevice</code> (<code><a class="el" href="class_nim_b_l_e_device.html" title="A model of a BLE Device from which all the BLE roles are created.">NimBLEDevice</a></code>). <br />
The security callback methods are now incorporated in the <code><a class="el" href="class_nim_b_l_e_server_callbacks.html" title="Callbacks associated with the operation of a BLE server.">NimBLEServerCallbacks</a></code> / <code><a class="el" href="class_nim_b_l_e_client_callbacks.html" title="Callbacks associated with a BLE client.">NimBLEClientCallbacks</a></code> classes.</p>
<p>The callback methods are:</p>
<blockquote class="doxtable">
<p>&zwj;<code>bool onConfirmPasskey(<a class="el" href="class_nim_b_l_e_conn_info.html" title="Connection information.">NimBLEConnInfo</a>&amp; connInfo, uint32_t pin)</code> </p>
</blockquote>
<p>Receives the pin when using numeric comparison authentication. Call <code>NimBLEDevice::injectConfirmPasskey(connInfo, true);</code> to accept or <code>NimBLEDevice::injectConfirmPasskey(connInfo, false);</code> to reject. <br />
</p>
<blockquote class="doxtable">
<p>&zwj;<code>void onPassKeyEntry(<a class="el" href="class_nim_b_l_e_conn_info.html" title="Connection information.">NimBLEConnInfo</a>&amp; connInfo)</code> </p>
</blockquote>
<p>Client callback; client should respond with the passkey (pin) by calling <code>NimBLEDevice::injectPassKey(connInfo, 123456);</code> <br />
</p>
<blockquote class="doxtable">
<p>&zwj;<code>uint32_t onPassKeyDisplay()</code> </p>
</blockquote>
<p>Server callback; should return the passkey (pin) expected from the client. <br />
</p>
<blockquote class="doxtable">
<p>&zwj;<code>void onAuthenticationComplete(<a class="el" href="class_nim_b_l_e_conn_info.html" title="Connection information.">NimBLEConnInfo</a>&amp; connInfo)</code> </p>
</blockquote>
<p>Authentication complete, success or failed information is available from the <code><a class="el" href="class_nim_b_l_e_conn_info.html" title="Connection information.">NimBLEConnInfo</a></code> methods. <br />
<br />
</p>
<p>Security settings and IO capabilities are now set by the following methods of <a class="el" href="class_nim_b_l_e_device.html" title="A model of a BLE Device from which all the BLE roles are created.">NimBLEDevice</a>. </p><blockquote class="doxtable">
<p>&zwj;<code><a class="el" href="class_nim_b_l_e_device.html#aa8e340c02418771ce72dec758d560938" title="Set the authorization mode for this device.">NimBLEDevice::setSecurityAuth(bool bonding, bool mitm, bool sc)</a></code> <code><a class="el" href="class_nim_b_l_e_device.html#abbf642ac4ce4023c7c4d9a1e4333b328" title="Set the authorization mode for this device.">NimBLEDevice::setSecurityAuth(uint8_t auth_req)</a></code> </p>
</blockquote>
<p>Sets the authorization mode for this device. <br />
<br />
</p>
<blockquote class="doxtable">
<p>&zwj;<code><a class="el" href="class_nim_b_l_e_device.html#ab9fee9e810d5fa18bc8a37053eb9b5d0" title="Set the Input/Output capabilities of this device.">NimBLEDevice::setSecurityIOCap(uint8_t iocap)</a></code> </p>
</blockquote>
<p>Sets the Input/Output capabilities of this device. <br />
<br />
</p>
<blockquote class="doxtable">
<p>&zwj;<code><a class="el" href="class_nim_b_l_e_device.html#ab0a29a11f71d3ba32645c096067a853b" title="If we are the initiator of the security procedure this sets the keys we will distribute.">NimBLEDevice::setSecurityInitKey(uint8_t init_key)</a></code> </p>
</blockquote>
<p>If we are the initiator of the security procedure this sets the keys we will distribute. <br />
<br />
</p>
<blockquote class="doxtable">
<p>&zwj;<code><a class="el" href="class_nim_b_l_e_device.html#ab769a5f5afb3ee486527d41b8c445566" title="Set the keys we are willing to accept during pairing.">NimBLEDevice::setSecurityRespKey(uint8_t resp_key)</a></code> </p>
</blockquote>
<p>Sets the keys we are willing to accept from the peer during pairing. <br />
<br />
</p>
<h1><a class="anchor" id="arduino-configuration"></a>
Arduino Configuration</h1>
<p>Unlike the original library pre-packaged in the esp32-arduino, this library has all the configuration options that are normally set in menuconfig available in the <em><a class="el" href="nimconfig_8h.html">src/nimconfig.h</a></em> file.</p>
<p>This allows Arduino users to fully customize the build, such as increasing max connections or loading the BLE stack into external PSRAM.</p>
<p>For details on the options, they are fully commented in <em><a class="el" href="nimconfig_8h.html">nimconfig.h</a></em> <br />
<br />
</p>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.8 </li>
</ul>
</div>
</body>
</html>