pabigot  0.1.1
C++ support classes
gap.hpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0 */
2 /* Copyright 2017-2019 Peter A. Bigot */
3 
8 #ifndef PABIGOT_BLE_GAP_HPP
9 #define PABIGOT_BLE_GAP_HPP
10 #pragma once
11 
12 #include <pabigot/ble.hpp>
13 #include <pabigot/byteorder.hpp>
14 
15 namespace pabigot {
16 namespace ble {
17 
24 namespace gap {
25 
28 static constexpr size_t ASR_DATA_SIZE{31};
29 
35 enum pdu_type_e : uint8_t
36 {
37  PT_ADV_IND = 0x00,
38  PT_ADV_DIRECT_IND = 0x01,
39  PT_ADV_NONCONN_IND = 0x02,
40  PT_SCAN_REQ = 0x03, // also AUX_SCAN_REQ
41  PT_SCAN_RESP = 0x04,
42  PT_CONNECT_IND = 0x05, // also AUX_CONNECT_REQ
43  PT_ADV_SCAN_IND = 0x06,
44  PT_ADV_EXT_IND = 0x07, // also AUX_{ADV,SYNC,CHAIN}_IND, AUX_SCAN_RSP
45  PT_AUX_CONNECT_RSP = 0x08,
46 };
47 
51 enum adv_event_type_e : uint8_t
52 {
53  ET_ADV_IND = 0x00,
54  ET_ADV_DIRECT_IND = 0x01,
55  ET_ADV_SCAN_IND = 0x02,
56  ET_ADV_NONCONN_IND = 0x03,
57  ET_SCAN_RSP = 0x04,
58 
65  ET_INVALID = 0x80,
66 };
67 
71 enum flags_data_type_e : uint8_t
72 {
73  FDT_LE_LIMITED = 0x01,
74  FDT_LE_GENERAL = 0x02,
75  FDT_BREDR_NOTSUP = 0x04,
76  FDT_BREDRLE_CTRL = 0x08,
77  FDT_BREDRLE_HOST = 0x10,
78 
80  FDT_LE_NON_DISCOVERABLE = FDT_BREDR_NOTSUP,
82  FDT_LE_LIMITED_DISCOVERABLE = FDT_BREDR_NOTSUP | FDT_LE_LIMITED,
84  FDT_LE_GENERAL_DISCOVERABLE = FDT_BREDR_NOTSUP | FDT_LE_GENERAL,
85 };
86 
93 enum data_type_e : uint8_t
94 {
96  DT_FLAGS = 0x01,
115  DT_CLASS_OF_DEVICE = 0x0D,
116  DT_SIMPLE_PAIRING_HASH_C192 = 0x0E,
117  DT_SIMPLE_PAIRING_RANDOMIZER_R192 = 0x0F,
118  DT_DEVICE_ID = 0x10,
119  DT_SECURITY_MANAGER_OOB_FLAGS = 0x11,
128  DT_PUBLIC_TARGET_ADDRESS = 0x17,
129  DT_RANDOM_TARGET_ADDRESS = 0x18,
130  DT_APPEARANCE = 0x19,
133  DT_LE_BLUETOOTH_DEVICE_ADDR = 0x1B,
134  DT_LE_ROLE = 0x1C,
135  DT_SIMPLE_PAIRING_HASH_C256 = 0x1D,
136  DT_SIMPLE_PAIRING_RANDOMIZER_R256 = 0x1E,
143  DT_LE_SECURE_CONN_CONFIRM_VALUE = 0x22,
144  DT_LE_SECURE_CONN_RANDOM_VALUE = 0x23,
145  DT_URI = 0x24,
146  DT_INDOOR_POSITIONING = 0x25,
147  DT_TRANSPORT_DISCOVERY_DATA = 0x26,
148  DT_LE_SUPPORTED_FEATURES = 0x27,
149  DT_CHANNEL_MAP_UPDATE_INDICATION = 0x28,
150  DT_PB_ADV = 0x29,
151  DT_MESH_MESSAGE = 0x2A,
152  DT_MESH_BEACON = 0x2B,
153  DT_3D_INFORMATION_DATA = 0x3D,
156 };
157 
167 {
168 protected:
170 
183  {
184  private:
185  friend class adv_data;
186 
187  adv_data& owner;
188  uint8_t* sp;
189 
190  store_helper (adv_data& owner_,
191  uint8_t tag,
192  size_type count) :
193  owner{owner_},
194  sp{owner.bp_}
195  {
196  // Increase span to cover the type tag.
197  auto span = count + sizeof(tag);
198  auto span_octet = static_cast<uint8_t>(span);
199 
200  // Valid requires representable span and available space
201  if ((span_octet == span)
202  && owner.can_advance(sizeof(*sp) + span)) {
203  // Store the expected length and the tag
204  owner.append(span_octet);
205  owner.append(tag);
206  } else {
207  sp = nullptr;
208  owner.invalidate();
209  }
210  }
211  public:
213  explicit operator bool() const noexcept
214  {
215  return sp;
216  }
217 
221  {
222  /* If the owner is valid, construction succeeded, and the pointer
223  * advanced past where it was left in construction, then we can and
224  * should update length to match the used region. */
225  if (owner.valid()
226  && sp
227  && ((sp + 2U) != owner.bp_)) {
228  /* Length is anything past the length octet. Invalidate if the span
229  * doesn't fit in an octet. */
230  auto span = owner.bp_ - sp - 1U;
231  if (static_cast<uint8_t>(span) == span) {
232  *sp = span;
233  } else {
234  owner.invalidate();
235  }
236  }
237  }
238  };
239 
240  template <typename uuid_type>
241  void store_uuids (uint8_t dt,
242  const uuid_type* begin,
243  const uuid_type* end);
244 
245 public:
253  adv_data (uint8_t* begin,
254  uint8_t* end) :
255  super{begin, end}
256  { }
257 
259  template <size_t count>
260  adv_data (std::array<uint8_t, count>& src) :
261  super{src.begin(), src.end()}
262  { }
263 
268  const uint8_t* data () const noexcept
269  {
270  return static_cast<const uint8_t *>(begin());
271  }
272 
301  [[nodiscard]] store_helper start_store (uint8_t tag,
302  size_type count)
303  {
304  return {*this, tag, count};
305  }
306 
310  void set_Flags (unsigned int flags);
311 
318  void set_ShortenedLocalName (const char* name,
319  ptrdiff_t count = -1);
320 
329  void set_CompleteLocalName (const char* name,
330  ptrdiff_t count = -1);
331 
335  void set_TXPowerLevel (int8_t txPower);
336 
343  template <typename uuid_type>
344  void set_CompleteListServiceUUID (const uuid_type& uuid)
345  {
346  return set_CompleteListServiceUUID(&uuid, 1 + &uuid);
347  }
348 
357  template <typename uuid_type>
358  void set_CompleteListServiceUUID (const uuid_type* begin,
359  const uuid_type* end);
360 
367  template <typename uuid_type>
368  void set_IncompleteListServiceUUID (const uuid_type& uuid)
369  {
370  return set_IncompleteListServiceUUID(&uuid, 1 + &uuid);
371  }
372 
381  template <typename uuid_type>
382  void set_IncompleteListServiceUUID (const uuid_type* begin,
383  const uuid_type* end);
384 
391  template <typename uuid_type>
392  void set_ListServiceSolicitationUUID (const uuid_type& uuid)
393  {
394  return set_ListServiceSolicitationUUID(&uuid, 1 + &uuid);
395  }
396 
405  template <typename uuid_type>
406  void set_ListServiceSolicitationUUID (const uuid_type* begin,
407  const uuid_type* end);
408 
421  template <typename uuid_type>
422  uint8_t* set_ServiceData (const uuid_type& uuid,
423  const uint8_t* begin,
424  const uint8_t* end);
425 
436  template <typename uuid_type,
437  std::size_t len>
438  uint8_t* set_ServiceData (const uuid_type& uuid,
439  const std::array<uint8_t, len>& data)
440  {
441  return set_ServiceData(uuid, data.begin(), data.end());
442  }
443 
456  template <typename uuid_type>
457  uint8_t* set_ServiceData (const uuid_type& uuid,
458  const void* buf,
459  size_t count)
460  {
461  auto ptr = static_cast<const uint8_t*>(buf);
462  return set_ServiceData(uuid, ptr, ptr + count);
463  }
464 
469  void set_AdvertisingInterval (uint16_t advInterval);
470 
484  void set_SlaveConnectionIntervalRange (uint16_t connIntervalMin,
485  uint16_t connIntervalMax);
486 
502  void* set_ManufacturerSpecificData (uint16_t companyID,
503  size_t span);
504 };
505 
507 template <>
509  const uuid16_type* end);
510 template <>
512  const uuid32_type* end);
513 template <>
515  const uuid128_type* end);
516 template <>
518  const uuid16_type* end);
519 template <>
521  const uuid32_type* end);
522 template <>
524  const uuid128_type* end);
525 template <>
527  const uuid16_type* end);
528 template <>
530  const uuid32_type* end);
531 template <>
533  const uuid128_type* end);
534 template <>
535 uint8_t*
537  const uint8_t* begin,
538  const uint8_t* end);
539 template <>
540 uint8_t*
542  const uint8_t* begin,
543  const uint8_t* end);
544 template <>
545 uint8_t*
547  const uint8_t* begin,
548  const uint8_t* end);
551 } // ns gap
552 } // ns ble
553 } // ns pabigot
554 
555 #endif /* PABIGOT_BLE_GAP_HPP */
pabigot::ble::gap::DT_UUID128_COMPLETE
adv_data::set_CompleteListServiceUUID()
Definition: gap.hpp:108
pabigot::ble::gap::adv_data::set_CompleteLocalName
void set_CompleteLocalName(const char *name, ptrdiff_t count=-1)
Helper to set the complete local name.
pabigot::byteorder::octets_helper::begin
const void * begin() const noexcept
Get a pointer to the start of buffer.
Definition: byteorder.hpp:372
pabigot::ble::gap::adv_data::start_store
store_helper start_store(uint8_t tag, size_type count)
Reserve space for a data type record.
Definition: gap.hpp:301
pabigot::ble::gap::DT_SHORTENED_LOCAL_NAME
adv_data::set_ShortenedLocalName()
Definition: gap.hpp:110
ble.hpp
Infrastructure supporting Bluetooth Low Energy.
pabigot::byteorder::octets_helper
Infrastructure to fill an octet buffer with data.
Definition: byteorder.hpp:310
pabigot::ble::gap::DT_UUID16_INCOMPLETE
adv_data::set_IncompleteListServiceUUID()
Definition: gap.hpp:98
pabigot::ble::gap::FDT_LE_NON_DISCOVERABLE
BT-5v3C9.2.2 LE-only not discoverable.
Definition: gap.hpp:80
pabigot::byteorder::octets_helper::append
bool append(const void *sp, size_type span) noexcept
Append a value to the buffer.
Definition: byteorder.hpp:452
pabigot::ble::gap::adv_data
Infrastructure to fill in Advertising and Scan Response Data.
Definition: gap.hpp:166
pabigot::ble::gap::DT_UUID32_COMPLETE
adv_data::set_CompleteListServiceUUID()
Definition: gap.hpp:104
pabigot::ble::gap::DT_UUID16_COMPLETE
adv_data::set_CompleteListServiceUUID()
Definition: gap.hpp:100
pabigot::ble::gap::DT_UUID128_INCOMPLETE
adv_data::set_IncompleteListServiceUUID()
Definition: gap.hpp:106
pabigot::ble::gap::adv_data::store_helper
RAII helper to avoid overruns and to back-fill lengths.
Definition: gap.hpp:182
pabigot::byteorder::octets_helper::end
const void * end() const noexcept
Get a pointer to the end of the filled part of the buffer.
Definition: byteorder.hpp:382
pabigot::ble::gap::DT_SERVICE_SOLICITATION_UUID16
adv_data::set_ListServiceSolicitationUUID()
Definition: gap.hpp:123
pabigot::ble::gap::DT_SERVICE_DATA_UUID16
adv_data::set_ServiceData()
Definition: gap.hpp:127
byteorder.hpp
Support for byte order manipulation and packed storage.
pabigot::ble::gap::adv_data::set_TXPowerLevel
void set_TXPowerLevel(int8_t txPower)
Helper to set the TX Power Level data value.
pabigot::ble::gap::DT_SERVICE_DATA_UUID128
adv_data::set_ServiceData()
Definition: gap.hpp:142
pabigot::ble::gap::adv_data::set_ShortenedLocalName
void set_ShortenedLocalName(const char *name, ptrdiff_t count=-1)
Helper to set the shortened local name.
pabigot::ble::gap::adv_data::set_IncompleteListServiceUUID
void set_IncompleteListServiceUUID(const uuid_type &uuid)
Helper for incomplete listing a single UUID service.
Definition: gap.hpp:368
pabigot::ble::gap::adv_data::set_Flags
void set_Flags(unsigned int flags)
Helper to set the Flags data value.
pabigot::ble::gap::pdu_type_e
pdu_type_e
Advertising PDU type.
Definition: gap.hpp:35
pabigot::ble::gap::adv_data::set_AdvertisingInterval
void set_AdvertisingInterval(uint16_t advInterval)
Helper to set the Advertising Interval data value.
pabigot::ble::gap::DT_SERVICE_DATA_UUID32
adv_data::set_ServiceData()
Definition: gap.hpp:140
pabigot::byteorder::octets_helper::invalidate
void invalidate() noexcept
Explicitly mark the buffer invalid.
Definition: byteorder.hpp:364
pabigot::ble::gap::DT_TX_POWER_LEVEL
adv_data::set_TXPowerLevel
Definition: gap.hpp:114
pabigot::ble::gap::DT_COMPLETE_LOCAL_NAME
adv_data::set_CompleteLocalName()
Definition: gap.hpp:112
pabigot::byteorder::octets_helper::valid
const bool valid() const noexcept
Indicates whether advance() caused an error.
Definition: byteorder.hpp:355
pabigot::ble::gap::FDT_LE_LIMITED_DISCOVERABLE
BT-5v3C9.2.3 LE-only short-term discoverable.
Definition: gap.hpp:82
pabigot::ble::gap::adv_data::store_helper::~store_helper
~store_helper()
Destructor updates length field if content was added since construction.
Definition: gap.hpp:220
pabigot::ble::gap::flags_data_type_e
flags_data_type_e
Bits and values for DT_FLAGS.
Definition: gap.hpp:71
pabigot::ble::gap::FDT_LE_GENERAL_DISCOVERABLE
BT-5v3C9.2.4 LE-only long-term discoverable.
Definition: gap.hpp:84
pabigot::ble::gap::adv_data::set_ServiceData
uint8_t * set_ServiceData(const uuid_type &uuid, const void *buf, size_t count)
Helper to set service data.
Definition: gap.hpp:457
pabigot::ble::gap::DT_SERVICE_SOLICITATION_UUID32
adv_data::set_ListServiceSolicitationUUID()
Definition: gap.hpp:138
pabigot::ble::gap::adv_event_type_e
adv_event_type_e
Advertising Event Type.
Definition: gap.hpp:51
pabigot::ble::gap::adv_data::adv_data
adv_data(std::array< uint8_t, count > &src)
Construct from a std::array reference.
Definition: gap.hpp:260
pabigot::byteorder::octets_helper::size_type
std::size_t size_type
Type used for span values.
Definition: byteorder.hpp:314
pabigot::ble::gap::DT_ADVERTISING_INTERVAL
adv_data::set_AdvertisingInterval
Definition: gap.hpp:132
pabigot::ble::gap::adv_data::set_CompleteListServiceUUID
void set_CompleteListServiceUUID(const uuid_type &uuid)
Helper for complete listing of a single UUID service.
Definition: gap.hpp:344
pabigot
Root for all pabigot namespaces.
Definition: gap.hpp:15
pabigot::ble::gap::adv_data::set_ManufacturerSpecificData
void * set_ManufacturerSpecificData(uint16_t companyID, size_t span)
Helper to set Manufacturer Specific Data.
pabigot::ble::gap::adv_data::set_ServiceData
uint8_t * set_ServiceData(const uuid_type &uuid, const uint8_t *begin, const uint8_t *end)
Helper to set service data.
pabigot::ble::gap::adv_data::set_SlaveConnectionIntervalRange
void set_SlaveConnectionIntervalRange(uint16_t connIntervalMin, uint16_t connIntervalMax)
Helper to set the preferred connectional interval range.
pabigot::ble::gap::DT_FLAGS
adv_data::set_Flags() CSSv7A1.3
Definition: gap.hpp:96
pabigot::ble::gap::DT_UUID32_INCOMPLETE
adv_data::set_IncompleteListServiceUUID()
Definition: gap.hpp:102
pabigot::ble::gap::ET_INVALID
Indicates an invalid event type flag.
Definition: gap.hpp:65
pabigot::ble::gap::DT_SLAVE_CONNECTION_INTERVAL_RANGE
adv_data::set_SlaveConnectionIntervalRange
Definition: gap.hpp:121
pabigot::ble::gap::adv_data::adv_data
adv_data(uint8_t *begin, uint8_t *end)
Reference an octet sequence into which advertising data will be written.
Definition: gap.hpp:253
pabigot::ble::uuid32_type
32-bit UUID type stored as a little-endian byte sequence.
Definition: ble.hpp:165
pabigot::ble::gap::DT_MANUFACTURER_SPECIFIC_DATA
adv_data::set_ManufacturerSpecificData
Definition: gap.hpp:155
pabigot::ble::gap::ASR_DATA_SIZE
static constexpr size_t ASR_DATA_SIZE
Number of octets available for a standard advertising or scan response data packet.
Definition: gap.hpp:28
pabigot::ble::gap::adv_data::set_ServiceData
uint8_t * set_ServiceData(const uuid_type &uuid, const std::array< uint8_t, len > &data)
Helper to set service data.
Definition: gap.hpp:438
pabigot::byteorder::octets_helper::can_advance
bool can_advance(size_type s) const noexcept
Indicate whether advance() would succeed for a given span.
Definition: byteorder.hpp:437
pabigot::ble::gap::adv_data::data
const uint8_t * data() const noexcept
Get a typed pointer to the start of the buffer.
Definition: gap.hpp:268
pabigot::ble::gap::data_type_e
data_type_e
GAP assigned numbers for data type values.
Definition: gap.hpp:93
pabigot::ble::gap::adv_data::set_ListServiceSolicitationUUID
void set_ListServiceSolicitationUUID(const uuid_type &uuid)
Helper for listing a single service solicitation UUID.
Definition: gap.hpp:392
pabigot::ble::gap::DT_SERVICE_SOLICITATION_UUID128
adv_data::set_ListServiceSolicitationUUID()
Definition: gap.hpp:125
pabigot::ble::uuid128_type
Basic holder for 128-bit UUIDs stored as a little-endian byte sequence.
Definition: ble.hpp:217
pabigot::ble::uuid16_type
16-bit UUID type stored as a little-endian byte sequence.
Definition: ble.hpp:132