{"id":997,"date":"2022-05-22T02:51:58","date_gmt":"2022-05-22T06:51:58","guid":{"rendered":"https:\/\/jausoft.com\/blog\/?p=997"},"modified":"2023-04-19T09:11:40","modified_gmt":"2023-04-19T13:11:40","slug":"direct-bt-implementation-details-pt1","status":"publish","type":"post","link":"https:\/\/jausoft.com\/blog\/2022\/05\/22\/direct-bt-implementation-details-pt1\/","title":{"rendered":"Direct-BT C++ Implementation Details (Part 1)"},"content":{"rendered":"<p>This is the first article covering <a href=\"https:\/\/jausoft.com\/cgit\/direct_bt.git\/about\/\"><em>Direct-BT<\/em><\/a>&#8216;s implementation details including <a href=\"https:\/\/jausoft.com\/cgit\/jaulib.git\/about\/\">jaulib<\/a>.<\/p>\n<p>See <a href=\"https:\/\/jausoft.com\/blog\/2022\/05\/22\/direct-bt-bluetooth-server-and-client-programming-in-cpp-and-java_pt1\/\"><em>Direct-BT, Bluetooth Server and Client Programming in C++ and Java (Part 1)<\/em><\/a> for a little introduction to Direct-BT.<\/p>\n<h2>Standard and Proprietary Communication Channels<\/h2>\n<p>As described, we were required to utilize the host Bluetooth implementation in the GNU\/Linux kernel, i.e. BlueZ\/Kernel directly without D-Bus to achieve best performance and access the native HCI, L2CAP\/GATT and SMP communication channels directly.<!--more--><\/p>\n<p>By mostly using the standard protocols, the implementation is almost platform agnostic. However, the Bluetooth adapter management as well as the SMP security level setup is done via the proprietary <em>BlueZ\/Kernel Manager control channel<\/em>.<br \/>\nPorting Direct-BT to different platform, we would need create alternatives for these relatively small portions<\/p>\n<p>In detail, we have the following 3 channels connected via sockets:<\/p>\n<ul>\n<li>Proprietary <a href=\"https:\/\/jausoft.com\/projects\/direct_bt\/build\/documentation\/cpp\/html\/classdirect__bt_1_1BTManager.html\"><em>BlueZ\/Kernel Manager <\/em><\/a><\/li>\n<li><a href=\"https:\/\/jausoft.com\/projects\/direct_bt\/build\/documentation\/cpp\/html\/classdirect__bt_1_1HCIHandler.html\">HCI used for control<\/a> as well as receiving <a href=\"https:\/\/jausoft.com\/projects\/direct_bt\/build\/documentation\/cpp\/html\/classdirect__bt_1_1SMPPDUMsg.html\">SMP communication<\/a><\/li>\n<li><a href=\"https:\/\/jausoft.com\/projects\/direct_bt\/build\/documentation\/cpp\/html\/classdirect__bt_1_1BTGattHandler.html\">L2CAP\/GATT client\/server<\/a> device communication via <a href=\"https:\/\/jausoft.com\/projects\/direct_bt\/build\/documentation\/cpp\/html\/classdirect__bt_1_1AttPDUMsg.html\">ATT PDU messages<\/a>.<\/li>\n<\/ul>\n<p>Each connection utilizes a lock-free <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1ringbuffer.html\"><em>ringbuffer&lt;T&gt;<\/em><\/a> for asynchronous access, which gets filled by their own packet-reader thread. The socket connection also allows sending commands to the underlying Bluetooth host implementation, which shall forward them to the Bluetooth adapter &#8211; except for the proprietary <em>Manager control channel<\/em>.<\/p>\n<p>One HCI socket connection per <a href=\"https:\/\/jausoft.com\/projects\/direct_bt\/build\/documentation\/cpp\/html\/classdirect__bt_1_1BTAdapter.html\">BTAdapter<\/a> is used and one L2CAP\/GATT socket per <a href=\"https:\/\/jausoft.com\/projects\/direct_bt\/build\/documentation\/cpp\/html\/classdirect__bt_1_1BTDevice.html\">BTDevice<\/a> connection.<\/p>\n<p>Since the BlueZ\/Kernel is sadly not allowing a direct <a href=\"https:\/\/jausoft.com\/projects\/direct_bt\/build\/documentation\/cpp\/html\/classdirect__bt_1_1SMPHandler.html\">SMP socket connection<\/a>, we filter the <a href=\"https:\/\/jausoft.com\/projects\/direct_bt\/build\/documentation\/cpp\/html\/classdirect__bt_1_1SMPPDUMsg.html\">SMP packets<\/a> from the <a href=\"https:\/\/jausoft.com\/projects\/direct_bt\/build\/documentation\/cpp\/html\/HCIHandler_8cpp_source.html#l00440\">HCI channel<\/a> and direct them to the associated BTAdapter.<\/p>\n<h2><em>Dirty<\/em> down to the metal details&#8230;<\/h2>\n<h3>Endian Order and Byte Alignment<\/h3>\n<p>Direct-BT is <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/group__ByteUtils.html#ga69993d795094ca823f6eec1a218462b0\">endian order agnostic<\/a>, performing all required transformations from Bluetooth <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/group__ByteUtils.html#details\">little-endian to host-endian order<\/a> and back. To avoid <em>memcpy() <\/em>to compensate for address alignment, we utilize the <em>free of costs<\/em> high performance <em>compiler magic<\/em> &#8216;struct <b>attribute<\/b>((<b>packed<\/b>))&#8217; as provided via <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/structjau_1_1packed__t.html#packed_t_alignment_cast\">jau::packed_t&lt; T &gt;&#8217;s alignment cast<\/a>.<\/p>\n<h3>Concurrency, or how to be not just multi-threaded<\/h3>\n<p>Mutli-threading is often sabotaged when CPU cores block each other and squash parallel processing and hence<a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/group__Concurrency.html#details\"> concurrency<\/a>.<\/p>\n<p>To achieve efficient parallelism while avoiding any deadlock situation, we use lock-free data structures.<\/p>\n<p>The <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1ringbuffer.html\">ringbuffer&lt;T&gt;<\/a> <em>stack-alike<\/em> storage essentially decouples the producer from the consumer thread without locking while avoiding moving its content around, since storage is handled as a ring without a start or end unlike a stack has.<br \/>\nLocking is only performed when the consumer requests to block until data is available or the producer awaits free space. Otherwise only atomic cash reloading iterator are utilized, allowing non-overlapping parallel read and write access.<br \/>\nThe <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1ringbuffer.html\">ringbuffer&lt;T&gt;<\/a> is used in Direct-BT for all socket connection receiver-threads to store asynchronous replies.<\/p>\n<p>The <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1cow__darray.html\">copy-on-write (CoW) cow_darray&lt;T&gt;<\/a> container also decouples the reader from the writer thread, while enjoying random-access properties of a container. Here we simply replace the underlying shared atomic <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1darray.html\">darray&lt;T&gt;<\/a> reference when the write operation is completed. This allows lock-free read access while another thread is mutating the content in parallel using the compromise that the reader thread may deal with an slightly older dataset.<br \/>\nTo implement <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1cow__darray.html\">cow_darray&lt;T&gt;<\/a> we also had to implement and use <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1darray.html\">darray&lt;T&gt;<\/a> to grant us fine control of the underlying data inclusive their iterator types &#8211; instead of simply using std::vector&lt;T&gt;.<br \/>\nThe CoW container is used in Direct-BT for lock-free listener and callback maintenance.<\/p>\n<p><a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/structjau_1_1ordered__atomic.html\">ordered_atomic&lt;T,..&gt;<\/a> is used for consistent atomic type std::memory_order usage, i.e. not changing the memory model after selecting the type and apply the set order to all operations.<\/p>\n<p><a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1sc__atomic__critical.html\">sc_atomic_critical<\/a> provides a <em>resource acquisition is initialization (RAII)<\/em> style <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/atomic\/memory_order#Sequentially-consistent_ordering\"><em>Sequentially Consistent (SC)<\/em><\/a> <em>data race free (DRF)<\/em> critical block and it is used e.g. in <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1cow__darray.html\">cow_darray&lt;T&gt;<\/a> and its mechanism in <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1ringbuffer.html\">ringbuffer&lt;T&gt;<\/a> to ensure proper cash-reloading when reading and mutating cached memory.<\/p>\n<p>The <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1service__runner.html\">service_runner<\/a> provides means to <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1service__runner.html#a0d8bd0a8ad6f4cb55961c4b3220da186\">hard stop<\/a> its service thread via signal SIGALRM as required for responsive behavior when blocked in a I\/O task like waiting for data. Such threads must be stopped before their resources holder reach their end of life, otherwise we would see a free-after-use and potential SIGSEGV crash.<br \/>\n<a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1service__runner.html\">service_runner<\/a> is used for Direct-BT&#8217;s socket connection receiver-threads as well as for certain GATT Server test applications.<\/p>\n<p>Last but not least, a simple <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1latch.html\">latch<\/a> has been implemented with its extension to also allow to <a href=\"https:\/\/jausoft.com\/projects\/jaulib\/build\/documentation\/cpp\/html\/classjau_1_1latch.html#abdc302192d4c4063d0e7996be3eac961\">count_up()<\/a>. Its mostly used in our (trial) unit tests to wait for dynamic threads to complete.<\/p>\n<h2>Next &#8230;<\/h2>\n<p>More details to follow-up ..<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the first article covering Direct-BT&#8216;s implementation details including jaulib. See Direct-BT, Bluetooth Server and Client Programming in C++ and Java (Part 1) for a little introduction to Direct-BT. Standard and Proprietary Communication Channels As described, we were required to utilize the host Bluetooth implementation in the GNU\/Linux kernel, i.e. BlueZ\/Kernel directly without D-Bus&hellip; <a class=\"more-link\" href=\"https:\/\/jausoft.com\/blog\/2022\/05\/22\/direct-bt-implementation-details-pt1\/\">Continue reading <span class=\"screen-reader-text\">Direct-BT C++ Implementation Details (Part 1)<\/span> <span class=\"meta-nav\" aria-hidden=\"true\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[49,59,3,50,58],"tags":[53,51,52,13,16,33,46],"class_list":["post-997","post","type-post","status-publish","format-standard","hentry","category-bluetooth","category-c-language","category-computer-stuff","category-direct_bt","category-computer-languages","tag-bluetooth","tag-c","tag-direct-bt","tag-embedded-device","tag-java","tag-linux","tag-openjdk"],"_links":{"self":[{"href":"https:\/\/jausoft.com\/blog\/wp-json\/wp\/v2\/posts\/997","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jausoft.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jausoft.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jausoft.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jausoft.com\/blog\/wp-json\/wp\/v2\/comments?post=997"}],"version-history":[{"count":17,"href":"https:\/\/jausoft.com\/blog\/wp-json\/wp\/v2\/posts\/997\/revisions"}],"predecessor-version":[{"id":1009,"href":"https:\/\/jausoft.com\/blog\/wp-json\/wp\/v2\/posts\/997\/revisions\/1009"}],"wp:attachment":[{"href":"https:\/\/jausoft.com\/blog\/wp-json\/wp\/v2\/media?parent=997"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jausoft.com\/blog\/wp-json\/wp\/v2\/categories?post=997"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jausoft.com\/blog\/wp-json\/wp\/v2\/tags?post=997"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}