blob: d2c126d5f2d32c9a7bb9cd8d51703bd7ede736b3 [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>Characteristic Access &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="BLE Peripheral Project" href="../bleprph.html"/>
<link rel="next" title="Advertising" href="bleprph-adv.html"/>
<link rel="prev" title="Service Registration" href="bleprph-svc-reg.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.12.0, Apache NimBLE 1.7.0 </a> released April 4, 2024)
</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> /
<a href="../bleprph.html">BLE Peripheral Project</a> /
Characteristic Access
<div class="sourcelink">
<a href="https://github.com/apache/mynewt-documentation/edit/master/docs/tutorials/ble/bleprph/bleprph-sections/bleprph-chr-access.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_12_0" >
Version: 1.12.0
</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"><a class="reference internal" href="../../eddystone.html">BLE Eddystone</a></li>
<li class="toctree-l3 current"><a class="reference internal" href="../bleprph.html">BLE Peripheral Project</a><ul class="current">
<li class="toctree-l4"><a class="reference internal" href="bleprph-svc-reg.html">Service Registration</a></li>
<li class="toctree-l4 current"><a class="current reference internal" href="#">Characteristic Access</a></li>
<li class="toctree-l4"><a class="reference internal" href="bleprph-adv.html">Advertising</a></li>
<li class="toctree-l4"><a class="reference internal" href="bleprph-gap-event.html">GAP Event callbacks</a></li>
<li class="toctree-l4"><a class="reference internal" href="bleprph-app.html">BLE Peripheral App</a></li>
</ul>
</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="characteristic-access">
<h1>Characteristic Access<a class="headerlink" href="#characteristic-access" title="Permalink to this headline">¶</a></h1>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><p><a class="reference internal" href="#review" id="id1">Review</a></p></li>
<li><p><a class="reference internal" href="#function-signature" id="id2">Function signature</a></p></li>
<li><p><a class="reference internal" href="#determine-characteristic-being-accessed" id="id3">Determine characteristic being accessed</a></p></li>
<li><p><a class="reference internal" href="#read-access" id="id4">Read access</a></p></li>
<li><p><a class="reference internal" href="#write-access" id="id5">Write access</a></p></li>
</ul>
</div>
<div class="section" id="review">
<h2><a class="toc-backref" href="#id1">Review</a><a class="headerlink" href="#review" title="Permalink to this headline">¶</a></h2>
<p>A characteristic’s access callback implements its behavior. Recall that
services and characteristics are registered with NimBLE via attribute
tables. Each characteristic definition in an attribute table contains an
<em>access_cb</em> field. The <em>access_cb</em> field is an application callback
that gets executed whenever a peer device attempts to read or write the
characteristic.</p>
<p>Earlier in this tutorial, we looked at how <em>bleprph</em> implements the GAP
service. Let’s take another look at how <em>bleprph</em> specifies the first
few characteristics in this service.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</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_gatt_svc_def</span><span class="w"> </span><span class="n">gatt_svr_svcs</span><span class="p">[]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/*** Service: Security test. */</span>
<span class="w"> </span><span class="p">.</span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BLE_GATT_SVC_TYPE_PRIMARY</span><span class="p">,</span>
<span class="w"> </span><span class="p">.</span><span class="n">uuid</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">gatt_svr_svc_sec_test_uuid</span><span class="p">.</span><span class="n">u</span><span class="p">,</span>
<span class="w"> </span><span class="p">.</span><span class="n">characteristics</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_gatt_chr_def</span><span class="p">[])</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/*** Characteristic: Random number generator. */</span>
<span class="w"> </span><span class="p">.</span><span class="n">uuid</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">gatt_svr_chr_sec_test_rand_uuid</span><span class="p">.</span><span class="n">u</span><span class="p">,</span>
<span class="w"> </span><span class="p">.</span><span class="n">access_cb</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">gatt_svr_chr_access_sec_test</span><span class="p">,</span>
<span class="w"> </span><span class="p">.</span><span class="n">flags</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BLE_GATT_CHR_F_READ</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">BLE_GATT_CHR_F_READ_ENC</span><span class="p">,</span>
<span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="cm">/*** Characteristic: Static value. */</span>
<span class="w"> </span><span class="p">.</span><span class="n">uuid</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">gatt_svr_chr_sec_test_static_uuid</span><span class="p">.</span><span class="n">u</span><span class="p">,</span>
<span class="w"> </span><span class="p">.</span><span class="n">access_cb</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">gatt_svr_chr_access_sec_test</span><span class="p">,</span>
<span class="w"> </span><span class="p">.</span><span class="n">flags</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BLE_GATT_CHR_F_READ</span><span class="w"> </span><span class="o">|</span>
<span class="w"> </span><span class="n">BLE_GATT_CHR_F_WRITE</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">BLE_GATT_CHR_F_WRITE_ENC</span><span class="p">,</span>
<span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="c1">// [...]</span>
</pre></div>
</div>
<p>As you can see, <em>bleprph</em> uses the same <em>access_cb</em> function for all
the GAP service characteristics, but the developer could have
implemented separate functions for each characteristic if they
preferred. Here is the <em>access_cb</em> function that the GAP service
characteristics use:</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="kt">int</span>
<span class="nf">gatt_svr_chr_access_sec_test</span><span class="p">(</span><span class="kt">uint16_t</span><span class="w"> </span><span class="n">conn_handle</span><span class="p">,</span><span class="w"> </span><span class="kt">uint16_t</span><span class="w"> </span><span class="n">attr_handle</span><span class="p">,</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">ble_gatt_access_ctxt</span><span class="w"> </span><span class="o">*</span><span class="n">ctxt</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">arg</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">ble_uuid_t</span><span class="w"> </span><span class="o">*</span><span class="n">uuid</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rand_num</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">uuid</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ctxt</span><span class="o">-&gt;</span><span class="n">chr</span><span class="o">-&gt;</span><span class="n">uuid</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/* Determine which characteristic is being accessed by examining its</span>
<span class="cm"> * 128-bit UUID.</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ble_uuid_cmp</span><span class="p">(</span><span class="n">uuid</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">gatt_svr_chr_sec_test_rand_uuid</span><span class="p">.</span><span class="n">u</span><span class="p">)</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="p">{</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="n">ctxt</span><span class="o">-&gt;</span><span class="n">op</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">BLE_GATT_ACCESS_OP_READ_CHR</span><span class="p">);</span>
<span class="w"> </span><span class="cm">/* Respond with a 32-bit random number. */</span>
<span class="w"> </span><span class="n">rand_num</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rand</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">os_mbuf_append</span><span class="p">(</span><span class="n">ctxt</span><span class="o">-&gt;</span><span class="n">om</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">rand_num</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="w"> </span><span class="n">rand_num</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </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="w"> </span><span class="o">?</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">BLE_ATT_ERR_INSUFFICIENT_RES</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ble_uuid_cmp</span><span class="p">(</span><span class="n">uuid</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">gatt_svr_chr_sec_test_static_uuid</span><span class="p">.</span><span class="n">u</span><span class="p">)</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="p">{</span>
<span class="w"> </span><span class="k">switch</span><span class="w"> </span><span class="p">(</span><span class="n">ctxt</span><span class="o">-&gt;</span><span class="n">op</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">BLE_GATT_ACCESS_OP_READ_CHR</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">os_mbuf_append</span><span class="p">(</span><span class="n">ctxt</span><span class="o">-&gt;</span><span class="n">om</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">gatt_svr_sec_test_static_val</span><span class="p">,</span>
<span class="w"> </span><span class="k">sizeof</span><span class="w"> </span><span class="n">gatt_svr_sec_test_static_val</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </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="w"> </span><span class="o">?</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">BLE_ATT_ERR_INSUFFICIENT_RES</span><span class="p">;</span>
<span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="no">BLE_GATT_ACCESS_OP_WRITE_CHR</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">gatt_svr_chr_write</span><span class="p">(</span><span class="n">ctxt</span><span class="o">-&gt;</span><span class="n">om</span><span class="p">,</span>
<span class="w"> </span><span class="k">sizeof</span><span class="w"> </span><span class="n">gatt_svr_sec_test_static_val</span><span class="p">,</span>
<span class="w"> </span><span class="k">sizeof</span><span class="w"> </span><span class="n">gatt_svr_sec_test_static_val</span><span class="p">,</span>
<span class="w"> </span><span class="o">&amp;</span><span class="n">gatt_svr_sec_test_static_val</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">rc</span><span class="p">;</span>
<span class="w"> </span><span class="k">default</span><span class="o">:</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">BLE_ATT_ERR_UNLIKELY</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="cm">/* Unknown characteristic; the nimble stack should not have called this</span>
<span class="cm"> * function.</span>
<span class="cm"> */</span>
<span class="w"> </span><span class="n">assert</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">BLE_ATT_ERR_UNLIKELY</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>After you’ve taken a moment to examine the structure of this function,
let’s explore some details.</p>
</div>
<div class="section" id="function-signature">
<h2><a class="toc-backref" href="#id2">Function signature</a><a class="headerlink" href="#function-signature" title="Permalink to this headline">¶</a></h2>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="kt">int</span>
<span class="n">gatt_svr_chr_access_sec_test</span><span class="p">(</span><span class="kt">uint16_t</span><span class="w"> </span><span class="n">conn_handle</span><span class="p">,</span><span class="w"> </span><span class="kt">uint16_t</span><span class="w"> </span><span class="n">attr_handle</span><span class="p">,</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">ble_gatt_access_ctxt</span><span class="w"> </span><span class="o">*</span><span class="n">ctxt</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">arg</span><span class="p">)</span>
</pre></div>
</div>
<p>A characteristic access function always takes this same set of
parameters and always returns an int. The parameters to this function
type are documented below.</p>
<table class="docutils align-default">
<colgroup>
<col style="width: 38%" />
<col style="width: 33%" />
<col style="width: 29%" />
</colgroup>
<thead>
<tr class="row-odd"><th class="head"><p><strong>Parameter</strong></p></th>
<th class="head"><p><strong>Purpose</strong></p></th>
<th class="head"><p><strong>Notes</strong></p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>conn_handle</p></td>
<td><p>Indicates
which
connection
the
characterist
ic
access was
sent over.</p></td>
<td><p>Use this
value to
determine
which peer
is
accessing
the
characteri
stic.</p></td>
</tr>
<tr class="row-odd"><td><p>attr_handle</p></td>
<td><p>The
low-level
ATT handle
of the
characterist
ic
value
attribute.</p></td>
<td><p>Can be
used to
determine
which
characteri
stic
is being
accessed
if you
don’t want
to perform
a UUID
lookup.</p></td>
</tr>
<tr class="row-even"><td><p>ctxt</p></td>
<td><p>Contains the
characterist
ic
value
pointer that
the
application
needs to
access.</p></td>
<td><p>For
characteri
stic
accesses,
use the
<em>ctxt-&gt;chr
_access</em>
member;
for
descriptor
accesses,
use the
<em>ctxt-&gt;dsc
_access</em>
member.</p></td>
</tr>
</tbody>
</table>
<p>The return value of the access function tells the NimBLE stack how to
respond to the peer performing the operation. A value of 0 indicates
success. For failures, the function returns the specific ATT error code
that the NimBLE stack should respond with. The ATT error codes are
defined in
<a class="reference external" href="https://github.com/apache/incubator-mynewt-core/blob/master/net/nimble/host/include/host/ble_att.h">net/nimble/host/include/host/ble_att.h</a>.</p>
</div>
<div class="section" id="determine-characteristic-being-accessed">
<h2><a class="toc-backref" href="#id3">Determine characteristic being accessed</a><a class="headerlink" href="#determine-characteristic-being-accessed" title="Permalink to this headline">¶</a></h2>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">ble_uuid_cmp</span><span class="p">(</span><span class="n">uuid</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">gatt_svr_chr_sec_test_rand_uuid</span><span class="p">.</span><span class="n">u</span><span class="p">)</span>
</pre></div>
</div>
<p>The function compares UUID with UUIDs of characteristic - if it fits,
characteristic is being accessed. There are two alternative methods <em>bleprph</em>
could have used to accomplish this task:</p>
<ul class="simple">
<li><p>Map characteristics to ATT handles during service registration; use
the <em>attr_handle</em> parameter as a key into this table during
characteristic access.</p></li>
<li><p>Implement a dedicated function for each characteristic; each function
inherently knows which characteristic it corresponds to.</p></li>
</ul>
</div>
<div class="section" id="read-access">
<h2><a class="toc-backref" href="#id4">Read access</a><a class="headerlink" href="#read-access" title="Permalink to this headline">¶</a></h2>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">case</span><span class="w"> </span><span class="no">BLE_GATT_ACCESS_OP_READ_CHR</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">os_mbuf_append</span><span class="p">(</span><span class="n">ctxt</span><span class="o">-&gt;</span><span class="n">om</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">gatt_svr_sec_test_static_val</span><span class="p">,</span>
<span class="w"> </span><span class="k">sizeof</span><span class="w"> </span><span class="n">gatt_svr_sec_test_static_val</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </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="w"> </span><span class="o">?</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">BLE_ATT_ERR_INSUFFICIENT_RES</span><span class="p">;</span>
</pre></div>
</div>
<p>This code excerpt handles read accesses to the device characteristic.
<em>ctxt-&gt;om</em> is chained memory buffer that for reads is being populated
with characteristic data. Returned value is either 0 for success or
<em>BLE_ATT_ERR_INSUFFICIENT_RES</em> if failed. The check makes sure the
NimBLE stack is doing its job; this characteristic was registered as
read-only, so the stack should have prevented write accesses.</p>
</div>
<div class="section" id="write-access">
<h2><a class="toc-backref" href="#id5">Write access</a><a class="headerlink" href="#write-access" title="Permalink to this headline">¶</a></h2>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">static</span><span class="w"> </span><span class="kt">int</span>
<span class="nf">gatt_svr_chr_write</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">os_mbuf</span><span class="w"> </span><span class="o">*</span><span class="n">om</span><span class="p">,</span><span class="w"> </span><span class="kt">uint16_t</span><span class="w"> </span><span class="n">min_len</span><span class="p">,</span><span class="w"> </span><span class="kt">uint16_t</span><span class="w"> </span><span class="n">max_len</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">dst</span><span class="p">,</span><span class="w"> </span><span class="kt">uint16_t</span><span class="w"> </span><span class="o">*</span><span class="n">len</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="kt">uint16_t</span><span class="w"> </span><span class="n">om_len</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">om_len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">OS_MBUF_PKTLEN</span><span class="p">(</span><span class="n">om</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">om_len</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">min_len</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">om_len</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">max_len</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN</span><span class="p">;</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_hs_mbuf_to_flat</span><span class="p">(</span><span class="n">om</span><span class="p">,</span><span class="w"> </span><span class="n">dst</span><span class="p">,</span><span class="w"> </span><span class="n">max_len</span><span class="p">,</span><span class="w"> </span><span class="n">len</span><span class="p">);</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </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="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">BLE_ATT_ERR_UNLIKELY</span><span class="p">;</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// [...]</span>
<span class="k">case</span><span class="w"> </span><span class="no">BLE_GATT_ACCESS_OP_WRITE_CHR</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">gatt_svr_chr_write</span><span class="p">(</span><span class="n">ctxt</span><span class="o">-&gt;</span><span class="n">om</span><span class="p">,</span>
<span class="w"> </span><span class="k">sizeof</span><span class="w"> </span><span class="n">gatt_svr_sec_test_static_val</span><span class="p">,</span>
<span class="w"> </span><span class="k">sizeof</span><span class="w"> </span><span class="n">gatt_svr_sec_test_static_val</span><span class="p">,</span>
<span class="w"> </span><span class="o">&amp;</span><span class="n">gatt_svr_sec_test_static_val</span><span class="p">,</span><span class="w"> </span><span class="nb">NULL</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">rc</span><span class="p">;</span>
</pre></div>
</div>
<p>This code excerpt handles writes to the Static value
characteristic. This characteristic was registered as read-write, so the
<em>return rc</em> here is just a safety precaution to ensure the NimBLE stack
is doing its job.</p>
<p>Data is written to the <em>ctxt-&gt;om</em> buffer from <em>gatt_svr_sec_test_static_val</em>
by <code class="docutils literal notranslate"><span class="pre">ble_hs_mbuf_to_flat()</span></code> function. If length of written data greater or
smaller than length of <em>gatt_svr_sec_test_static_val</em>, function return error.</p>
<p>Many characteristics have strict length requirements for write
operations.</p>
</div>
</div>
</div>
</div>
<div class="rst-footer-buttons row" role="navigation" aria-label="footer navigation">
<a href="bleprph-adv.html" class="btn btn-neutral float-right" title="Advertising" accesskey="n">Next: Advertising <span class="fa fa-arrow-circle-right"></span></a>
<a href="bleprph-svc-reg.html" class="btn btn-neutral" title="Service Registration" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous: Service Registration</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>