summaryrefslogtreecommitdiffstats
path: root/src/tinyb_hci
diff options
context:
space:
mode:
Diffstat (limited to 'src/tinyb_hci')
-rw-r--r--src/tinyb_hci/BTDataTypes.cpp354
-rw-r--r--src/tinyb_hci/BasicTypes.cpp151
-rw-r--r--src/tinyb_hci/CMakeLists.txt45
-rw-r--r--src/tinyb_hci/HCIAdapter.cpp417
-rw-r--r--src/tinyb_hci/HCIDevice.cpp163
-rw-r--r--src/tinyb_hci/UUID.cpp156
-rw-r--r--src/tinyb_hci/tinyb_hci.pc.cmake11
7 files changed, 0 insertions, 1297 deletions
diff --git a/src/tinyb_hci/BTDataTypes.cpp b/src/tinyb_hci/BTDataTypes.cpp
deleted file mode 100644
index f17aa9da..00000000
--- a/src/tinyb_hci/BTDataTypes.cpp
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Author: Sven Gothel <[email protected]>
- * Copyright (c) 2020 Gothel Software e.K.
- * Copyright (c) 2020 ZAFENA AB
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <cstring>
-#include <string>
-#include <memory>
-#include <cstdint>
-#include <vector>
-#include <cstdio>
-
-#include <algorithm>
-
-#include "BTDataTypes.hpp"
-
-/**
- * TODO libbluetooth replacement:
- * - bt_compidtostr
- */
-
-#define VERBOSE_ON 1
-
-#ifdef VERBOSE_ON
- #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
-#else
- #define DBG_PRINT(...)
-#endif
-
-
-using namespace tinyb_hci;
-
-static inline const int8_t * const_uint8_to_const_int8_ptr(const uint8_t* p) {
- return static_cast<const int8_t *>( static_cast<void *>( const_cast<uint8_t*>( p ) ) );
-}
-
-static std::string bt_compidtostr(const uint16_t companyid) {
- return std::to_string(companyid);
-}
-
-std::string EUI48::toString() const {
- char cstr[17+1];
-
- const int count = sprintf(cstr, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
- b[5], b[4], b[3], b[2], b[1], b[0]);
-
- if( 17 != count ) {
- std::string msg("EUI48 string not of length 17 but ");
- msg.append(std::to_string(count));
- throw InternalError(msg, E_FILE_LINE);
- }
- return std::string(cstr);
-}
-
-EUI48::EUI48(const std::string str) {
- if( 17 != str.length() ) {
- std::string msg("EUI48 string not of length 17 but ");
- msg.append(std::to_string(str.length()));
- msg.append(": "+str);
- throw IllegalArgumentException(msg, E_FILE_LINE);
- }
- if ( sscanf(str.c_str(), "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
- &b[5], &b[4], &b[3], &b[2], &b[1], &b[0]) != 6 )
- {
- std::string msg("EUI48 string not in format '00:00:00:00:00:00' but "+str);
- throw IllegalArgumentException(msg, E_FILE_LINE);
- }
-
- // sscanf provided host data type, in which we store the values,
- // hence no endian conversion
-}
-
-const EUI48 EUI48_ANY_DEVICE; // default ctor is zero bytes!
-
-// *************************************************
-// *************************************************
-// *************************************************
-
-ManufactureSpecificData::ManufactureSpecificData(uint16_t const company, uint8_t const * const data, int const data_len)
-: company(company), companyName(std::string(bt_compidtostr(company))), data_len(data_len), data(new uint8_t[data_len]) {
- memcpy(this->data.get(), data, data_len);
-}
-
-std::string ManufactureSpecificData::toString() const {
- std::string out("MSD[");
- out.append(std::to_string(company)+" "+companyName);
- out.append(", data "+std::to_string(data_len)+" bytes]");
- return out;
-}
-
-// *************************************************
-// *************************************************
-// *************************************************
-
-std::string EInfoReport::getSourceString() const {
- switch (source) {
- case Source::NA: return "N/A";
- case Source::AD: return "AD";
- case Source::EIR: return "EIR";
- }
- return "N/A";
-}
-
-void EInfoReport::setName(const uint8_t *buffer, int buffer_len) {
- name = get_string(buffer, buffer_len, 30);
- set(Element::NAME);
-}
-
-void EInfoReport::setShortName(const uint8_t *buffer, int buffer_len) {
- name_short = get_string(buffer, buffer_len, 30);
- set(Element::NAME_SHORT);
-}
-
-void EInfoReport::addService(std::shared_ptr<UUID> const &uuid)
-{
- auto begin = services.begin();
- auto it = std::find_if(begin, services.end(), [&](std::shared_ptr<UUID> const& p) {
- return *p == *uuid;
- });
- if ( it == std::end(services) ) {
- services.push_back(uuid);
- }
-}
-
-std::string EInfoReport::dataSetToString(const uint32_t data_set) {
- std::string out("[");
- if( isSet(data_set, Element::EVT_TYPE) ) {
- out.append("EVT_TYPE, ");
- }
- if( isSet(data_set, Element::BDADDR) ) {
- out.append("BDADDR, ");
- }
- if( isSet(data_set, Element::NAME) ) {
- out.append("NAME, ");
- }
- if( isSet(data_set, Element::NAME_SHORT) ) {
- out.append("NAME_SHORT, ");
- }
- if( isSet(data_set, Element::RSSI) ) {
- out.append("RSSI, ");
- }
- if( isSet(data_set, Element::TX_POWER) ) {
- out.append("TX_POWER, ");
- }
- if( isSet(data_set, Element::MANUF_DATA) ) {
- out.append("MANUF_DATA, ");
- }
- out.append("]");
- return out;
-}
-std::string EInfoReport::dataSetToString() const {
- return std::string("DataSet"+dataSetToString(data_set));
-}
-std::string EInfoReport::toString() const {
- std::string msdstr = nullptr != msd ? msd->toString() : "MSD[null]";
- std::string out("EInfoReport::"+getSourceString()+"["+getAddressString()+", "+name+"/"+name_short+", "+dataSetToString()+
- ", evt-type "+std::to_string(evt_type)+", rssi "+std::to_string(rssi)+
- ", tx-power "+std::to_string(tx_power)+", "+msdstr+"]");
- if(services.size() > 0 ) {
- out.append("\n");
- for(auto it = services.begin(); it != services.end(); it++) {
- std::shared_ptr<UUID> p = *it;
- out.append(" ").append(p->toUUID128String()).append(", ").append(std::to_string(static_cast<int>(p->type))).append(" bytes\n");
- }
- }
- return out;
-}
-
-// *************************************************
-// *************************************************
-// *************************************************
-
-int EInfoReport::next_data_elem(uint8_t *eir_elem_len, uint8_t *eir_elem_type, uint8_t const **eir_elem_data,
- uint8_t const * data, int offset, int const size)
-{
- if (offset < size) {
- uint8_t len = data[offset]; // covers: type + data, less len field itself
-
- if (len == 0) {
- return 0; // end of significant part
- }
-
- if (len + offset > size) {
- return -ENOENT;
- }
-
- *eir_elem_type = data[offset + 1];
- *eir_elem_data = data + offset + 2; // net data ptr
- *eir_elem_len = len - 1; // less type -> net data length
-
- return offset + 1 + len; // next ad_struct offset: + len + type + data
- }
- return -ENOENT;
-}
-
-int EInfoReport::read_data(uint8_t const * data, uint8_t const data_length) {
- int count = 0;
- int offset = 0;
- uint8_t elem_len, elem_type;
- uint8_t const *elem_data;
-
- while( 0 < ( offset = next_data_elem( &elem_len, &elem_type, &elem_data, data, offset, data_length ) ) )
- {
- DBG_PRINT("%s-Element[%d] @ [%d/%d]: type 0x%.2X with %d bytes net\n",
- getSourceString().c_str(), count, offset, data_length, elem_type, elem_len);
- count++;
-
- // Guaranteed: eir_elem_len >= 0!
- switch ( elem_type ) {
- case GAP_T::FLAGS:
- // FIXME
- break;
- case GAP_T::UUID16_INCOMPLETE:
- case GAP_T::UUID16_COMPLETE:
- for(int j=0; j<elem_len/2; j++) {
- const std::shared_ptr<UUID> uuid(new UUID16(elem_data, j*2, true));
- addService(std::move(uuid));
- }
- break;
- case GAP_T::UUID32_INCOMPLETE:
- case GAP_T::UUID32_COMPLETE:
- for(int j=0; j<elem_len/4; j++) {
- const std::shared_ptr<UUID> uuid(new UUID32(elem_data, j*4, true));
- addService(std::move(uuid));
- }
- break;
- case GAP_T::UUID128_INCOMPLETE:
- case GAP_T::UUID128_COMPLETE:
- for(int j=0; j<elem_len/16; j++) {
- const std::shared_ptr<UUID> uuid(new UUID128(elem_data, j*16, true));
- addService(std::move(uuid));
- }
- break;
- case GAP_T::NAME_LOCAL_SHORT:
- case GAP_T::NAME_LOCAL_COMPLETE: {
- if( GAP_T::NAME_LOCAL_COMPLETE == elem_type ) {
- setName(elem_data, elem_len);
- } else {
- setShortName(elem_data, elem_len);
- }
- } break;
- case GAP_T::TX_POWER_LEVEL:
- setTxPower(*const_uint8_to_const_int8_ptr(elem_data));
- break;
-
- case GAP_T::SSP_CLASS_OF_DEVICE:
- case GAP_T::DEVICE_ID:
- case GAP_T::SOLICIT_UUID16:
- case GAP_T::SOLICIT_UUID128:
- case GAP_T::SVC_DATA_UUID16:
- case GAP_T::PUB_TRGT_ADDR:
- case GAP_T::RND_TRGT_ADDR:
- case GAP_T::GAP_APPEARANCE:
- case GAP_T::SOLICIT_UUID32:
- case GAP_T::SVC_DATA_UUID32:
- case GAP_T::SVC_DATA_UUID128:
- break;
-
- case GAP_T::MANUFACTURE_SPECIFIC: {
- uint16_t company = get_uint16(elem_data, 0, true /* littleEndian */);
- setManufactureSpecificData(company, elem_data+2, elem_len-2);
- } break;
-
- default: {
- // FIXME: Use a data blob!!!!
- fprintf(stderr, "%s-Element @ [%d/%d]: Warning: Unhandled type 0x%.2X with %d bytes net\n",
- getSourceString().c_str(), offset, data_length, elem_type, elem_len);
- } break;
- }
- }
- return count;
-}
-
-std::vector<std::shared_ptr<EInfoReport>> EInfoReport::read_ad_reports(uint8_t const * data, uint8_t const data_length) {
- int const num_reports = (int) data[0];
- std::vector<std::shared_ptr<EInfoReport>> ad_reports;
-
- if( 0 >= num_reports || num_reports > 0x19 ) {
- DBG_PRINT("AD-Reports: Invalid reports count: %d\n", num_reports);
- return ad_reports;
- }
- uint8_t const *limes = data + data_length;
- uint8_t const *i_octets = data + 1;
- uint8_t ad_data_len[0x19];
- const int segment_count = 6;
- int read_segments = 0;
- int i;
-
- for(i = 0; i < num_reports && i_octets < limes; i++) {
- ad_reports.push_back(std::shared_ptr<EInfoReport>(new EInfoReport()));
- ad_reports[i]->setSource(Source::AD);
- ad_reports[i]->setTimestamp(getCurrentMilliseconds());
- ad_reports[i]->setEvtType(*i_octets++);
- read_segments++;
- }
- for(i = 0; i < num_reports && i_octets < limes; i++) {
- ad_reports[i]->setAddressType(*i_octets++);
- read_segments++;
- }
- for(i = 0; i < num_reports && i_octets + 5 < limes; i++) {
- ad_reports[i]->setAddress( *((EUI48 const *)i_octets) );
- i_octets += 6;
- read_segments++;
- }
- for(i = 0; i < num_reports && i_octets < limes; i++) {
- ad_data_len[i] = *i_octets++;
- read_segments++;
- }
- for(i = 0; i < num_reports && i_octets + ad_data_len[i] < limes; i++) {
- ad_reports[i]->read_data(i_octets, ad_data_len[i]);
- i_octets += ad_data_len[i];
- read_segments++;
- }
- for(i = 0; i < num_reports && i_octets < limes; i++) {
- ad_reports[i]->setRSSI(*const_uint8_to_const_int8_ptr(i_octets));
- i_octets++;
- read_segments++;
- }
- const int bytes_left = limes - i_octets;
-
- if( segment_count != read_segments ) {
- fprintf(stderr, "AD-Reports: Warning: Incomplete %d reports within %d bytes: Segment read %d < %d, data-ptr %d bytes to limes\n",
- num_reports, data_length, read_segments, segment_count, bytes_left);
- } else {
- DBG_PRINT("AD-Reports: Completed %d reports within %d bytes: Segment read %d == %d, data-ptr %d bytes to limes\n",
- num_reports, data_length, read_segments, segment_count, bytes_left);
- }
- return ad_reports;
-}
-
-// *************************************************
-// *************************************************
-// *************************************************
-
diff --git a/src/tinyb_hci/BasicTypes.cpp b/src/tinyb_hci/BasicTypes.cpp
deleted file mode 100644
index 97ef1cfc..00000000
--- a/src/tinyb_hci/BasicTypes.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Author: Sven Gothel <[email protected]>
- * Copyright (c) 2020 Gothel Software e.K.
- * Copyright (c) 2020 ZAFENA AB
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "BasicTypes.hpp"
-
-// #define _USE_BACKTRACE_ 1
-
-#if _USE_BACKTRACE_
-extern "C" {
- #include <execinfo.h>
-}
-#endif
-
-using namespace tinyb_hci;
-
-static const int64_t NanoPerMilli = 1000000L;
-static const int64_t MilliPerOne = 1000L;
-
-/**
- * See <http://man7.org/linux/man-pages/man2/clock_gettime.2.html>
- * <p>
- * Regarding avoiding kernel via VDSO,
- * see <http://man7.org/linux/man-pages/man7/vdso.7.html>,
- * clock_gettime seems to be well supported at least on kernel >= 4.4.
- * Only bfin and sh are missing, while ia64 seems to be complicated.
- */
-int64_t tinyb_hci::getCurrentMilliseconds() {
- struct timespec t;
- clock_gettime(CLOCK_MONOTONIC, &t);
- return t.tv_sec * MilliPerOne + t.tv_nsec / NanoPerMilli;
-}
-
-const char* RuntimeException::what() const noexcept {
-#if _USE_BACKTRACE_
- std::string out(msg);
- void *buffers[10];
- size_t nptrs = backtrace(buffers, 10);
- char **symbols = backtrace_symbols(buffers, nptrs);
- if( NULL != symbols ) {
- out.append("\nBacktrace:\n");
- for(int i=0; i<nptrs; i++) {
- out.append(symbols[i]).append("\n");
- }
- free(symbols);
- }
- return out.c_str();
-#else
- return msg.c_str();
-#endif
-}
-
-std::string tinyb_hci::get_string(const uint8_t *buffer, int const buffer_len, int const max_len) {
- const int cstr_len = std::min(buffer_len, max_len);
- char cstr[max_len+1]; // EOS
- memcpy(cstr, buffer, cstr_len);
- cstr[cstr_len] = 0; // EOS
- return std::string(cstr);
-}
-
-uint128_t tinyb_hci::merge_uint128(uint128_t const & base_uuid, uint16_t const uuid16, int const uuid16_le_octet_index)
-{
- if( 0 > uuid16_le_octet_index || uuid16_le_octet_index > 14 ) {
- std::string msg("uuid16_le_octet_index ");
- msg.append(std::to_string(uuid16_le_octet_index));
- msg.append(", not within [0..14]");
- throw IllegalArgumentException(msg, E_FILE_LINE);
- }
- uint128_t dest = base_uuid;
-
- // base_uuid: 00000000-0000-1000-8000-00805F9B34FB
- // uuid16: DCBA
- // uuid16_le_octet_index: 12
- // result: 0000DCBA-0000-1000-8000-00805F9B34FB
- //
- // LE: low-mem - FB349B5F8000-0080-0010-0000-ABCD0000 - high-mem
- // ^ index 12
- // LE: uuid16 -> value.data[12+13]
- //
- // BE: low-mem - 0000DCBA-0000-1000-8000-00805F9B34FB - high-mem
- // ^ index 2
- // BE: uuid16 -> value.data[2+3]
- //
-#if __BYTE_ORDER == __BIG_ENDIAN
- int offset = 15 - 1 - uuid16_le_octet_index;
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
- int offset = uuid16_le_octet_index;
-#else
-#error "Unexpected __BYTE_ORDER"
-#endif
- uint16_t * destu16 = (uint16_t*)(dest.data + offset);
- *destu16 += uuid16;
- return dest;
-}
-
-uint128_t tinyb_hci::merge_uint128(uint128_t const & base_uuid, uint32_t const uuid32, int const uuid32_le_octet_index)
-{
- if( 0 > uuid32_le_octet_index || uuid32_le_octet_index > 12 ) {
- std::string msg("uuid32_le_octet_index ");
- msg.append(std::to_string(uuid32_le_octet_index));
- msg.append(", not within [0..12]");
- throw IllegalArgumentException(msg, E_FILE_LINE);
- }
- uint128_t dest = base_uuid;
-
- // base_uuid: 00000000-0000-1000-8000-00805F9B34FB
- // uuid32: 87654321
- // uuid32_le_octet_index: 12
- // result: 87654321-0000-1000-8000-00805F9B34FB
- //
- // LE: low-mem - FB349B5F8000-0080-0010-0000-12345678 - high-mem
- // ^ index 12
- // LE: uuid32 -> value.data[12..15]
- //
- // BE: low-mem - 87654321-0000-1000-8000-00805F9B34FB - high-mem
- // ^ index 0
- // BE: uuid32 -> value.data[0..3]
- //
-#if __BYTE_ORDER == __BIG_ENDIAN
- int offset = 15 - 3 - uuid32_le_octet_index;
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
- int offset = uuid32_le_octet_index;
-#else
-#error "Unexpected __BYTE_ORDER"
-#endif
- uint32_t * destu32 = (uint32_t*)(dest.data + offset);
- *destu32 += uuid32;
- return dest;
-}
-
diff --git a/src/tinyb_hci/CMakeLists.txt b/src/tinyb_hci/CMakeLists.txt
deleted file mode 100644
index d50d40c6..00000000
--- a/src/tinyb_hci/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-set (tinyb_hci_LIB_INCLUDE_DIRS
- ${PROJECT_SOURCE_DIR}/api
- ${PROJECT_SOURCE_DIR}/api/tinyb_hci
- ${PROJECT_SOURCE_DIR}/include
-)
-
-include_directories(
- ${tinyb_hci_LIB_INCLUDE_DIRS}
- ${CMAKE_CURRENT_BINARY_DIR}
-)
-
-set (tinyb_hci_LIB_SRCS
- ${PROJECT_SOURCE_DIR}/src/tinyb_hci/BasicTypes.cpp
- ${PROJECT_SOURCE_DIR}/src/tinyb_hci/UUID.cpp
- ${PROJECT_SOURCE_DIR}/src/tinyb_hci/BTDataTypes.cpp
- ${PROJECT_SOURCE_DIR}/src/tinyb_hci/HCIAdapter.cpp
- ${PROJECT_SOURCE_DIR}/src/tinyb_hci/HCIDevice.cpp
-# autogenerated files
- ${CMAKE_CURRENT_BINARY_DIR}/../version.c
-)
-
-add_library (tinyb_hci SHARED ${tinyb_hci_LIB_SRCS})
-target_link_libraries (
- tinyb_hci
- ${CMAKE_THREAD_LIBS_INIT}
- bluetooth
-)
-
-set_target_properties(
- tinyb_hci
- PROPERTIES
- SOVERSION ${tinyb_VERSION_MAJOR}
- VERSION ${tinyb_VERSION_STRING}
- CXX_STANDARD 11
-)
-install (DIRECTORY ${PROJECT_SOURCE_DIR}/api/tinyb_hci/ DESTINATION include/tinyb_hci)
-
-macro (tinyb_CREATE_INSTALL_PKGCONFIG generated_file install_location)
- configure_file (${generated_file}.cmake ${CMAKE_CURRENT_BINARY_DIR}/${generated_file} @ONLY)
- install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${generated_file} DESTINATION ${install_location})
-endmacro (tinyb_CREATE_INSTALL_PKGCONFIG)
-tinyb_create_install_pkgconfig (tinyb_hci.pc lib${LIB_SUFFIX}/pkgconfig)
-
-install(TARGETS tinyb_hci LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
-
diff --git a/src/tinyb_hci/HCIAdapter.cpp b/src/tinyb_hci/HCIAdapter.cpp
deleted file mode 100644
index 38e28cd4..00000000
--- a/src/tinyb_hci/HCIAdapter.cpp
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Author: Sven Gothel <[email protected]>
- * Copyright (c) 2020 Gothel Software e.K.
- * Copyright (c) 2020 ZAFENA AB
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <cstring>
-#include <string>
-#include <memory>
-#include <cstdint>
-#include <vector>
-#include <cstdio>
-
-#include <algorithm>
-
-#include <inttypes.h>
-#include <unistd.h>
-#include <poll.h>
-
-extern "C" {
- #include <bluetooth/bluetooth.h>
- #include <bluetooth/hci.h>
- #include <bluetooth/hci_lib.h>
-}
-
-#include "HCITypes.hpp"
-
-#define VERBOSE_ON 1
-
-#ifdef VERBOSE_ON
- #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
-#else
- #define DBG_PRINT(...)
-#endif
-
-using namespace tinyb_hci;
-
-static inline bdaddr_t* eui48_to_bdaddr_ptr(EUI48 *p) {
- return static_cast<bdaddr_t *>( static_cast<void *>( p ) );
-}
-
-
-// *************************************************
-// *************************************************
-// *************************************************
-
-std::atomic_int HCISession::name_counter(0);
-
-bool HCISession::close()
-{
- if( 0 > _dd ) {
- return false;
- }
- hci_close_dev(_dd);
- _dd = -1;
- adapter.sessionClosed(*this);
- return true;
-}
-
-// *************************************************
-// *************************************************
-// *************************************************
-
-int HCIAdapter::getDefaultDevId() {
- return hci_get_route(NULL);
-}
-int HCIAdapter::getDevId(EUI48 &mac) {
- return hci_get_route( eui48_to_bdaddr_ptr( &mac ) );
-}
-int HCIAdapter::getDevId(const std::string &hcidev) {
- return hci_devid(hcidev.c_str());
-}
-
-bool HCIAdapter::validateDevInfo() {
- if( 0 > dev_id ) {
- return false;
- }
- struct hci_dev_info dev_info;
- bzero(&dev_info, sizeof(dev_info));
- if( 0 > hci_devinfo(dev_id, &dev_info) ) {
- return false;
- }
- memcpy(&mac, &dev_info.bdaddr, sizeof(mac));
- name = std::string(dev_info.name);
- return true;
-}
-
-void HCIAdapter::sessionClosed(HCISession& s)
-{
- auto it = std::find_if(sessions.begin(), sessions.end(), [&](std::shared_ptr<HCISession> const& p) {
- return *p == s;
- });
- if ( it != std::end(sessions) ) {
- sessions.erase(it);
- }
-}
-
-HCIAdapter::HCIAdapter()
-: dev_id(getDefaultDevId())
-{
- valid = validateDevInfo();
-}
-
-HCIAdapter::HCIAdapter(EUI48 &mac)
-: dev_id(getDevId(mac))
-{
- valid = validateDevInfo();
-}
-
-HCIAdapter::HCIAdapter(const std::string &hcidev)
-: dev_id(getDevId(hcidev))
-{
- valid = validateDevInfo();
-}
-
-HCIAdapter::HCIAdapter(const int dev_id)
-: dev_id(dev_id)
-{
- valid = validateDevInfo();
-}
-
-HCIAdapter::~HCIAdapter() {
- scannedDevices.clear();
- discoveredDevices.clear();
- sessions.clear();
-}
-
-std::shared_ptr<HCISession> HCIAdapter::open()
-{
- if( !valid ) {
- return nullptr;
- }
- int dd = hci_open_dev(dev_id);
- if( 0 > dd ) {
- perror("Could not open device");
- return nullptr;
- }
- std::shared_ptr<HCISession> s(new HCISession(*this, dd));
- sessions.push_back(s);
- return s;
-}
-
-std::shared_ptr<HCIDeviceDiscoveryListener> HCIAdapter::setDeviceDiscoveryListener(std::shared_ptr<HCIDeviceDiscoveryListener> l)
-{
- std::shared_ptr<HCIDeviceDiscoveryListener> o = deviceDiscoveryListener;
- deviceDiscoveryListener = l;
- return o;
-}
-
-bool HCIAdapter::startDiscovery(HCISession &s,
- uint16_t interval, uint16_t window,
- uint8_t own_mac_type)
-{
- const uint8_t scan_type = 0x01;
- const uint8_t filter_type = 0;
- const uint8_t filter_policy = 0x00;
- const uint8_t filter_dup = 0x01;
-
- if( !s.isOpen() ) {
- fprintf(stderr, "Session not open\n");
- return false;
- }
- int err = hci_le_set_scan_parameters(s.dd(), scan_type,
- cpu_to_le(interval), cpu_to_le(window),
- own_mac_type, filter_policy, to_send_req_poll_ms);
- if (err < 0) {
- perror("Set scan parameters failed");
- return false;
- }
-
- err = hci_le_set_scan_enable(s.dd(), 0x01, filter_dup, to_send_req_poll_ms);
- if (err < 0) {
- perror("Start scan failed");
- return false;
- }
- return true;
-}
-
-bool HCIAdapter::stopDiscovery(HCISession& session) {
- const uint8_t filter_dup = 0x01;
-
- if( !session.isOpen() ) {
- fprintf(stderr, "Session not open\n");
- return false;
- }
- bool res;
- if( 0 > hci_le_set_scan_enable(session.dd(), 0x00, filter_dup, to_send_req_poll_ms) ) {
- perror("Stop scan failed");
- res = false;
- } else {
- res = true;
- }
- return res;
-}
-
-int HCIAdapter::findDevice(std::vector<std::shared_ptr<HCIDevice>> const & devices, EUI48 const & mac) {
- auto begin = devices.begin();
- auto it = std::find_if(begin, devices.end(), [&](std::shared_ptr<HCIDevice> const& p) {
- return p->mac == mac;
- });
- if ( it == std::end(devices) ) {
- return -1;
- } else {
- return std::distance(begin, it);
- }
-}
-
-bool HCIAdapter::addScannedDevice(std::shared_ptr<HCIDevice> const &device) {
- if( 0 > findDevice(scannedDevices, device->mac) ) {
- scannedDevices.push_back(device);
- return true;
- }
- return false;
-}
-
-bool HCIAdapter::addDiscoveredDevice(std::shared_ptr<HCIDevice> const &device) {
- if( 0 > findDiscoveredDevice(device->mac) ) {
- discoveredDevices.push_back(device);
- return true;
- }
- return false;
-}
-
-int HCIAdapter::findDiscoveredDevice(EUI48 const & mac) const {
- return findDevice(discoveredDevices, mac);
-}
-
-void HCIAdapter::removeDiscoveredDevices() {
- // also need to flush scannedDevices, old data
- scannedDevices.clear();
- discoveredDevices.clear();
-}
-
-std::string HCIAdapter::toString() const {
- std::string out("Adapter["+getAddressString()+", '"+getName()+"', id="+std::to_string(dev_id)+"]");
- if(discoveredDevices.size() > 0 ) {
- out.append("\n");
- for(auto it = discoveredDevices.begin(); it != discoveredDevices.end(); it++) {
- std::shared_ptr<HCIDevice> p = *it;
- out.append(" ").append(p->toString()).append("\n");
- }
- }
- return out;
-}
-
-// *************************************************
-
-int HCIAdapter::discoverDevices(HCISession& session,
- const int waitForDeviceCount,
- const EUI48 &waitForDevice,
- const int timeoutMS,
- const uint32_t ad_type_req)
-{
- uint8_t buf[HCI_MAX_EVENT_SIZE];
- struct hci_filter nf, of;
- socklen_t olen;
- int bytes_left = -1;
- const int64_t t0 = getCurrentMilliseconds();
-
- if( !session.isOpen() ) {
- fprintf(stderr, "Session not open\n");
- return false;
- }
-
- olen = sizeof(of);
- if (getsockopt(session.dd(), SOL_HCI, HCI_FILTER, &of, &olen) < 0) {
- fprintf(stderr, "Could not get socket options\n");
- return false;
- }
-
- hci_filter_clear(&nf);
- hci_filter_set_ptype(HCI_EVENT_PKT, &nf);
- hci_filter_set_event(EVT_LE_META_EVENT, &nf);
-
- if (setsockopt(session.dd(), SOL_HCI, HCI_FILTER, &nf, sizeof(nf)) < 0) {
- fprintf(stderr, "Could not set socket options\n");
- return false;
- }
-
- const uint32_t ad_req = static_cast<uint32_t>(EInfoReport::Element::BDADDR) |
- static_cast<uint32_t>(EInfoReport::Element::RSSI) |
- ad_type_req;
- bool done = false;
- int64_t t1;
- int matchedDeviceCount = 0, loop=0;
-
- while ( !done && ( ( t1 = getCurrentMilliseconds() ) - t0 ) < timeoutMS ) {
- uint8_t hci_type;
- hci_event_hdr *ehdr;
- evt_le_meta_event *meta;
- loop++;
-
- if( timeoutMS ) {
- struct pollfd p;
- int n;
-
- p.fd = session.dd(); p.events = POLLIN;
- while ((n = poll(&p, 1, timeoutMS)) < 0) {
- if (errno == EAGAIN || errno == EINTR ) {
- // cont temp unavail or interruption
- continue;
- }
- goto errout;
- }
- if (!n) {
- goto done; // timeout: exit but no error
- }
- }
-
- while ((bytes_left = read(session.dd(), buf, sizeof(buf))) < 0) {
- if (errno == EAGAIN || errno == EINTR ) {
- // cont temp unavail or interruption
- continue;
- }
- goto errout;
- }
-
- if( bytes_left < HCI_TYPE_LEN + HCI_EVENT_HDR_SIZE + EVT_LE_META_EVENT_SIZE ) {
- // not enough data ..
- continue;
- }
- hci_type = buf[0]; // sizeof HCI_TYPE_LEN
-
- ehdr = (hci_event_hdr*)(void*) ( buf + HCI_TYPE_LEN ); // sizeof HCI_EVENT_HDR_SIZE
-
- bytes_left -= (HCI_TYPE_LEN + HCI_EVENT_HDR_SIZE);
- meta = (evt_le_meta_event*)(void *) ( buf + ( HCI_TYPE_LEN + HCI_EVENT_HDR_SIZE ) ); // sizeof EVT_LE_META_EVENT_SIZE
-
- if( bytes_left < ehdr->plen ) {
- // not enough data ..
- fprintf(stderr, "HCIAdapter::discovery[%d]: Warning: Incomplete type 0x%.2X, event 0x%.2X, subevent 0x%.2X, remaining %d bytes < plen %d!\n",
- loop-1, hci_type, ehdr->evt, meta->subevent, bytes_left, ehdr->plen);
- continue;
- } else {
- DBG_PRINT("HCIAdapter::discovery[%d]: Complete type 0x%.2X, event 0x%.2X, subevent 0x%.2X, remaining %d bytes >= plen %d\n",
- loop-1, hci_type, ehdr->evt, meta->subevent, bytes_left, ehdr->plen);
- }
-
- // HCI_LE_Advertising_Report == 0x3E == EVT_LE_META_EVENT
- // 0x3E 0x02
- if ( HCI_Event_Types::LE_Advertising_Report != ehdr->evt || meta->subevent != EVT_LE_ADVERTISING_REPORT ) {
- continue; // next ..
- }
- bytes_left -= EVT_LE_META_EVENT_SIZE;
-
- std::vector<std::shared_ptr<EInfoReport>> ad_reports = EInfoReport::read_ad_reports(meta->data, bytes_left);
- const int num_reports = ad_reports.size();
-
- for(int i = 0; i < num_reports && i < 0x19; i++) {
- std::shared_ptr<EInfoReport> ad_report = ad_reports.at(i);
- const bool matches = ( ad_req == ( ad_req & ad_report->getDataSet() ) ) &&
- ( EUI48_ANY_DEVICE == waitForDevice || ad_report->getAddress() == waitForDevice );
- if( matches ) {
- matchedDeviceCount++;
- if( 0 < waitForDeviceCount && waitForDeviceCount <= matchedDeviceCount ) {
- done = true;
- }
- }
- DBG_PRINT("HCIAdapter::discovery[%d] %d/%d: matches %d, waitForDevice %s, ad_req %s, matchCount %d/%d, done %d\n",
- loop-1, i, num_reports, matches, waitForDevice.toString().c_str(), EInfoReport::dataSetToString(ad_req).c_str(),
- matchedDeviceCount, waitForDeviceCount, done);
- DBG_PRINT("HCIAdapter::discovery[%d] %d/%d: %s\n", loop-1, i, num_reports, ad_report->toString().c_str());
-
- int idx = findDevice(scannedDevices, ad_report->getAddress());
- std::shared_ptr<HCIDevice> dev;
- if( 0 > idx ) {
- // new device
- dev = std::shared_ptr<HCIDevice>(new HCIDevice(*this, *ad_report));
- addScannedDevice(dev);
- } else {
- // existing device
- dev = scannedDevices.at(idx);
- dev->update(*ad_report);
- }
- if( matches ) {
- if( addDiscoveredDevice(dev) ) {
- // new matching
- if( nullptr != deviceDiscoveryListener ) {
- deviceDiscoveryListener->deviceAdded(*this, dev);
- }
- } else {
- // update
- if( nullptr != deviceDiscoveryListener ) {
- deviceDiscoveryListener->deviceUpdated(*this, dev);
- }
- }
- }
- }
-
- }
-done:
- setsockopt(session.dd(), SOL_HCI, HCI_FILTER, &of, sizeof(of));
- return matchedDeviceCount;
-
-errout:
- setsockopt(session.dd(), SOL_HCI, HCI_FILTER, &of, sizeof(of));
- return -1;
-}
diff --git a/src/tinyb_hci/HCIDevice.cpp b/src/tinyb_hci/HCIDevice.cpp
deleted file mode 100644
index c674cf75..00000000
--- a/src/tinyb_hci/HCIDevice.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Author: Sven Gothel <[email protected]>
- * Copyright (c) 2020 Gothel Software e.K.
- * Copyright (c) 2020 ZAFENA AB
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <cstring>
-#include <string>
-#include <memory>
-#include <cstdint>
-#include <vector>
-#include <cstdio>
-
-#include <algorithm>
-
-extern "C" {
- #include <bluetooth/bluetooth.h>
- #include <bluetooth/hci.h>
- #include <bluetooth/hci_lib.h>
-}
-
-#include "HCITypes.hpp"
-
-using namespace tinyb_hci;
-
-static inline const bdaddr_t* const_eui48_to_const_bdaddr_ptr(const EUI48 *p) {
- return static_cast<const bdaddr_t *>( static_cast<void *>( const_cast<EUI48 *>( p ) ) );
-}
-
-// *************************************************
-// *************************************************
-// *************************************************
-
-HCIDevice::HCIDevice(HCIAdapter const & a, EInfoReport const & r)
-: adapter(a), ts_creation(r.getTimestamp()), mac(r.getAddress())
-{
- if( !r.isSet(EInfoReport::Element::BDADDR) ) {
- throw IllegalArgumentException("HCIDevice ctor: Address not set: "+r.toString(), E_FILE_LINE);
- }
- update(r);
-}
-
-void HCIDevice::addService(std::shared_ptr<UUID> const &uuid)
-{
- if( 0 > findService(uuid) ) {
- services.push_back(uuid);
- }
-}
-void HCIDevice::addServices(std::vector<std::shared_ptr<UUID>> const & services)
-{
- for(int j=0; j<services.size(); j++) {
- const std::shared_ptr<UUID> uuid = services.at(j);
- addService(uuid);
- }
-}
-
-int HCIDevice::findService(std::shared_ptr<UUID> const &uuid) const
-{
- auto begin = services.begin();
- auto it = std::find_if(begin, services.end(), [&](std::shared_ptr<UUID> const& p) {
- return *p == *uuid;
- });
- if ( it == std::end(services) ) {
- return -1;
- } else {
- return std::distance(begin, it);
- }
-}
-
-std::string HCIDevice::toString() const {
- const uint64_t t0 = getCurrentMilliseconds();
- std::string msdstr = nullptr != msd ? msd->toString() : "MSD[null]";
- std::string out("Device["+getAddressString()+", '"+getName()+
- "', age "+std::to_string(t0-ts_creation)+" ms, lup "+std::to_string(t0-ts_update)+" ms, rssi "+std::to_string(getRSSI())+
- ", tx-power "+std::to_string(tx_power)+", "+msdstr+"]");
- if(services.size() > 0 ) {
- out.append("\n");
- for(auto it = services.begin(); it != services.end(); it++) {
- std::shared_ptr<UUID> p = *it;
- out.append(" ").append(p->toUUID128String()).append(", ").append(std::to_string(static_cast<int>(p->type))).append(" bytes\n");
- }
- }
- return out;
-}
-
-void HCIDevice::update(EInfoReport const & data) {
- ts_update = data.getTimestamp();
- if( data.isSet(EInfoReport::Element::NAME) ) {
- if( !name.length() || data.getName().length() > name.length() ) {
- name = data.getName();
- }
- }
- if( data.isSet(EInfoReport::Element::NAME_SHORT) ) {
- if( !name.length() ) {
- name = data.getShortName();
- }
- }
- if( data.isSet(EInfoReport::Element::RSSI) ) {
- rssi = data.getRSSI();
- }
- if( data.isSet(EInfoReport::Element::TX_POWER) ) {
- tx_power = data.getTxPower();
- }
- if( data.isSet(EInfoReport::Element::MANUF_DATA) ) {
- msd = data.getManufactureSpecificData();
- }
- addServices(data.getServices());
-}
-
-uint16_t HCIDevice::le_connect(HCISession &s,
- uint16_t interval, uint16_t window,
- uint16_t min_interval, uint16_t max_interval,
- uint16_t latency, uint16_t supervision_timeout,
- uint16_t min_ce_length, uint16_t max_ce_length,
- uint8_t initiator_filter,
- uint8_t peer_mac_type,
- uint8_t own_mac_type )
-{
- if( !s.isOpen() ) {
- fprintf(stderr, "Session not open\n");
- return 0;
- }
- uint16_t handle = 0;
- bdaddr_t bdmac;
- memcpy(&bdmac, const_eui48_to_const_bdaddr_ptr(&mac), sizeof(bdaddr_t));
-
- int err = hci_le_create_conn(s.dd(),
- cpu_to_le(interval), cpu_to_le(window),
- initiator_filter, peer_mac_type, bdmac, own_mac_type,
- cpu_to_le(min_interval), cpu_to_le(max_interval),
- cpu_to_le(latency), cpu_to_le(supervision_timeout),
- cpu_to_le(min_ce_length), cpu_to_le(max_ce_length),
- &handle, to_connect_ms);
- if (err < 0) {
- perror("Could not create connection");
- return 0;
- }
- return handle;
-}
-
-// *************************************************
-// *************************************************
-// *************************************************
-
diff --git a/src/tinyb_hci/UUID.cpp b/src/tinyb_hci/UUID.cpp
deleted file mode 100644
index 88b28323..00000000
--- a/src/tinyb_hci/UUID.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Author: Sven Gothel <[email protected]>
- * Copyright (c) 2020 Gothel Software e.K.
- * Copyright (c) 2020 ZAFENA AB
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "UUID.hpp"
-
-using namespace tinyb_hci;
-
-// BASE_UUID '00000000-0000-1000-8000-00805F9B34FB'
-static uint8_t bt_base_uuid_be[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
- 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
-UUID128 tinyb_hci::BT_BASE_UUID = UUID128( bt_base_uuid_be, 0, false );
-
-UUID128::UUID128(UUID128 const & base_uuid, UUID16 const & uuid16, int const uuid16_le_octet_index)
-: UUID(Type::UUID128), value(merge_uint128(base_uuid.value, uuid16.value, uuid16_le_octet_index)) {}
-
-UUID128::UUID128(UUID128 const & base_uuid, UUID32 const & uuid32, int const uuid32_le_octet_index)
-: UUID(Type::UUID128), value(merge_uint128(base_uuid.value, uuid32.value, uuid32_le_octet_index)) {}
-
-std::string UUID16::toString() const {
- char buffer[4+1];
- const int count = snprintf(buffer, sizeof(buffer), "%.4X", value);
- if( 4 != count ) {
- std::string msg("UUID16 string not of length 4 but ");
- msg.append(std::to_string(count));
- throw InternalError(msg, E_FILE_LINE);
- }
- return std::string(buffer);
-}
-
-std::string UUID16::toUUID128String(UUID128 const & base_uuid, int const le_octet_index) const
-{
- UUID128 u128(base_uuid, *this, le_octet_index);
- return u128.toString();
-}
-
-std::string UUID32::toString() const {
- char buffer[8+1];
- int count = snprintf(buffer, sizeof(buffer), "%.8X", value);
- if( 8 != count ) {
- std::string msg("UUID32 string not of length 8 but ");
- msg.append(std::to_string(count));
- throw InternalError(msg, E_FILE_LINE);
- }
- return std::string(buffer);
-}
-
-std::string UUID32::toUUID128String(UUID128 const & base_uuid, int const le_octet_index) const
-{
- UUID128 u128(base_uuid, *this, le_octet_index);
- return u128.toString();
-}
-
-std::string UUID128::toString() const {
- // 87654321-0000-1000-8000-00805F9B34FB
- // 0 1 2 3 4 5
- // LE: low-mem - FB349B5F0800-0080-0010-0000-12345678 - high-mem
- // 5 4 3 2 1 0
- //
- // BE: low-mem - 87654321-0000-1000-8000-00805F9B34FB - high-mem
- // 0 1 2 3 4 5
- //
- char buffer[36+1];
- uint32_t part0, part4;
- uint16_t part1, part2, part3, part5;
-
- // snprintf uses host data type, in which values are stored,
- // hence no endian conversion
-#if __BYTE_ORDER == __BIG_ENDIAN
- part0 = get_uint32(value.data, 0);
- part1 = get_uint16(value.data, 4);
- part2 = get_uint16(value.data, 6);
- part3 = get_uint16(value.data, 8);
- part4 = get_uint32(value.data, 10);
- part5 = get_uint16(value.data, 14);
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
- part5 = get_uint16(value.data, 0);
- part4 = get_uint32(value.data, 2);
- part3 = get_uint16(value.data, 6);
- part2 = get_uint16(value.data, 8);
- part1 = get_uint16(value.data, 10);
- part0 = get_uint32(value.data, 12);
-#else
-#error "Unexpected __BYTE_ORDER"
-#endif
- int count = snprintf(buffer, sizeof(buffer), "%.8X-%.4X-%.4X-%.4X-%.8X%.4X",
- part0, part1, part2, part3, part4, part5);
- if( 36 != count ) {
- std::string msg("UUID128 string not of length 36 but ");
- msg.append(std::to_string(count));
- throw InternalError(msg, E_FILE_LINE);
- }
- return std::string(buffer);
-}
-
-UUID128::UUID128(const std::string str)
-: UUID(Type::UUID128)
-{
- uint32_t part0, part4;
- uint16_t part1, part2, part3, part5;
-
- if( 36 != str.length() ) {
- std::string msg("UUID128 string not of length 36 but ");
- msg.append(std::to_string(str.length()));
- msg.append(": "+str);
- throw IllegalArgumentException(msg, E_FILE_LINE);
- }
- if ( sscanf(str.c_str(), "%08x-%04hx-%04hx-%04hx-%08x%04hx",
- &part0, &part1, &part2, &part3, &part4, &part5) != 6 )
- {
- std::string msg("UUID128 string not in format '00000000-0000-1000-8000-00805F9B34FB' but "+str);
- throw IllegalArgumentException(msg, E_FILE_LINE);
- }
- uint128_t value;
-
- // sscanf provided host data type, in which we store the values,
- // hence no endian conversion
-#if __BYTE_ORDER == __BIG_ENDIAN
- put_uint32(value.data, 0, part0);
- put_uint16(value.data, 4, part1);
- put_uint16(value.data, 6, part2);
- put_uint16(value.data, 8, part3);
- put_uint32(value.data, 10, part4);
- put_uint16(value.data, 14, part5);
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
- put_uint16(value.data, 0, part5);
- put_uint32(value.data, 2, part4);
- put_uint16(value.data, 6, part3);
- put_uint16(value.data, 8, part2);
- put_uint16(value.data, 10, part1);
- put_uint32(value.data, 12, part0);
-#else
-#error "Unexpected __BYTE_ORDER"
-#endif
-}
diff --git a/src/tinyb_hci/tinyb_hci.pc.cmake b/src/tinyb_hci/tinyb_hci.pc.cmake
deleted file mode 100644
index 8a18a64e..00000000
--- a/src/tinyb_hci/tinyb_hci.pc.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
-prefix=@CMAKE_INSTALL_PREFIX@
-exec_prefix=${prefix}
-libdir=${exec_prefix}/lib@LIB_SUFFIX@
-includedir=${prefix}/include/tinyb_hci
-
-Name: tinyb_hci
-Description: Tiny BLE HCI library
-Version: @tinyb_VERSION_STRING@
-
-Libs: -L${libdir} -ltinyb
-Cflags: -I${includedir}