100 return nullptr != d ? (*d) == *device :
false;
113 std::make_shared<DBGattService> (
true ,
125 std::make_shared<DBGattService> (
true ,
153 std::make_shared<DBGattService> (
true ,
156 std::make_shared<DBGattChar>( std::make_unique<const jau::uuid128_t>(
StaticDataUUID) ,
159 std::make_shared<DBGattDesc>( BTGattDesc::TYPE_USER_DESC,
make_gvalue(
"DATA_STATIC") )
161 make_gvalue(
"Proprietary Static Data 0x00010203") ),
162 std::make_shared<DBGattChar>( std::make_unique<const jau::uuid128_t>(
CommandUUID) ,
165 std::make_shared<DBGattDesc>( BTGattDesc::TYPE_USER_DESC,
make_gvalue(
"COMMAND") )
168 std::make_shared<DBGattChar>( std::make_unique<const jau::uuid128_t>(
ResponseUUID) ,
171 std::make_shared<DBGattDesc>( BTGattDesc::TYPE_USER_DESC,
make_gvalue(
"RESPONSE") ),
172 DBGattDesc::createClientCharConfig()
175 std::make_shared<DBGattChar>( std::make_unique<const jau::uuid128_t>(
PulseDataUUID) ,
178 std::make_shared<DBGattDesc>( BTGattDesc::TYPE_USER_DESC,
make_gvalue(
"DATA_PULSE") ),
179 DBGattDesc::createClientCharConfig()
189 const AdapterSetting changedmask,
const uint64_t timestamp)
override {
190 const bool initialSetting = AdapterSetting::NONE == oldmask;
191 if( initialSetting ) {
192 fprintf_td(stderr,
"****** SETTINGS_INITIAL: %s -> %s, changed %s\n",
to_string(oldmask).c_str(),
195 fprintf_td(stderr,
"****** SETTINGS_CHANGED: %s -> %s, changed %s\n",
to_string(oldmask).c_str(),
202 if( !initialSetting &&
212 fprintf_td(stderr,
"****** DISCOVERING: meta %s, changed[%s, enabled %d, policy %s]: %s\n",
217 bool deviceFound(
const BTDeviceRef& device,
const uint64_t timestamp)
override {
220 fprintf_td(stderr,
"****** FOUND__-1: NOP %s\n", device->toString(
true).c_str());
224 void deviceUpdated(
const BTDeviceRef& device,
const EIRDataType updateMask,
const uint64_t timestamp)
override {
225 if(
is_set(updateMask, EIRDataType::BDADDR)) {
226 fprintf_td(stderr,
"****** UPDATED (ADDR-RESOLVED): %s of %s\n",
to_string(updateMask).c_str(), device->toString(
true).c_str());
228 fprintf_td(stderr,
"****** UPDATED: %s of %s\n",
to_string(updateMask).c_str(), device->toString(
true).c_str());
233 void deviceConnected(
const BTDeviceRef& device,
const bool discovered,
const uint64_t timestamp)
override {
234 fprintf_td(stderr,
"****** CONNECTED (discovered %d): %s\n", discovered, device->toString(
true).c_str());
235 const bool available =
nullptr ==
getDevice();
244 fprintf_td(stderr,
"****** PAIRING STATE: state %s, mode %s, %s\n",
248 case SMPPairingState::NONE:
251 case SMPPairingState::FAILED: {
254 case SMPPairingState::REQUESTED_BY_RESPONDER:
257 case SMPPairingState::FEATURE_EXCHANGE_STARTED:
260 case SMPPairingState::FEATURE_EXCHANGE_COMPLETED:
263 case SMPPairingState::PASSKEY_EXPECTED: {
265 if(
nullptr != sec && sec->
getPairingPasskey() != BTSecurityRegistry::Entry::NO_PASSKEY ) {
266 std::thread dc(&BTDevice::setPairingPasskey, device,
static_cast<uint32_t
>( sec->
getPairingPasskey() ));
269 std::thread dc(&BTDevice::setPairingPasskey, device, 0);
275 case SMPPairingState::NUMERIC_COMPARE_EXPECTED: {
277 if(
nullptr != sec ) {
281 std::thread dc(&BTDevice::setPairingNumericComparison, device,
true);
286 case SMPPairingState::PASSKEY_NOTIFY: {
289 fprintf_td(stderr,
"****** Confirm on your device %s\n", device->getName().c_str());
290 fprintf_td(stderr,
"****** PassKey: %s\n", device->getResponderSMPPassKeyString().c_str());
295 case SMPPairingState::OOB_EXPECTED:
298 case SMPPairingState::KEY_DISTRIBUTION:
301 case SMPPairingState::COMPLETED:
309 void deviceReady(
const BTDeviceRef& device,
const uint64_t timestamp)
override {
311 fprintf_td(stderr,
"****** READY-1: NOP %s\n", device->toString(
true).c_str());
314 void deviceDisconnected(
const BTDeviceRef& device,
const HCIStatusCode reason,
const uint16_t handle,
const uint64_t timestamp)
override {
316 fprintf_td(stderr,
"****** DISCONNECTED (count %zu): Reason 0x%X (%s), old handle %s: %s\n",
318 to_hexstring(handle).c_str(), device->toString(
true).c_str());
320 const bool match =
matches(device);
329 std::string toString() const noexcept
override {
330 return "MyAdapterStatusListener[this "+
to_hexstring(
this)+
"]";
349 handlePulseDataNotify = 0;
350 handlePulseDataIndicate = 0;
351 handleResponseDataNotify = 0;
352 handleResponseDataIndicate = 0;
361 const std::string connectedDeviceStr =
nullptr != connectedDevice_ ? connectedDevice_->toString() :
"n/a";
362 fprintf_td(stderr,
"****** Server GATT::PULSE Start %s\n", connectedDeviceStr.c_str());
366 if(
nullptr != connectedDevice_ && connectedDevice_->getConnected() ) {
367 if( 0 != handlePulseDataNotify || 0 != handlePulseDataIndicate ) {
368 std::string data(
"Dynamic Data Example. Elapsed Milliseconds: "+
jau::to_decstring(environment::getElapsedMillisecond(),
',', 9) );
371 if( 0 != handlePulseDataNotify ) {
372 const bool res = connectedDevice_->sendNotification(handlePulseDataNotify, v);
373 fprintf_td(stderr,
"****** GATT::sendNotification: PULSE (res %d) to %s\n", res, connectedDevice_->toString().c_str());
375 if( 0 != handlePulseDataIndicate ) {
376 const bool res = connectedDevice_->sendIndication(handlePulseDataIndicate, v);
377 fprintf_td(stderr,
"****** GATT::sendIndication: PULSE (res %d) to %s\n", res, connectedDevice_->toString().c_str());
388 const std::string connectedDeviceStr =
nullptr != connectedDevice_ ? connectedDevice_->toString() :
"n/a";
389 fprintf_td(stderr,
"****** Server GATT::PULSE End %s\n", connectedDeviceStr.c_str());
394 if(
nullptr != connectedDevice_ && connectedDevice_->getConnected() ) {
395 if( 0 != handleResponseDataNotify || 0 != handleResponseDataIndicate ) {
396 if( 0 != handleResponseDataNotify ) {
397 const bool res = connectedDevice_->sendNotification(handleResponseDataNotify, data);
398 fprintf_td(stderr,
"****** GATT::sendNotification (res %d): %s to %s\n",
399 res, data.
toString().c_str(), connectedDevice_->toString().c_str());
401 if( 0 != handleResponseDataIndicate ) {
402 const bool res = connectedDevice_->sendIndication(handleResponseDataIndicate, data);
403 fprintf_td(stderr,
"****** GATT::sendIndication (res %d): %s to %s\n",
404 res, data.
toString().c_str(), connectedDevice_->toString().c_str());
417 pulse_service.
start();
421 pulse_service.
stop();
425 pulse_service.
stop();
431 const bool match =
matches(device);
432 fprintf_td(stderr,
"****** GATT::connected(match %d): initMTU %d, %s\n",
433 match, (
int)initialMTU, device->toString().c_str());
435 usedMTU = initialMTU;
441 const bool match =
matches(device);
442 fprintf_td(stderr,
"****** GATT::disconnected(match %d): %s\n", match, device->toString().c_str());
449 const bool match =
matches(device);
450 fprintf_td(stderr,
"****** GATT::mtuChanged(match %d): %d -> %d, %s\n",
451 match, match ? (
int)usedMTU : 0, (
int)mtu, device->toString().c_str());
458 const bool match =
matches(device);
459 fprintf_td(stderr,
"****** GATT::readCharValue(match %d): to %s, from\n %s\n %s\n",
460 match, device->toString().c_str(), s->toString().c_str(), c->toString().c_str());
465 const bool match =
matches(device);
466 fprintf_td(stderr,
"****** GATT::readDescValue(match %d): to %s, from\n %s\n %s\n %s\n",
467 match, device->toString().c_str(), s->toString().c_str(), c->toString().c_str(), d->toString().c_str());
472 const bool match =
matches(device);
473 fprintf_td(stderr,
"****** GATT::writeCharValue(match %d): %s '%s' @ %u from %s, to\n %s\n %s\n",
476 device->toString().c_str(), s->toString().c_str(), c->toString().c_str());
480 const bool match =
matches(device);
482 fprintf_td(stderr,
"****** GATT::writeCharValueDone(match %d): From %s, to\n %s\n %s\n Char-Value: %s\n",
483 match, device->toString().c_str(), s->toString().c_str(), c->toString().c_str(), value.
toString().c_str());
487 ( 0 != handleResponseDataNotify || 0 != handleResponseDataIndicate ) )
490 std::thread senderThread(&MyGATTServerListener::sendResponse,
this, value2);
491 senderThread.detach();
496 const bool match =
matches(device);
497 fprintf_td(stderr,
"****** GATT::writeDescValue(match %d): %s '%s' @ %u from %s\n %s\n %s\n %s\n",
500 device->toString().c_str(), s->toString().c_str(), c->toString().c_str(), d->toString().c_str());
504 const bool match =
matches(device);
506 fprintf_td(stderr,
"****** GATT::writeDescValueDone(match %d): From %s\n %s\n %s\n %s\n Desc-Value: %s\n",
507 match, device->toString().c_str(), s->toString().c_str(), c->toString().c_str(), d->toString().c_str(), value.
toString().c_str());
511 const bool match =
matches(device);
513 fprintf_td(stderr,
"****** GATT::clientCharConfigChanged(match %d): notify %d, indicate %d from %s\n %s\n %s\n %s\n Desc-Value: %s\n",
514 match, notificationEnabled, indicationEnabled,
515 device->toString().c_str(), s->toString().c_str(), c->toString().c_str(), d->toString().c_str(), value.
toString().c_str());
520 handlePulseDataNotify = notificationEnabled ? c->getValueHandle() : 0;
521 handlePulseDataIndicate = indicationEnabled ? c->getValueHandle() : 0;
522 }
else if( c->getValueType()->equivalent(
ResponseUUID ) ) {
523 handleResponseDataNotify = notificationEnabled ? c->getValueHandle() : 0;
524 handleResponseDataIndicate = indicationEnabled ? c->getValueHandle() : 0;
538 fprintf_td(stderr,
"****** Start advertising (%s): Adapter not selected: %s\n", msg.c_str(), a->
toString().c_str());
547 LE_PHYs Tx { LE_PHYs::LE_2M }, Rx { LE_PHYs::LE_2M };
549 fprintf_td(stderr,
"startAdvertising: Set Default LE PHY: status %s: Tx %s, Rx %s\n",
556 EIRDataType adv_mask = EIRDataType::FLAGS | EIRDataType::SERVICE_UUID;
557 EIRDataType scanrsp_mask = EIRDataType::NAME | EIRDataType::CONN_IVAL;
559 eir.
addFlags(GAPFlags::LE_Gen_Disc);
560 eir.
addFlags(GAPFlags::BREDR_UNSUP);
570 if(
nullptr != gattDevNameChar ) {
571 std::string aname = a->
getName();
572 gattDevNameChar->setValue(
reinterpret_cast<uint8_t*
>(aname.data()), aname.size(), 0);
575 fprintf_td(stderr,
"****** Start advertising (%s): EIR %s\n", msg.c_str(), eir.
toString().c_str());
576 fprintf_td(stderr,
"****** Start advertising (%s): adv %s, scanrsp %s\n", msg.c_str(),
to_string(adv_mask).c_str(),
to_string(scanrsp_mask).c_str());
581 fprintf_td(stderr,
"****** Start advertising (%s) result: %s: %s\n", msg.c_str(),
to_string(status).c_str(), a->
toString().c_str());
583 return HCIStatusCode::SUCCESS == status;
588 fprintf_td(stderr,
"****** Stop advertising (%s): Adapter not selected: %s\n", msg.c_str(), a->
toString().c_str());
592 fprintf_td(stderr,
"****** Stop advertising (%s) result: %s: %s\n", msg.c_str(),
to_string(status).c_str(), a->
toString().c_str());
593 return HCIStatusCode::SUCCESS == status;
597 fprintf_td(stderr,
"****** Disconnected Device (count %zu): Start %s\n",
610 fprintf_td(stderr,
"****** Disonnected Device: End %s\n", device->toString().c_str());
615 fprintf_td(stderr,
"initAdapter: Adapter not selected: %s\n", adapter->toString().c_str());
618 if( !adapter->isInitialized() ) {
621 if( HCIStatusCode::SUCCESS != status ) {
622 fprintf_td(stderr,
"initAdapter: initialize failed: %s: %s\n",
623 to_string(status).c_str(), adapter->toString().c_str());
626 }
else if( !adapter->setPowered(
false ) ) {
627 fprintf_td(stderr,
"initAdapter: setPower.1 off failed: %s\n", adapter->toString().c_str());
631 fprintf_td(stderr,
"initAdapter.1: %s\n", adapter->toString().c_str());
635 if( HCIStatusCode::SUCCESS == status ) {
636 fprintf_td(stderr,
"initAdapter: setLocalName OK: %s\n", adapter->toString().c_str());
638 fprintf_td(stderr,
"initAdapter: setLocalName failed: %s\n", adapter->toString().c_str());
642 status = adapter->setSecureConnections(
use_SC );
643 if( HCIStatusCode::SUCCESS == status ) {
644 fprintf_td(stderr,
"initAdapter: setSecureConnections OK: %s\n", adapter->toString().c_str());
646 fprintf_td(stderr,
"initAdapter: setSecureConnections failed: %s\n", adapter->toString().c_str());
650 const uint16_t conn_min_interval = 8;
651 const uint16_t conn_max_interval = 40;
652 const uint16_t conn_latency = 0;
653 const uint16_t supervision_timeout = 50;
654 status = adapter->setDefaultConnParam(conn_min_interval, conn_max_interval, conn_latency, supervision_timeout);
655 if( HCIStatusCode::SUCCESS == status ) {
656 fprintf_td(stderr,
"initAdapter: setDefaultConnParam OK: %s\n", adapter->toString().c_str());
657 }
else if( HCIStatusCode::UNKNOWN_COMMAND == status ) {
658 fprintf_td(stderr,
"initAdapter: setDefaultConnParam UNKNOWN_COMMAND (ignored): %s\n", adapter->toString().c_str());
660 fprintf_td(stderr,
"initAdapter: setDefaultConnParam failed: %s, %s\n",
to_string(status).c_str(), adapter->toString().c_str());
664 if( !adapter->setPowered(
true ) ) {
665 fprintf_td(stderr,
"initAdapter: setPower.2 on failed: %s\n", adapter->toString().c_str());
669 fprintf_td(stderr,
"initAdapter.2: %s\n", adapter->toString().c_str());
673 std::shared_ptr<AdapterStatusListener> asl( std::make_shared<MyAdapterStatusListener>() );
674 adapter->addStatusListener( asl );
676 adapter->removeStatusListener( asl );
687 fprintf_td(stderr,
"****** Adapter ADDED__: InitOK: %s\n", adapter->toString().c_str());
689 fprintf_td(stderr,
"****** Adapter ADDED__: Ignored: %s\n", adapter->toString().c_str());
693 fprintf_td(stderr,
"****** Adapter ADDED__: Ignored (other): %s\n", adapter->toString().c_str());
698 fprintf_td(stderr,
"****** Adapter REMOVED: %s\n", adapter->toString().c_str());
700 fprintf_td(stderr,
"****** Adapter REMOVED (other): %s\n", adapter->toString().c_str());
712 std::shared_ptr<MyGATTServerListener> listener = std::make_shared<MyGATTServerListener>();
721 fprintf_td(stderr,
"****** Test Shutdown.01 (DBGattServer.remove-listener)\n");
724 fprintf_td(stderr,
"****** Test Shutdown.02 (listener.close)\n");
727 fprintf_td(stderr,
"****** Test Shutdown.03 (DBGattServer.close := nullptr)\n");
737int main(
int argc,
char *argv[])
739 bool waitForEnter=
false;
741 fprintf_td(stderr,
"Direct-BT Native Version %s (API %s)\n", DIRECT_BT_VERSION, DIRECT_BT_VERSION_API);
743 for(
int i=1; i<argc; i++) {
744 if( !strcmp(
"-dbt_debug", argv[i]) && argc > (i+1) ) {
745 setenv(
"direct_bt.debug", argv[++i], 1 );
746 }
else if( !strcmp(
"-dbt_verbose", argv[i]) && argc > (i+1) ) {
747 setenv(
"direct_bt.verbose", argv[++i], 1 );
748 }
else if( !strcmp(
"-dbt_gatt", argv[i]) && argc > (i+1) ) {
749 setenv(
"direct_bt.gatt", argv[++i], 1 );
750 }
else if( !strcmp(
"-dbt_l2cap", argv[i]) && argc > (i+1) ) {
751 setenv(
"direct_bt.l2cap", argv[++i], 1 );
752 }
else if( !strcmp(
"-dbt_hci", argv[i]) && argc > (i+1) ) {
753 setenv(
"direct_bt.hci", argv[++i], 1 );
754 }
else if( !strcmp(
"-dbt_mgmt", argv[i]) && argc > (i+1) ) {
755 setenv(
"direct_bt.mgmt", argv[++i], 1 );
756 }
else if( !strcmp(
"-wait", argv[i]) ) {
758 }
else if( !strcmp(
"-show_update_events", argv[i]) ) {
760 }
else if( !strcmp(
"-btmode", argv[i]) && argc > (i+1) ) {
762 }
else if( !strcmp(
"-use_sc", argv[i]) && argc > (i+1) ) {
763 use_SC = 0 != atoi(argv[++i]);
764 }
else if( !strcmp(
"-adapter", argv[i]) && argc > (i+1) ) {
766 }
else if( !strcmp(
"-name", argv[i]) && argc > (i+1) ) {
768 }
else if( !strcmp(
"-short_name", argv[i]) && argc > (i+1) ) {
770 }
else if( !strcmp(
"-mtu", argv[i]) && argc > (i+1) ) {
772 }
else if( !strcmp(
"-seclevel", argv[i]) && argc > (i+1) ) {
774 }
else if( !strcmp(
"-iocap", argv[i]) && argc > (i+1) ) {
776 }
else if( !strcmp(
"-once", argv[i]) ) {
782 fprintf_td(stderr,
"Run with '[-btmode LE|BREDR|DUAL] [-use_sc 0|1] "
783 "[-adapter <adapter_address>] "
784 "[-name <adapter_name>] "
785 "[-short_name <adapter_short_name>] "
786 "[-mtu <max att_mtu>] "
787 "[-seclevel <int_sec_level>]* "
788 "[-iocap <int_iocap>]* "
790 "[-dbt_verbose true|false] "
791 "[-dbt_debug true|false|adapter.event,gatt.data,hci.event,hci.scan_ad_eir,mgmt.event] "
792 "[-dbt_mgmt cmd.timeout=3000,ringsize=64,...] "
793 "[-dbt_hci cmd.complete.timeout=10000,cmd.status.timeout=3000,ringsize=64,...] "
794 "[-dbt_gatt cmd.read.timeout=500,cmd.write.timeout=500,cmd.init.timeout=2500,ringsize=128,...] "
795 "[-dbt_l2cap reader.timeout=10000,restart.count=0,...] "
809 fprintf_td(stderr,
"GattService.characteristics: %s\n",
dbGattServer->getServices()[0]->getCharacteristics().get_info().c_str());
812 fprintf_td(stderr,
"Press ENTER to continue\n");
void writeDescValueDone(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const DBGattDescRef &d) override
Notifies completion of single or bulk writeCharValue() after having accepted and performed all write ...
void disconnected(const BTDeviceRef &device) override
Notification that device got disconnected.
bool writeDescValue(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const DBGattDescRef &d, const jau::TROOctets &value, const uint16_t value_offset) override
Signals attempt to write a single or bulk (prepare) value.
void writeCharValueDone(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c) override
Notifies completion of single or bulk writeCharValue() after having accepted and performed all write ...
void connected(const BTDeviceRef &device, const uint16_t initialMTU) override
Notification that device got connected.
void clientCharConfigChanged(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const DBGattDescRef &d, const bool notificationEnabled, const bool indicationEnabled) override
Notifies a change of the Client Characteristic Configuration Descriptor (CCCD) value.
bool readDescValue(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const DBGattDescRef &d) override
Signals attempt to read a value.
bool writeCharValue(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const jau::TROOctets &value, const uint16_t value_offset) override
Signals attempt to write a single or bulk (prepare) value.
void mtuChanged(const BTDeviceRef &device, const uint16_t mtu) override
Notification that the MTU has changed.
~MyGATTServerListener() noexcept override
bool readCharValue(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c) override
Signals attempt to read a value.
BTAdapter status listener for remote BTDevice discovery events: Added, updated and removed; as well a...
BTAdapter represents one local Bluetooth Controller.
HCIStatusCode stopAdvertising() noexcept
Ends advertising.
constexpr LE_Features getLEFeatures() const noexcept
Return LE_Features for this controller.
std::string toString() const noexcept override
void setServerConnSecurity(const BTSecurityLevel sec_level, const SMPIOCapability io_cap) noexcept
Sets the given BTSecurityLevel and SMPIOCapability for connecting device when in server (peripheral) ...
HCIStatusCode startAdvertising(const DBGattServerRef &gattServerData_, EInfoReport &eir, EIRDataType adv_mask=EIRDataType::FLAGS|EIRDataType::SERVICE_UUID, EIRDataType scanrsp_mask=EIRDataType::NAME|EIRDataType::CONN_IVAL, const uint16_t adv_interval_min=160, const uint16_t adv_interval_max=480, const AD_PDU_Type adv_type=AD_PDU_Type::ADV_IND, const uint8_t adv_chan_map=0x07, const uint8_t filter_policy=0x00) noexcept
Starts advertising.
BDAddressAndType const & getAddressAndType() const noexcept
Returns the adapter's public BDAddressAndType, i.e.
HCIStatusCode setDefaultLE_PHY(const LE_PHYs Tx, const LE_PHYs Rx) noexcept
Sets default preference of LE_PHYs.
constexpr uint16_t getBTMajorVersion() const noexcept
Returns the Bluetooth major version of this adapter.
std::string getName() const noexcept
Returns the name.
Listener to remote master device's operations on the local GATT-Server.
Representing a complete list of Gatt Service objects from the GATTRole::Server perspective,...
Collection of 'Extended Advertising Data' (EAD), 'Advertising Data' (AD) or 'Extended Inquiry Respons...
std::string toString(const bool includeServices=true) const noexcept
void setServicesComplete(const bool v) noexcept
void addFlags(GAPFlags f) noexcept
bool addService(const std::shared_ptr< const jau::uuid_t > &uuid) noexcept
void setConnInterval(const uint16_t min, const uint16_t max) noexcept
Set slave connection interval range.
Persistent endian aware octet data, i.e.
std::string toString() const
void put_string_nc(const nsize_t i, const std::string &v, const nsize_t max_len, const bool includeEOS) noexcept
Transient read only and endian aware octet data, i.e.
std::string toString() const noexcept
constexpr nsize_t size() const noexcept
Returns the used memory size for read and write operations, may be zero.
constexpr uint8_t const * get_ptr() const noexcept
This class provides a RAII-style Sequentially Consistent (SC) data race free (DRF) critical block.
Service runner, a reusable dedicated thread performing custom user services.
bool stop() noexcept
Stops this service, if running.
bool shall_stop() const noexcept
Returns true if service shall stop.
void start() noexcept
Starts this service, if not running already.
static const uint8_t filter_policy
static const jau::uuid128_t StaticDataUUID
static bool RUN_ONLY_ONCE
int main(int argc, char *argv[])
static std::string adapter_name
static BTSecurityLevel adapter_sec_level
static uint64_t timestamp_t0
static bool SHOW_UPDATE_EVENTS
static const uint16_t adv_interval_max
static const jau::uuid128_t DataServiceUUID
static jau::sc_atomic_bool sync_data
static const uint8_t adv_chan_map
DBGattServerRef dbGattServer(new DBGattServer(jau::make_darray(std::make_shared< DBGattService >(true, std::make_unique< const jau::uuid16_t >(GattServiceType::GENERIC_ACCESS), jau::make_darray(std::make_shared< DBGattChar >(std::make_unique< const jau::uuid16_t >(GattCharacteristicType::DEVICE_NAME), BTGattChar::PropertyBitVal::Read, jau::darray< DBGattDescRef >(), make_gvalue(adapter_name.c_str(), 128), true), std::make_shared< DBGattChar >(std::make_unique< const jau::uuid16_t >(GattCharacteristicType::APPEARANCE), BTGattChar::PropertyBitVal::Read, jau::darray< DBGattDescRef >(), make_gvalue((uint16_t) 0)))), std::make_shared< DBGattService >(true, std::make_unique< const jau::uuid16_t >(GattServiceType::DEVICE_INFORMATION), jau::make_darray(std::make_shared< DBGattChar >(std::make_unique< const jau::uuid16_t >(GattCharacteristicType::MANUFACTURER_NAME_STRING), BTGattChar::PropertyBitVal::Read, jau::darray< DBGattDescRef >(), make_gvalue("Gothel Software")), std::make_shared< DBGattChar >(std::make_unique< const jau::uuid16_t >(GattCharacteristicType::MODEL_NUMBER_STRING), BTGattChar::PropertyBitVal::Read, jau::darray< DBGattDescRef >(), make_gvalue("2.4.0-pre")), std::make_shared< DBGattChar >(std::make_unique< const jau::uuid16_t >(GattCharacteristicType::SERIAL_NUMBER_STRING), BTGattChar::PropertyBitVal::Read, jau::darray< DBGattDescRef >(), make_gvalue("sn:0123456789")), std::make_shared< DBGattChar >(std::make_unique< const jau::uuid16_t >(GattCharacteristicType::HARDWARE_REVISION_STRING), BTGattChar::PropertyBitVal::Read, jau::darray< DBGattDescRef >(), make_gvalue("hw:0123456789")), std::make_shared< DBGattChar >(std::make_unique< const jau::uuid16_t >(GattCharacteristicType::FIRMWARE_REVISION_STRING), BTGattChar::PropertyBitVal::Read, jau::darray< DBGattDescRef >(), make_gvalue("fw:0123456789")), std::make_shared< DBGattChar >(std::make_unique< const jau::uuid16_t >(GattCharacteristicType::SOFTWARE_REVISION_STRING), BTGattChar::PropertyBitVal::Read, jau::darray< DBGattDescRef >(), make_gvalue("sw:0123456789")))), std::make_shared< DBGattService >(true, std::make_unique< const jau::uuid128_t >(DataServiceUUID), jau::make_darray(std::make_shared< DBGattChar >(std::make_unique< const jau::uuid128_t >(StaticDataUUID), BTGattChar::PropertyBitVal::Read, jau::make_darray(std::make_shared< DBGattDesc >(BTGattDesc::TYPE_USER_DESC, make_gvalue("DATA_STATIC"))), make_gvalue("Proprietary Static Data 0x00010203")), std::make_shared< DBGattChar >(std::make_unique< const jau::uuid128_t >(CommandUUID), BTGattChar::PropertyBitVal::WriteNoAck|BTGattChar::PropertyBitVal::WriteWithAck, jau::make_darray(std::make_shared< DBGattDesc >(BTGattDesc::TYPE_USER_DESC, make_gvalue("COMMAND"))), make_gvalue(128, 64), true), std::make_shared< DBGattChar >(std::make_unique< const jau::uuid128_t >(ResponseUUID), BTGattChar::PropertyBitVal::Notify|BTGattChar::PropertyBitVal::Indicate, jau::make_darray(std::make_shared< DBGattDesc >(BTGattDesc::TYPE_USER_DESC, make_gvalue("RESPONSE")), DBGattDesc::createClientCharConfig()), make_gvalue((uint16_t) 0)), std::make_shared< DBGattChar >(std::make_unique< const jau::uuid128_t >(PulseDataUUID), BTGattChar::PropertyBitVal::Notify|BTGattChar::PropertyBitVal::Indicate, jau::make_darray(std::make_shared< DBGattDesc >(BTGattDesc::TYPE_USER_DESC, make_gvalue("DATA_PULSE")), DBGattDesc::createClientCharConfig()), make_gvalue("Synthethic Sensor 01")))))))
static void processDisconnectedDevice(BTDeviceRef device)
static std::shared_ptr< BTAdapter > chosenAdapter
static void myChangedAdapterSetFunc(const bool added, std::shared_ptr< BTAdapter > &adapter)
static bool initAdapter(std::shared_ptr< BTAdapter > &adapter)
static const jau::uuid128_t PulseDataUUID
static jau::relaxed_atomic_nsize_t servedConnections
static BTDeviceRef getDevice()
static bool stopAdvertising(BTAdapter *a, std::string msg)
static std::string adapter_short_name
static const jau::uuid128_t ResponseUUID
static const jau::uuid128_t CommandUUID
static bool startAdvertising(BTAdapter *a, std::string msg)
static void setDevice(const BTDeviceRef &cd)
static BTDeviceRef connectedDevice
static const uint16_t adv_interval_min
static const AD_PDU_Type adv_type
static SMPIOCapability adapter_sec_io_cap
static bool matches(const BTDeviceRef &device)
constexpr const char SERVER_KEY_PATH[]
uint32_t dfa_utf8_decode(uint32_t &state, uint32_t &codep, const uint32_t byte_value)
std::string to_string(const alphabet &v) noexcept
constexpr const jau::fraction_i64 THREAD_SHUTDOWN_TIMEOUT_MS
Maximum time in fractions of seconds to wait for a thread shutdown.
SMPPairingState
SMP Pairing Process state definition.
constexpr SMPIOCapability to_SMPIOCapability(const uint8_t v) noexcept
SMPIOCapability
Vol 3, Part H, 2.3.2 IO capabilities.
Entry * getStartOf(const EUI48 &addr, const std::string &name) noexcept
Returns a matching Entry,.
constexpr BTSecurityLevel to_BTSecurityLevel(const uint8_t v) noexcept
BTMode
Bluetooth adapter operating mode.
LE_Features
HCI Supported Commands.
DiscoveryPolicy
Discovery policy defines the BTAdapter discovery mode after connecting a remote BTDevice:
std::shared_ptr< BTDevice > BTDeviceRef
std::string to_string(const DiscoveryPolicy v) noexcept
LE_PHYs
LE Transport PHY bit values.
Entry * get(const EUI48 &addr, const std::string &name, AddressNameEntryMatchFunc m) noexcept
Returns a matching BTSecurityRegistry::Entry with the given addr and/or name.
ScanType
Meta ScanType as derived from BTMode, with defined value mask consisting of BDAddressType bits.
AdapterSetting
Adapter Setting Bits.
constexpr bool isAdapterSettingBitSet(const AdapterSetting mask, const AdapterSetting bit) noexcept
BTMode to_BTMode(const std::string &value) noexcept
Maps the specified name to a constant of BTMode.
BTSecurityLevel
Bluetooth Security Level.
AD_PDU_Type
LE Advertising (AD) Protocol Data Unit (PDU) Types.
PairingMode
Bluetooth secure pairing mode.
HCIStatusCode
BT Core Spec v5.2: Vol 1, Part F Controller Error Codes: 1.3 List of Error Codes.
EIRDataType
Bit mask of 'Extended Inquiry Response' (EIR) data fields, indicating a set of related data.
std::shared_ptr< DBGattDesc > DBGattDescRef
jau::POctets make_gvalue(const char *name)
Convenience jau::POctets ctor function to create DBGattChar or DBGattDesc values.
std::shared_ptr< DBGattService > DBGattServiceRef
std::shared_ptr< DBGattServer > DBGattServerRef
std::shared_ptr< DBGattChar > DBGattCharRef
constexpr darray< First > make_darray(First &&arg1, Next &&... argsN)
Construct a darray<T> instance, initialized by move semantics from the variadic (template pack) argum...
void sync() noexcept
Synchronizes filesystems, i.e.
jau::function< R(A...)> bind_member(C1 *base, R(C0::*mfunc)(A...)) noexcept
Bind given class instance and non-void member function to an anonymous function using func_member_tar...
constexpr uint32_t number(const iostate rhs) noexcept
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
std::string to_decstring(const value_type &v, const char separator=',', const nsize_t width=0) noexcept
Produce a decimal string representation of an integral integer value.
constexpr bool is_set(const cpu_family_t mask, const cpu_family_t bit) noexcept
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
uint64_t getCurrentMilliseconds() noexcept
Returns current monotonic time in milliseconds.
bool sleep_for(const fraction_timespec &relative_time, const bool monotonic=true, const bool ignore_irq=true) noexcept
sleep_for causes the current thread to block until a specific amount of time has passed.
constexpr int getPairingPasskey() const noexcept
constexpr bool getPairingNumericComparison() const noexcept
A packed 48 bit EUI-48 identifier, formerly known as MAC-48 or simply network device MAC address (Med...
std::string toString() const noexcept
CXX_ALWAYS_INLINE _Tp load() const noexcept
@ GENERIC_ACCESS
This service contains generic information about the device.
@ DEVICE_INFORMATION
This service exposes manufacturer and/or vendor information about a device.
@ SOFTWARE_REVISION_STRING
@ MANUFACTURER_NAME_STRING
@ FIRMWARE_REVISION_STRING
@ HARDWARE_REVISION_STRING