124 const AdapterSetting changedmask,
const uint64_t timestamp)
override {
125 const bool initialSetting = AdapterSetting::NONE == oldmask;
126 if( initialSetting ) {
127 fprintf_td(stderr,
"****** To Server: SETTINGS_INITIAL: %s -> %s, changed %s\n",
to_string(oldmask).c_str(),
130 fprintf_td(stderr,
"****** To Server: SETTINGS_CHANGED: %s -> %s, changed %s\n",
to_string(oldmask).c_str(),
133 fprintf_td(stderr,
"To Server: Status BTAdapter:\n");
137 if( !initialSetting &&
147 fprintf_td(stderr,
"****** To Server: DISCOVERING: meta %s, changed[%s, enabled %d, policy %s]: %s\n",
152 bool deviceFound(
const BTDeviceRef& device,
const uint64_t timestamp)
override {
159 fprintf_td(stderr,
"****** To Server: FOUND__-0: Connecting %s\n", device->toString(
true).c_str());
162 fprintf_td(stderr,
"PERF: adapter-init -> FOUND__-0 %" PRIu64
" ms\n", td);
169 fprintf_td(stderr,
"****** To Server: FOUND__-1: NOP %s\n", device->toString(
true).c_str());
175 void deviceConnected(
const BTDeviceRef& device,
const bool discovered,
const uint64_t timestamp)
override {
176 fprintf_td(stderr,
"****** To Server: CONNECTED (discovered %d): %s\n", discovered, device->toString(
true).c_str());
182 fprintf_td(stderr,
"****** To Server: PAIRING STATE: state %s, mode %s, %s\n",
186 case SMPPairingState::NONE:
189 case SMPPairingState::FAILED: {
191 fprintf_td(stderr,
"****** To Server: PAIRING_STATE: state %s; Remove key file %s, res %d\n",
195 case SMPPairingState::REQUESTED_BY_RESPONDER:
198 case SMPPairingState::FEATURE_EXCHANGE_STARTED:
201 case SMPPairingState::FEATURE_EXCHANGE_COMPLETED:
204 case SMPPairingState::PASSKEY_EXPECTED: {
206 if(
nullptr != sec && sec->
getPairingPasskey() != BTSecurityRegistry::Entry::NO_PASSKEY ) {
207 std::thread dc(&BTDevice::setPairingPasskey, device,
static_cast<uint32_t
>( sec->
getPairingPasskey() ));
210 std::thread dc(&BTDevice::setPairingPasskey, device, 0);
216 case SMPPairingState::NUMERIC_COMPARE_EXPECTED: {
218 if(
nullptr != sec ) {
222 std::thread dc(&BTDevice::setPairingNumericComparison, device,
false);
227 case SMPPairingState::OOB_EXPECTED:
230 case SMPPairingState::KEY_DISTRIBUTION:
233 case SMPPairingState::COMPLETED:
241 void deviceReady(
const BTDeviceRef& device,
const uint64_t timestamp)
override {
251 fprintf_td(stderr,
"****** To Server: READY-1: NOP %s\n", device->toString(
true).c_str());
255 void deviceDisconnected(
const BTDeviceRef& device,
const HCIStatusCode reason,
const uint16_t handle,
const uint64_t timestamp)
override {
256 fprintf_td(stderr,
"****** To Server: DISCONNECTED: Reason 0x%X (%s), old handle %s: %s\n",
257 static_cast<uint8_t
>(reason),
to_string(reason).c_str(),
258 to_hexstring(handle).c_str(), device->toString(
true).c_str());
268 std::string toString()
const noexcept override {
269 return "MyAdapterClientStatusListener[this "+
to_hexstring(
this)+
"]";
285 const TROOctets& char_value,
const uint64_t timestamp)
override
289 std::string devToClientS =
nullptr != devToClient ? devToClient->getAddressAndType().address.toString() :
"nil";
290 std::string devFromServerS = source->getAddressAndType().address.toString();
292 fprintf_td(stderr,
"%s* -> %s : Notify: handle %s\n",
293 devFromServerS.c_str(), devToClientS.c_str(),
jau::to_hexstring(char_handle).c_str());
297 std::shared_ptr<BTGattHandler> gh =
nullptr != devToClient ? devToClient->getGattHandler() :
nullptr;
298 if(
nullptr != gh ) {
299 gh->sendNotification(char_handle, char_value);
304 const TROOctets& char_value,
const uint64_t timestamp,
305 const bool confirmationSent)
override
309 std::string devToClientS =
nullptr != devToClient ? devToClient->getAddressAndType().address.toString() :
"nil";
310 std::string devFromServerS = source->getAddressAndType().address.toString();
312 fprintf_td(stderr,
"%s* -> %s : Indication: handle %s, confirmed %d\n",
313 devFromServerS.c_str(), devToClientS.c_str(),
jau::to_hexstring(char_handle).c_str(), confirmationSent);
317 std::shared_ptr<BTGattHandler> gh =
nullptr != devToClient ? devToClient->getGattHandler() :
nullptr;
318 if(
nullptr != gh ) {
319 gh->sendIndication(char_handle, char_value);
326 const uint16_t serverMTU,
327 const uint16_t usedMTU,
330 std::string serverReplierS = serverReplier->getAddressAndType().address.toString();
331 std::string clientRequesterS =
nullptr != clientRequester ? clientRequester->getAddressAndType().address.toString() :
"nil";
333 fprintf_td(stderr,
"%s <-> %s*: MTU: client %u -> %s, server %u -> used %u\n",
334 clientRequesterS.c_str(), serverReplierS.c_str(),
335 clientMTU, AttErrorRsp::getErrorCodeString(error_reply).c_str(), serverMTU, usedMTU);
336 if( AttErrorRsp::ErrorCode::NO_ERROR != error_reply ) {
345 const bool with_response,
348 std::string serverDestS = serverDest->getAddressAndType().address.toString();
349 std::string clientSourceS =
nullptr != clientSource ? clientSource->getAddressAndType().address.toString() :
"nil";
351 fprintf_td(stderr,
"%s -> %s*: Write-Req: handle %s, with_response %d\n",
352 clientSourceS.c_str(), serverDestS.c_str(),
jau::to_hexstring(handle).c_str(), with_response);
357 fprintf(stderr,
"%s, ", s.toString().c_str());
359 fprintf(stderr,
"\n");
367 std::string serverSourceS = serverSource->getAddressAndType().address.toString();
368 std::string clientDestS =
nullptr != clientDest ? clientDest->getAddressAndType().address.toString() :
"nil";
370 fprintf_td(stderr,
"%s* -> %s : Write-Rsp: %s\n",
371 serverSourceS.c_str(), clientDestS.c_str(), AttErrorRsp::getErrorCodeString(error_code).c_str());
378 const uint16_t value_offset,
384 std::string serverReplierS = serverReplier->getAddressAndType().address.toString();
385 std::string clientRequesterS =
nullptr != clientRequester ? clientRequester->getAddressAndType().address.toString() :
"nil";
387 fprintf_td(stderr,
"%s <-> %s*: Read: handle %s, value_offset %d -> %s\n",
388 clientRequesterS.c_str(), serverReplierS.c_str(),
389 jau::to_hexstring(handle).c_str(), value_offset, AttErrorRsp::getErrorCodeString(error_reply).c_str());
390 if( 0 < data_reply.
size() ) {
402 fprintf_td(stderr,
"****** To Server: Connecting Device: Start %s\n", device->toString().c_str());
405 if(
nullptr != sec ) {
406 fprintf_td(stderr,
"****** To Server: Connecting Device: Found SecurityDetail %s for %s\n", sec->
toString().c_str(), device->toString().c_str());
408 fprintf_td(stderr,
"****** To Server: Connecting Device: No SecurityDetail for %s\n", device->toString().c_str());
412 fprintf_td(stderr,
"****** Connecting Device: BTDevice::uploadKeys(...) result %s\n",
to_string(res).c_str());
413 if( HCIStatusCode::SUCCESS != res ) {
414 if(
nullptr != sec ) {
417 fprintf_td(stderr,
"****** To Server: Connecting Device: Using SecurityDetail.SEC AUTO %s, set OK %d\n", sec->
toString().c_str(), r);
420 fprintf_td(stderr,
"****** To Server: Connecting Device: Using SecurityDetail.Level+IOCap %s, set OK %d\n", sec->
toString().c_str(), r);
422 bool r = device->setConnSecurityAuto( SMPIOCapability::KEYBOARD_ONLY );
423 fprintf_td(stderr,
"****** To Server: Connecting Device: Setting SEC AUTO security detail w/ KEYBOARD_ONLY (%s) -> set OK %d\n", sec->
toString().c_str(), r);
426 bool r = device->setConnSecurityAuto( SMPIOCapability::KEYBOARD_ONLY );
427 fprintf_td(stderr,
"****** To Server: Connecting Device: Setting SEC AUTO security detail w/ KEYBOARD_ONLY -> set OK %d\n", r);
430 std::shared_ptr<const EInfoReport> eir = device->getEIR();
431 fprintf_td(stderr,
"To Server: EIR-1 %s\n", device->getEIRInd()->toString().c_str());
432 fprintf_td(stderr,
"To Server: EIR-2 %s\n", device->getEIRScanRsp()->toString().c_str());
433 fprintf_td(stderr,
"To Server: EIR-+ %s\n", eir->toString().c_str());
435 uint16_t conn_interval_min = (uint16_t)12;
436 uint16_t conn_interval_max = (uint16_t)12;
437 const uint16_t conn_latency = (uint16_t)0;
438 if( eir->isSet(EIRDataType::CONN_IVAL) ) {
439 eir->getConnInterval(conn_interval_min, conn_interval_max);
443 fprintf_td(stderr,
"****** To Server: Connecting Device: End result %s of %s\n",
to_string(res).c_str(), device->toString().c_str());
447 fprintf_td(stderr,
"****** To Server: Processing Ready Device: Start %s\n", device->toString().c_str());
451 bool success =
false;
453 if( device->getAdapter().getBTMajorVersion() > 4 ) {
454 LE_PHYs Tx { LE_PHYs::LE_2M }, Rx { LE_PHYs::LE_2M };
456 fprintf_td(stderr,
"****** To Server: Set Connected LE PHY: status %s: Tx %s, Rx %s\n",
461 HCIStatusCode res = device->getConnectedLE_PHY(resTx, resRx);
462 fprintf_td(stderr,
"****** To Server: Got Connected LE PHY: status %s: Tx %s, Rx %s\n",
469 fprintf_td(stderr,
"****** To Server: Processing Ready Device: GATT start: %s\n", device->getAddressAndType().toString().c_str());
471 std::shared_ptr<BTGattHandler> gh = device->getGattHandler();
472 gh->addCharListener( std::make_shared<NativeGattToServerCharListener>() );
478 device->disconnect(HCIStatusCode::REMOTE_USER_TERMINATED_CONNECTION);
483 }
catch ( std::exception & e ) {
484 fprintf_td(stderr,
"****** To Server: Processing Ready Device: Exception caught for %s: %s\n", device->toString().c_str(), e.what());
487 fprintf_td(stderr,
"****** To Server: Processing Ready Device: End-1: Success %d on %s\n", success, device->toString().c_str());
496 fprintf_td(stderr,
"****** To Server: Remove Device: %s\n", device->getAddressAndType().toString().c_str());
509 fprintf_td(stderr,
"****** To Server: Disconnected: %s\n", device->toString().c_str());
510 device->disconnect(HCIStatusCode::DISCONNECTED);
524 fprintf_td(stderr,
"****** To Server: Start discovery (%s): Adapter not selected: %s\n", msg.c_str(), a->
toString().c_str());
528 fprintf_td(stderr,
"****** To Server: Start discovery (%s) result: %s: %s\n", msg.c_str(),
to_string(status).c_str(), a->
toString().c_str());
529 return HCIStatusCode::SUCCESS == status;
534 fprintf_td(stderr,
"initAdapterToServer: Adapter not selected: %s\n", adapter->toString().c_str());
538 if( !adapter->isInitialized() ) {
540 if( HCIStatusCode::SUCCESS != status ) {
541 fprintf_td(stderr,
"initAdapterToServer: Adapter initialization failed: %s: %s\n",
542 to_string(status).c_str(), adapter->toString().c_str());
545 }
else if( !adapter->setPowered(
true ) ) {
546 fprintf_td(stderr,
"initAdapterToServer: Already initialized adapter power-on failed:: %s\n", adapter->toString().c_str());
550 fprintf_td(stderr,
"initAdapterToServer: %s\n", adapter->toString().c_str());
552 const LE_Features le_feats = adapter->getLEFeatures();
555 if( adapter->getBTMajorVersion() > 4 ) {
556 LE_PHYs Tx { LE_PHYs::LE_2M }, Rx { LE_PHYs::LE_2M };
558 fprintf_td(stderr,
"initAdapterToServer: Set Default LE PHY: status %s: Tx %s, Rx %s\n",
562 adapter->addStatusListener( asl );
565 adapter->removeStatusListener( asl );
578 const AdapterSetting changedmask,
const uint64_t timestamp)
override {
579 const bool initialSetting = AdapterSetting::NONE == oldmask;
580 if( initialSetting ) {
581 fprintf_td(stderr,
"****** To Client: SETTINGS_INITIAL: %s -> %s, changed %s\n",
to_string(oldmask).c_str(),
584 fprintf_td(stderr,
"****** To Client: SETTINGS_CHANGED: %s -> %s, changed %s\n",
to_string(oldmask).c_str(),
587 fprintf_td(stderr,
"To Client: Status BTAdapter:\n");
593 fprintf_td(stderr,
"****** To Client: DISCOVERING: meta %s, changed[%s, enabled %d, policy %s]: %s\n",
598 bool deviceFound(
const BTDeviceRef& device,
const uint64_t timestamp)
override {
601 fprintf_td(stderr,
"****** To Client: FOUND__-1: NOP %s\n", device->toString(
true).c_str());
605 void deviceConnected(
const BTDeviceRef& device,
const bool discovered,
const uint64_t timestamp)
override {
606 fprintf_td(stderr,
"****** To Client: CONNECTED (discovered %d): %s\n", discovered, device->toString(
true).c_str());
612 fprintf_td(stderr,
"****** To Client: PAIRING STATE: state %s, mode %s, %s\n",
616 case SMPPairingState::NONE:
619 case SMPPairingState::FAILED: {
622 case SMPPairingState::REQUESTED_BY_RESPONDER:
625 case SMPPairingState::FEATURE_EXCHANGE_STARTED:
628 case SMPPairingState::FEATURE_EXCHANGE_COMPLETED:
631 case SMPPairingState::PASSKEY_EXPECTED: {
633 if(
nullptr != sec && sec->
getPairingPasskey() != BTSecurityRegistry::Entry::NO_PASSKEY ) {
634 std::thread dc(&BTDevice::setPairingPasskey, device,
static_cast<uint32_t
>( sec->
getPairingPasskey() ));
637 std::thread dc(&BTDevice::setPairingPasskey, device, 0);
643 case SMPPairingState::NUMERIC_COMPARE_EXPECTED: {
645 if(
nullptr != sec ) {
649 std::thread dc(&BTDevice::setPairingNumericComparison, device,
false);
654 case SMPPairingState::OOB_EXPECTED:
657 case SMPPairingState::KEY_DISTRIBUTION:
660 case SMPPairingState::COMPLETED:
668 void deviceReady(
const BTDeviceRef& device,
const uint64_t timestamp)
override {
674 fprintf_td(stderr,
"****** To Client: READY-0: Processing %s\n", device->toString(
true).c_str());
677 void deviceDisconnected(
const BTDeviceRef& device,
const HCIStatusCode reason,
const uint16_t handle,
const uint64_t timestamp)
override {
679 fprintf_td(stderr,
"****** DISCONNECTED (count %zu): Reason 0x%X (%s), old handle %s: %s\n",
681 to_hexstring(handle).c_str(), device->toString(
true).c_str());
692 std::string toString()
const noexcept override {
693 return "MyAdapterServerStatusListener[this "+
to_hexstring(
this)+
"]";
699 fprintf_td(stderr,
"****** To Client: Disconnected Device (count %zu): Start %s\n",
712 if(
nullptr != devToServer ) {
719 fprintf_td(stderr,
"****** To Client: Disonnected Device: End %s\n", device->toString().c_str());
728 if(
nullptr == devToServer ) {
729 fprintf_td(stderr,
"To Client: Start advertising: Skipped, not connected to server\n");
742 if(
nullptr != gattDevNameChar ) {
743 std::string aname = a->getName();
744 gattDevNameChar->setValue(
reinterpret_cast<uint8_t*
>(aname.data()), aname.size(), 0);
747 fprintf_td(stderr,
"****** To Client: Start advertising (%s): EIR %s\n", msg.c_str(), eir.
toString().c_str());
748 fprintf_td(stderr,
"****** To Client: Start advertising (%s): adv %s, scanrsp %s\n", msg.c_str(),
to_string(ind_mask).c_str(),
to_string(scanrsp_mask).c_str());
753 fprintf_td(stderr,
"****** To Client: Start advertising (%s) result: %s: %s\n", msg.c_str(),
to_string(status).c_str(), a->toString().c_str());
755 return HCIStatusCode::SUCCESS == status;
760 fprintf_td(stderr,
"****** To Client: Stop advertising (%s) result: %s: %s\n", msg.c_str(),
to_string(status).c_str(), a->toString().c_str());
761 return HCIStatusCode::SUCCESS == status;
766 fprintf_td(stderr,
"initAdapterToClient: Adapter not selected: %s\n", adapter->toString().c_str());
769 if( !adapter->isInitialized() ) {
772 if( HCIStatusCode::SUCCESS != status ) {
773 fprintf_td(stderr,
"initAdapterToClient: initialize failed: %s: %s\n",
774 to_string(status).c_str(), adapter->toString().c_str());
777 }
else if( !adapter->setPowered(
false ) ) {
778 fprintf_td(stderr,
"initAdapterToClient: setPower.1 off failed: %s\n", adapter->toString().c_str());
782 fprintf_td(stderr,
"initAdapterToClient.1: %s\n", adapter->toString().c_str());
786 if( HCIStatusCode::SUCCESS == status ) {
787 fprintf_td(stderr,
"initAdapterToClient: setLocalName OK: %s\n", adapter->toString().c_str());
789 fprintf_td(stderr,
"initAdapterToClient: setLocalName failed: %s\n", adapter->toString().c_str());
794 if( HCIStatusCode::SUCCESS == status ) {
795 fprintf_td(stderr,
"initAdapterToClient: setSecureConnections OK: %s\n", adapter->toString().c_str());
797 fprintf_td(stderr,
"initAdapterToClient: setSecureConnections failed: %s\n", adapter->toString().c_str());
801 const uint16_t conn_min_interval = 8;
802 const uint16_t conn_max_interval = 40;
803 const uint16_t conn_latency = 0;
804 const uint16_t supervision_timeout = 50;
805 status = adapter->setDefaultConnParam(conn_min_interval, conn_max_interval, conn_latency, supervision_timeout);
806 if( HCIStatusCode::SUCCESS == status ) {
807 fprintf_td(stderr,
"initAdapterToClient: setDefaultConnParam OK: %s\n", adapter->toString().c_str());
808 }
else if( HCIStatusCode::UNKNOWN_COMMAND == status ) {
809 fprintf_td(stderr,
"initAdapterToClient: setDefaultConnParam UNKNOWN_COMMAND (ignored): %s\n", adapter->toString().c_str());
811 fprintf_td(stderr,
"initAdapterToClient: setDefaultConnParam failed: %s, %s\n",
to_string(status).c_str(), adapter->toString().c_str());
815 if( !adapter->setPowered(
true ) ) {
816 fprintf_td(stderr,
"initAdapterToClient: setPower.2 on failed: %s\n", adapter->toString().c_str());
820 fprintf_td(stderr,
"initAdapterToClient.2: %s\n", adapter->toString().c_str());
823 const LE_Features le_feats = adapter->getLEFeatures();
826 if( adapter->getBTMajorVersion() > 4 ) {
827 LE_PHYs Tx { LE_PHYs::LE_2M }, Rx { LE_PHYs::LE_2M };
829 fprintf_td(stderr,
"initAdapterToClient: Set Default LE PHY: status %s: Tx %s, Rx %s\n",
834 std::shared_ptr<AdapterStatusListener> asl( std::make_shared<AdapterToClientStatusListener>() );
835 adapter->addStatusListener( asl );
851 fprintf_td(stderr,
"****** AdapterToServer ADDED__: InitOK: %s\n", adapter->toString().c_str());
858 fprintf_td(stderr,
"****** AdapterToClient ADDED__: InitOK: %s\n", adapter->toString().c_str());
862 fprintf_td(stderr,
"****** Adapter ADDED__: Ignored: %s\n", adapter->toString().c_str());
866 fprintf_td(stderr,
"****** AdapterToServer REMOVED: %s\n", adapter->toString().c_str());
871 fprintf_td(stderr,
"****** AdapterToClient REMOVED: %s\n", adapter->toString().c_str());
874 fprintf_td(stderr,
"****** Adapter REMOVED: Ignored %s\n", adapter->toString().c_str());
896 fprintf_td(stderr,
"****** EOL Adapter's Devices - pre close: %s\n", adapter->toString().c_str());
897 adapter->printDeviceLists();
901 fprintf_td(stderr,
"****** EOL Removed ChangedAdapterSetCallback %zu\n", (
size_t)count);
906 fprintf_td(stderr,
"****** EOL Adapter's Devices - post close: %s\n", adapter->toString().c_str());
907 adapter->printDeviceLists();
913int main(
int argc,
char *argv[])
915 bool waitForEnter=
false;
917 fprintf_td(stderr,
"Direct-BT Native Version %s (API %s)\n", DIRECT_BT_VERSION, DIRECT_BT_VERSION_API);
919 for(
int i=1; i<argc; i++) {
920 fprintf(stderr,
"arg[%d/%d]: '%s'\n", i, argc, argv[i]);
922 if( !strcmp(
"-dbt_debug", argv[i]) && argc > (i+1) ) {
923 setenv(
"direct_bt.debug", argv[++i], 1 );
924 }
else if( !strcmp(
"-dbt_verbose", argv[i]) && argc > (i+1) ) {
925 setenv(
"direct_bt.verbose", argv[++i], 1 );
926 }
else if( !strcmp(
"-dbt_gatt", argv[i]) && argc > (i+1) ) {
927 setenv(
"direct_bt.gatt", argv[++i], 1 );
928 }
else if( !strcmp(
"-dbt_l2cap", argv[i]) && argc > (i+1) ) {
929 setenv(
"direct_bt.l2cap", argv[++i], 1 );
930 }
else if( !strcmp(
"-dbt_hci", argv[i]) && argc > (i+1) ) {
931 setenv(
"direct_bt.hci", argv[++i], 1 );
932 }
else if( !strcmp(
"-dbt_mgmt", argv[i]) && argc > (i+1) ) {
933 setenv(
"direct_bt.mgmt", argv[++i], 1 );
934 }
else if( !strcmp(
"-wait", argv[i]) ) {
936 }
else if( !strcmp(
"-quiet", argv[i]) ) {
938 }
else if( !strcmp(
"-discoveryPolicy", argv[i]) ) {
940 }
else if( !strcmp(
"-btmode", argv[i]) && argc > (i+1) ) {
942 }
else if( !strcmp(
"-use_sc", argv[i]) && argc > (i+1) ) {
944 }
else if( !strcmp(
"-adapterToClient", argv[i]) && argc > (i+1) ) {
946 }
else if( !strcmp(
"-nameToClient", argv[i]) && argc > (i+1) ) {
948 }
else if( !strcmp(
"-mtuToClient", argv[i]) && argc > (i+1) ) {
950 }
else if( !strcmp(
"-seclevelToClient", argv[i]) && argc > (i+1) ) {
953 }
else if( !strcmp(
"-adapterToServer", argv[i]) && argc > (i+1) ) {
955 }
else if( !strcmp(
"-server", argv[i]) && argc > (i+1) ) {
956 std::string addrOrNameSub = std::string(argv[++i]);
958 }
else if( !strcmp(
"-passkeyToServer", argv[i]) && argc > (i+2) ) {
959 const std::string addrOrNameSub(argv[++i]);
961 sec->
passkey = atoi(argv[++i]);
962 fprintf(stderr,
"Set passkey to server in %s\n", sec->
toString().c_str());
963 }
else if( !strcmp(
"-seclevelToServer", argv[i]) && argc > (i+2) ) {
964 const std::string addrOrNameSub(argv[++i]);
967 fprintf(stderr,
"Set sec_level to server in %s\n", sec->
toString().c_str());
968 }
else if( !strcmp(
"-iocapToServer", argv[i]) && argc > (i+2) ) {
969 const std::string addrOrNameSub(argv[++i]);
972 fprintf(stderr,
"Set io_cap to server in %s\n", sec->
toString().c_str());
973 }
else if( !strcmp(
"-secautoToServer", argv[i]) && argc > (i+2) ) {
974 const std::string addrOrNameSub(argv[++i]);
977 fprintf(stderr,
"Set SEC AUTO security io_cap to server in %s\n", sec->
toString().c_str());
978 }
else if( !strcmp(
"-count", argv[i]) && argc > (i+1) ) {
984 fprintf_td(stderr,
"Run with '[-btmode LE|BREDR|DUAL] [-use_sc 0|1] [-count <connection_number>] [-quiet] "
985 "[-discoveryPolicy <0-4>] "
986 "[-adapterToClient <adapter_address>] "
987 "[-nameToClient <adapter_name>] "
988 "[-mtuToClient <max att_mtu>] "
989 "[-seclevelToClient <int_sec_level>]* "
990 "[-adapterToServer <adapter_address>] "
991 "(-server <device_[address|name]_sub>)* "
992 "(-seclevelToServer <device_[address|name]_sub> <int_sec_level>)* "
993 "(-iocapToServer <device_[address|name]_sub> <int_iocap>)* "
994 "(-secautoToServer <device_[address|name]_sub> <int_iocap>)* "
995 "(-passkeyToServer <device_[address|name]_sub> <digits>)* "
996 "[-dbt_verbose true|false] "
997 "[-dbt_debug true|false|adapter.event,gatt.data,hci.event,hci.scan_ad_eir,mgmt.event] "
998 "[-dbt_mgmt cmd.timeout=3000,ringsize=64,...] "
999 "[-dbt_hci cmd.complete.timeout=10000,cmd.status.timeout=3000,ringsize=64,...] "
1000 "[-dbt_gatt cmd.read.timeout=500,cmd.write.timeout=500,cmd.init.timeout=2500,ringsize=128,...] "
1001 "[-dbt_l2cap reader.timeout=10000,restart.count=0,...] "
1006 fprintf_td(stderr,
"To Client Settings (acting as server):\n");
1012 fprintf_td(stderr,
"To Server Settings (acting as client):\n");
1019 if( waitForEnter ) {
1020 fprintf_td(stderr,
"Press ENTER to continue\n");
1029 fprintf_td(stderr,
"****** Manager close start\n");
1032 fprintf_td(stderr,
"****** Manager close end\n");
void mtuResponse(const uint16_t clientMTU, const AttPDUMsg &pduReply, const AttErrorRsp::ErrorCode error_reply, const uint16_t serverMTU, const uint16_t usedMTU, const BTDeviceRef &serverReplier, const BTDeviceRef &clientRequester) override
Informal notification about a complete MTU exchange request and response to and from this GATTRole::S...
void readResponse(const uint16_t handle, const uint16_t value_offset, const AttPDUMsg &pduReply, const AttErrorRsp::ErrorCode error_reply, const jau::TROOctets &data_reply, const BTDeviceRef &serverReplier, const BTDeviceRef &clientRequester) override
Informal notification about a complete read request and response to and from this GATTRole::Server,...
BTDeviceRef getToClient() noexcept
void writeResponse(const AttPDUMsg &pduReply, const AttErrorRsp::ErrorCode error_code, const BTDeviceRef &serverSource, const BTDeviceRef &clientDest) override
Informal notification about a write response received from this GATTRole::Server, optional.
void indicationReceived(const BTDeviceRef &source, const uint16_t char_handle, const TROOctets &char_value, const uint64_t timestamp, const bool confirmationSent) override
Called from native BLE stack, initiated by a received indication.
NativeGattToServerCharListener()=default
void writeRequest(const uint16_t handle, const jau::TROOctets &data, const jau::darray< Section > §ions, const bool with_response, const BTDeviceRef &serverDest, const BTDeviceRef &clientSource) override
Informal notification about a completed write request sent to this GATTRole::Server,...
void notificationReceived(const BTDeviceRef &source, const uint16_t char_handle, const TROOctets &char_value, const uint64_t timestamp) override
Called from native BLE stack, initiated by a received notification.
BTAdapter status listener for remote BTDevice discovery events: Added, updated and removed; as well a...
Handles the Attribute Protocol (ATT) using Protocol Data Unit (PDU) encoded messages over L2CAP chann...
virtual std::string toString() const noexcept
BTAdapter represents one local Bluetooth Controller.
std::string toString() const noexcept override
HCIStatusCode startDiscovery(const DBGattServerRef &gattServerData_=nullptr, const DiscoveryPolicy policy=DiscoveryPolicy::PAUSE_CONNECTED_UNTIL_READY, const bool le_scan_active=true, const uint16_t le_scan_interval=24, const uint16_t le_scan_window=24, const uint8_t filter_policy=0x00, const bool filter_dup=true) noexcept
Starts discovery.
BDAddressAndType const & getAddressAndType() const noexcept
Returns the adapter's public BDAddressAndType, i.e.
bool setPowered(const bool power_on) noexcept
Set the power state of the adapter.
Native GATT characteristic event listener for notification and indication events received from a GATT...
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
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
Implementation of a dynamic linear array storage, aka vector.
This class provides a RAII-style Sequentially Consistent (SC) data race free (DRF) critical block.
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("Jausoft_Dev", 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")))))))
static const uint8_t filter_policy
int main(int argc, char *argv[])
static BTAdapterRef adapterToServer
static const uint16_t le_scan_interval
static uint64_t timestamp_t0
static EUI48 adapterToClientAddr
static const uint16_t adv_interval_max
static const uint16_t le_scan_window
static uint16_t max_att_mtu_to_client
static std::string adapterToClientShortName
static std::atomic< int > serverDeviceReadyCount
static jau::sc_atomic_bool sync_data
static void processReadyToServer(const BTDeviceRef &device)
static const uint8_t adv_chan_map
static void removeDeviceToServer(BTDeviceRef device)
static void myChangedAdapterSetFunc(const bool added, std::shared_ptr< BTAdapter > &adapter)
static EUI48 adapterToServerAddr
static std::string adapterToClientName
static bool adapterToClientUseSC
static BTDeviceRef connectedDeviceToServer
static bool initAdapterToClient(std::shared_ptr< BTAdapter > &adapter)
static BTDeviceRef connectedDeviceToClient
static DiscoveryPolicy discoveryPolicy
static void processDisconnectedDeviceToClient(BTDeviceRef device)
static BTSecurityLevel adapterToClientSecLevel
static bool initAdapterToServer(std::shared_ptr< BTAdapter > &adapter)
static const bool le_scan_active
static void connectToDiscoveredServer(BTDeviceRef device)
static bool startDiscoveryToServer(BTAdapter *a, std::string msg)
static bool startAdvertisingToClient(const BTAdapterRef &a, const std::string &msg)
static BTAdapterRef adapterToClient
static jau::nsize_t MAX_SERVED_CONNECTIONS
static const uint16_t adv_interval_min
static const AD_PDU_Type adv_type
static bool stopAdvertisingToClient(const BTAdapterRef &a, const std::string &msg)
static void resetConnectionToServer(BTDeviceRef device)
static jau::relaxed_atomic_nsize_t servedClientConnections
constexpr const char SERVER_KEY_PATH[]
constexpr const char CLIENT_KEY_PATH[]
C++20 we could use constexpr std::string
constexpr UnaryFunction for_each_const(T &data, UnaryFunction f, std::enable_if_t< is_cow_type< T >::value, bool >=true) noexcept
uint32_t dfa_utf8_decode(uint32_t &state, uint32_t &codep, const uint32_t byte_value)
std::string to_string(const alphabet &v) noexcept
SMPPairingState
SMP Pairing Process state definition.
constexpr SMPIOCapability to_SMPIOCapability(const uint8_t v) noexcept
constexpr const EIRDataType EIR_DATA_TYPE_MASK
Explicit mask to erase all implicit set EIRDataType fields: EVT_TYPE, EXT_EVT_TYPE,...
Entry * getStartOf(const EUI48 &addr, const std::string &name) noexcept
Returns a matching Entry,.
constexpr BTSecurityLevel to_BTSecurityLevel(const uint8_t v) noexcept
Entry * getOrCreate(const std::string &addrOrNameSub) noexcept
Determines whether the given addrOrNameSub is a EUI48Sub or just a name and retrieves an entry.
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::shared_ptr< BTAdapter > BTAdapterRef
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.
std::string allToString() noexcept
BTSecurityLevel
Bluetooth Security Level.
AD_PDU_Type
LE Advertising (AD) Protocol Data Unit (PDU) Types.
PairingMode
Bluetooth secure pairing mode.
constexpr DiscoveryPolicy to_DiscoveryPolicy(const uint8_t v) noexcept
constexpr uint16_t getHCIConnSupervisorTimeout(const uint16_t conn_latency, const uint16_t conn_interval_max_ms, const uint16_t min_result_ms=number(HCIConstInt::LE_CONN_MIN_TIMEOUT_MS), const uint16_t multiplier=10) noexcept
Defining the supervising timeout for LE connections to be a multiple of the maximum connection interv...
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< DBGattServer > DBGattServerRef
std::shared_ptr< DBGattChar > DBGattCharRef
bool remove(const std::string &path, const traverse_options topts=traverse_options::none) noexcept
Remove the given path.
void sync() noexcept
Synchronizes filesystems, i.e.
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
void addToWaitForDevices(const std::string &addrOrNameSub) noexcept
std::string getWaitForDevicesString() noexcept
bool isWaitingForAnyDevice() noexcept
void addToProcessedDevices(const BDAddressAndType &a, const std::string &n) noexcept
bool isWaitingForDevice(const EUI48 &address, const std::string &name, DeviceQueryMatchFunc m) noexcept
Returns true if the given address and/or name matches any of the BTDeviceRegistry::addToWaitForDevice...
__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.
BTSecurityLevel sec_level
SMPIOCapability io_cap_auto
constexpr bool isSecLevelOrIOCapSet() const noexcept
constexpr const BTSecurityLevel & getSecLevel() const noexcept
constexpr int getPairingPasskey() const noexcept
constexpr bool getPairingNumericComparison() const noexcept
constexpr const SMPIOCapability & getSecurityAutoIOCap() const noexcept
constexpr const SMPIOCapability & getIOCap() const noexcept
constexpr bool isSecurityAutoEnabled() const noexcept
std::string toString() 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.