41 #include "BTIoctl.hpp"
43 #include "HCIIoctl.hpp"
60 BTMode MgmtEnv::getEnvBTMode() {
71 MgmtEnv::MgmtEnv() noexcept
73 exploding(
jau::environment::getExplodingProperties("
direct_bt.mgmt") ),
74 MGMT_READER_THREAD_POLL_TIMEOUT(
jau::environment::getInt32Property("
direct_bt.mgmt.reader.timeout", 10000, 1500 , INT32_MAX ) ),
75 MGMT_COMMAND_REPLY_TIMEOUT(
jau::environment::getInt32Property("
direct_bt.mgmt.cmd.timeout", 3000, 1500 , INT32_MAX ) ),
76 MGMT_EVT_RING_CAPACITY(
jau::environment::getInt32Property("
direct_bt.mgmt.ringsize", 64, 64 , 1024 ) ),
77 DEBUG_EVENT(
jau::environment::getBooleanProperty("
direct_bt.debug.mgmt.event", false) ),
78 DEFAULT_BTMODE( getEnvBTMode() ),
79 MGMT_READ_PACKET_MAX_RETRY( MGMT_EVT_RING_CAPACITY )
84 std::mutex BTManager::mtx_singleton;
86 void BTManager::mgmtReaderThreadImpl() noexcept {
88 const std::lock_guard<std::mutex> lock(mtx_mgmtReaderLifecycle);
89 mgmtReaderShallStop =
false;
90 mgmtReaderRunning =
true;
92 cv_mgmtReaderInit.notify_all();
95 DBG_PRINT(
"DBTManager::mgmtReaderThreadCleanup: mgmtReaderRunning %d -> 0", mgmtReaderRunning.
load());
96 mgmtReaderRunning =
false;
99 while( !mgmtReaderShallStop ) {
103 ERR_PRINT(
"DBTManager::reader: Not connected");
104 mgmtReaderShallStop =
true;
120 if( mgmtEventRing.isFull() ) {
121 const jau::nsize_t dropCount = mgmtEventRing.capacity()/4;
122 mgmtEventRing.drop(dropCount);
123 WARN_PRINT(
"DBTManager-IO RECV Drop (%u oldest elements of %u capacity, ring full)", dropCount, mgmtEventRing.capacity());
125 mgmtEventRing.putBlocking( std::move( event ) );
128 std::thread adapterAddedThread(&BTManager::processAdapterAdded,
this, std::move( event) );
129 adapterAddedThread.detach();
132 std::thread adapterRemovedThread(&BTManager::processAdapterRemoved,
this, std::move( event ) );
133 adapterRemovedThread.detach();
139 }
else if( ETIMEDOUT != errno && !mgmtReaderShallStop ) {
140 ERR_PRINT(
"DBTManager::reader: HCIComm read error");
144 const std::lock_guard<std::mutex> lock(mtx_mgmtReaderLifecycle);
145 WORDY_PRINT(
"DBTManager::reader: Ended. Ring has %u entries flushed", mgmtEventRing.getSize());
146 mgmtEventRing.clear();
147 mgmtReaderRunning =
false;
148 cv_mgmtReaderInit.notify_all();
155 const uint16_t dev_id =
event.getDevID();
162 cb.getCallback().invoke(event);
163 } catch (std::exception &e) {
164 ERR_PRINT(
"DBTManager::sendMgmtEvent-CBs %d/%zd: MgmtAdapterEventCallback %s : Caught exception %s",
165 invokeCount+1, mgmtEventCallbackList.
size(),
172 COND_PRINT(env.DEBUG_EVENT,
"DBTManager::sendMgmtEvent: Event %s -> %d/%zd callbacks", event.toString().c_str(), invokeCount, mgmtEventCallbackList.size());
177 bool pidMatch = info->si_pid == BTManager::pidSelf;
178 WORDY_PRINT(
"DBTManager.sigaction: sig %d, info[code %d, errno %d, signo %d, pid %d, uid %d, fd %d], pid-self %d (match %d)",
179 sig, info->si_code, info->si_errno, info->si_signo,
180 info->si_pid, info->si_uid, info->si_fd,
181 BTManager::pidSelf, pidMatch);
184 if( !pidMatch || SIGALRM != sig ) {
191 struct sigaction sa_setup;
192 bzero(&sa_setup,
sizeof(sa_setup));
193 sa_setup.sa_handler = SIG_DFL;
194 sigemptyset(&(sa_setup.sa_mask));
195 sa_setup.sa_flags = 0;
196 if( 0 != sigaction( SIGALRM, &sa_setup, NULL ) ) {
197 ERR_PRINT(
"DBTManager.sigaction: Resetting sighandler");
204 const std::lock_guard<std::recursive_mutex> lock(mtx_sendReply);
205 COND_PRINT(env.DEBUG_EVENT,
"DBTManager-IO SENT %s", req.toString().c_str());
208 ERR_PRINT(
"DBTManager::sendWithReply: HCIComm write error, req %s", req.toString().c_str());
214 std::unique_ptr<MgmtEvent> BTManager::sendWithReply(
MgmtCommand &req) noexcept {
215 const std::lock_guard<std::recursive_mutex> lock(mtx_sendReply);
221 int32_t retryCount = 0;
222 while( retryCount < env.MGMT_READ_PACKET_MAX_RETRY ) {
223 std::unique_ptr<MgmtEvent> res = mgmtEventRing.getBlocking(env.MGMT_COMMAND_REPLY_TIMEOUT);
225 if(
nullptr == res ) {
227 ERR_PRINT(
"DBTManager::sendWithReply.X: nullptr result (timeout -> abort): req %s", req.toString().c_str());
232 COND_PRINT(env.DEBUG_EVENT,
"DBTManager-IO RECV sendWithReply: res mismatch (drop evt, retryCount %d): res %s; req %s",
233 retryCount, res->
toString().c_str(), req.toString().c_str());
236 COND_PRINT(env.DEBUG_EVENT,
"DBTManager-IO RECV sendWithReply: res %s; req %s", res->
toString().c_str(), req.toString().c_str());
251 #if USE_LINUX_BT_SECURITY
252 const uint8_t debug_keys = 0;
253 const uint8_t ssp_on_param = 0x01;
254 const uint8_t sc_on_param = 0x01;
257 std::unique_ptr<AdapterInfo> adapterInfo(
nullptr);
259 MgmtCommand req0(MgmtCommand::Opcode::READ_INFO, dev_id);
261 std::unique_ptr<MgmtEvent> res = sendWithReply(req0);
262 if(
nullptr == res ) {
265 if( MgmtEvent::Opcode::CMD_COMPLETE != res->
getOpcode() || res->
getTotalSize() < MgmtEvtAdapterInfo::getRequiredTotalSize()) {
266 ERR_PRINT(
"Insufficient data for adapter info: req %d, res %s", MgmtEvtAdapterInfo::getRequiredTotalSize(), res->
toString().c_str());
271 if( dev_id != adapterInfo->dev_id ) {
272 ABORT(
"AdapterInfo dev_id=%d != dev_id=%d: %s", adapterInfo->dev_id, dev_id, adapterInfo->toString().c_str());
275 DBG_PRINT(
"initAdapter[%d, BTMode %s]: Start: %s", dev_id,
to_string(btMode).c_str(), adapterInfo->toString().c_str());
276 current_settings = adapterInfo->getCurrentSettingMask();
278 setMode(dev_id, MgmtCommand::Opcode::SET_POWERED, 0, current_settings);
282 setMode(dev_id, MgmtCommand::Opcode::SET_BREDR, 1, current_settings);
283 setDiscoverable(dev_id, 0, 0, current_settings);
284 setMode(dev_id, MgmtCommand::Opcode::SET_LE, 1, current_settings);
285 #if USE_LINUX_BT_SECURITY
286 setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, sc_on_param, current_settings);
287 setMode(dev_id, MgmtCommand::Opcode::SET_SSP, ssp_on_param, current_settings);
291 setMode(dev_id, MgmtCommand::Opcode::SET_BREDR, 1, current_settings);
292 setDiscoverable(dev_id, 0, 0, current_settings);
293 setMode(dev_id, MgmtCommand::Opcode::SET_LE, 0, current_settings);
294 #if USE_LINUX_BT_SECURITY
295 setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, 0, current_settings);
296 setMode(dev_id, MgmtCommand::Opcode::SET_SSP, ssp_on_param, current_settings);
302 setMode(dev_id, MgmtCommand::Opcode::SET_BREDR, 0, current_settings);
303 setMode(dev_id, MgmtCommand::Opcode::SET_LE, 1, current_settings);
304 #if USE_LINUX_BT_SECURITY
305 setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, sc_on_param, current_settings);
306 setMode(dev_id, MgmtCommand::Opcode::SET_SSP, 0, current_settings);
311 #if USE_LINUX_BT_SECURITY
312 setMode(dev_id, MgmtCommand::Opcode::SET_DEBUG_KEYS, debug_keys, current_settings);
313 setMode(dev_id, MgmtCommand::Opcode::SET_IO_CAPABILITY,
direct_bt::number(BTManager::defaultIOCapability), current_settings);
314 setMode(dev_id, MgmtCommand::Opcode::SET_BONDABLE, 1, current_settings);
316 setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, 0, current_settings);
317 setMode(dev_id, MgmtCommand::Opcode::SET_SSP, 0, current_settings);
318 setMode(dev_id, MgmtCommand::Opcode::SET_DEBUG_KEYS, 0, current_settings);
319 setMode(dev_id, MgmtCommand::Opcode::SET_BONDABLE, 0, current_settings);
322 setMode(dev_id, MgmtCommand::Opcode::SET_CONNECTABLE, 0, current_settings);
323 setMode(dev_id, MgmtCommand::Opcode::SET_FAST_CONNECTABLE, 0, current_settings);
325 removeDeviceFromWhitelist(dev_id, BDAddressAndType::ANY_BREDR_DEVICE);
327 setMode(dev_id, MgmtCommand::Opcode::SET_POWERED, 1, current_settings);
332 if( AdapterSetting::NONE != current_settings ) {
333 adapterInfo->setCurrentSettingMask(current_settings);
335 adapterInfo =
nullptr;
336 std::unique_ptr<MgmtEvent> res = sendWithReply(req0);
337 if(
nullptr == res ) {
340 if( MgmtEvent::Opcode::CMD_COMPLETE != res->
getOpcode() || res->
getTotalSize() < MgmtEvtAdapterInfo::getRequiredTotalSize()) {
341 ERR_PRINT(
"Insufficient data for adapter info: req %d, res %s", MgmtEvtAdapterInfo::getRequiredTotalSize(), res->
toString().c_str());
346 if( dev_id != adapterInfo->dev_id ) {
347 ABORT(
"AdapterInfo dev_id=%d != dev_id=%d: %s", adapterInfo->dev_id, dev_id, adapterInfo->toString().c_str());
350 DBG_PRINT(
"initAdapter[%d, BTMode %s]: End: %s", dev_id,
to_string(btMode).c_str(), adapterInfo->toString().c_str());
356 void BTManager::shutdownAdapter(
BTAdapter& adapter) noexcept {
357 DBG_PRINT(
"DBTManager::shutdownAdapter: %s", adapter.toString().c_str());
358 const uint16_t dev_id = adapter.dev_id;
362 setMode(dev_id, MgmtCommand::Opcode::SET_POWERED, 0, current_settings);
364 setMode(dev_id, MgmtCommand::Opcode::SET_BONDABLE, 0, current_settings);
365 setMode(dev_id, MgmtCommand::Opcode::SET_CONNECTABLE, 0, current_settings);
366 setMode(dev_id, MgmtCommand::Opcode::SET_FAST_CONNECTABLE, 0, current_settings);
368 setMode(dev_id, MgmtCommand::Opcode::SET_DEBUG_KEYS, 0, current_settings);
369 setMode(dev_id, MgmtCommand::Opcode::SET_IO_CAPABILITY,
direct_bt::number(SMPIOCapability::DISPLAY_ONLY), current_settings);
370 setMode(dev_id, MgmtCommand::Opcode::SET_SSP, 0, current_settings);
371 setMode(dev_id, MgmtCommand::Opcode::SET_SECURE_CONN, 0, current_settings);
372 DBG_PRINT(
"DBTManager::shutdownAdapter: done: %s", adapter.toString().c_str());
375 BTManager::BTManager(
const BTMode _defaultBTMode) noexcept
377 defaultBTMode(BTMode::NONE != _defaultBTMode ? _defaultBTMode : env.DEFAULT_BTMODE),
378 rbuffer(ClientMaxMTU), comm(HCI_DEV_NONE, HCI_CHANNEL_CONTROL),
379 mgmtEventRing(
nullptr, env.MGMT_EVT_RING_CAPACITY), mgmtReaderShallStop(
false),
380 mgmtReaderThreadId(0), mgmtReaderRunning(
false),
381 allowClose( comm.isOpen() )
383 WORDY_PRINT(
"DBTManager.ctor: BTMode %s, pid %d",
to_string(defaultBTMode).c_str(), BTManager::pidSelf);
385 ERR_PRINT(
"DBTManager::open: Could not open mgmt control channel");
390 struct sigaction sa_setup;
391 bzero(&sa_setup,
sizeof(sa_setup));
393 sigemptyset(&(sa_setup.sa_mask));
394 sa_setup.sa_flags = SA_SIGINFO;
395 if( 0 != sigaction( SIGALRM, &sa_setup, NULL ) ) {
396 ERR_PRINT(
"DBTManager::ctor: Setting sighandler");
400 std::unique_lock<std::mutex> lock(mtx_mgmtReaderLifecycle);
402 std::thread mgmtReaderThread(&BTManager::mgmtReaderThreadImpl,
this);
403 mgmtReaderThreadId = mgmtReaderThread.native_handle();
406 mgmtReaderThread.detach();
408 while(
false == mgmtReaderRunning ) {
409 cv_mgmtReaderInit.wait(lock);
418 std::unique_ptr<MgmtEvent> res = sendWithReply(req0);
419 if(
nullptr == res ) {
426 const uint8_t *data = res->
getData();
427 const uint8_t version = data[0];
429 WORDY_PRINT(
"Bluetooth version %d.%d", version, revision);
431 ERR_PRINT(
"Bluetooth version >= 1.0 required");
438 std::unique_ptr<MgmtEvent> res = sendWithReply(req0);
439 if(
nullptr == res ) {
443 const uint8_t *data = res->
getData();
446 WORDY_PRINT(
"Bluetooth %d commands, %d events", num_commands, num_events);
448 const int expDataSize = 4 + num_commands * 2 + num_events * 2;
450 for(
int i=0; i< num_commands; i++) {
452 DBG_PRINT(
"kernel op %d: %s", i, toString(op).c_str());
463 std::unique_ptr<MgmtEvent> res = sendWithReply(req0);
464 if(
nullptr == res ) {
468 ERR_PRINT(
"Insufficient data for adapter index: res %s", res->
toString().c_str());
471 const uint8_t *data = res->
getData();
477 ERR_PRINT(
"Insufficient data for %d adapter indices: res %s", num_adapter, res->
toString().c_str());
480 for(
int i=0; i < num_adapter; i++) {
482 std::unique_ptr<AdapterInfo> adapterInfo =
initAdapter(dev_id, defaultBTMode);
483 if(
nullptr != adapterInfo ) {
484 std::shared_ptr<BTAdapter> adapter = BTAdapter::make_shared(*
this, *adapterInfo);
485 adapters.push_back( adapter );
486 adapterIOCapability.push_back(BTManager::defaultIOCapability);
487 DBG_PRINT(
"DBTManager::adapters %d/%d: dev_id %d: %s", i, num_adapter, dev_id, adapter->
toString().c_str());
489 DBG_PRINT(
"DBTManager::adapters %d/%d: dev_id %d: FAILED", i, num_adapter, dev_id);
494 addMgmtEventCallback(-1, MgmtEvent::Opcode::NEW_SETTINGS,
jau::bindMemberFunc(
this, &BTManager::mgmtEvNewSettingsCB));
497 addMgmtEventCallback(-1, MgmtEvent::Opcode::CONTROLLER_ERROR,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
498 addMgmtEventCallback(-1, MgmtEvent::Opcode::CLASS_OF_DEV_CHANGED,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
499 addMgmtEventCallback(-1, MgmtEvent::Opcode::NEW_LINK_KEY,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
500 addMgmtEventCallback(-1, MgmtEvent::Opcode::NEW_LONG_TERM_KEY,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
501 addMgmtEventCallback(-1, MgmtEvent::Opcode::DEVICE_CONNECTED,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
502 addMgmtEventCallback(-1, MgmtEvent::Opcode::DEVICE_DISCONNECTED,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
503 addMgmtEventCallback(-1, MgmtEvent::Opcode::CONNECT_FAILED,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
504 addMgmtEventCallback(-1, MgmtEvent::Opcode::PIN_CODE_REQUEST,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
505 addMgmtEventCallback(-1, MgmtEvent::Opcode::USER_CONFIRM_REQUEST,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
506 addMgmtEventCallback(-1, MgmtEvent::Opcode::USER_PASSKEY_REQUEST,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
507 addMgmtEventCallback(-1, MgmtEvent::Opcode::AUTH_FAILED,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
508 addMgmtEventCallback(-1, MgmtEvent::Opcode::DEVICE_FOUND,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
509 addMgmtEventCallback(-1, MgmtEvent::Opcode::DISCOVERING,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
510 addMgmtEventCallback(-1, MgmtEvent::Opcode::DEVICE_BLOCKED,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
511 addMgmtEventCallback(-1, MgmtEvent::Opcode::DEVICE_UNBLOCKED,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
512 addMgmtEventCallback(-1, MgmtEvent::Opcode::DEVICE_UNPAIRED,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
513 addMgmtEventCallback(-1, MgmtEvent::Opcode::PASSKEY_NOTIFY,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
514 addMgmtEventCallback(-1, MgmtEvent::Opcode::NEW_IRK,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
515 addMgmtEventCallback(-1, MgmtEvent::Opcode::NEW_CSRK,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
516 addMgmtEventCallback(-1, MgmtEvent::Opcode::DEVICE_WHITELIST_ADDED,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
517 addMgmtEventCallback(-1, MgmtEvent::Opcode::DEVICE_WHITELIST_REMOVED,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
518 addMgmtEventCallback(-1, MgmtEvent::Opcode::NEW_CONN_PARAM,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
520 addMgmtEventCallback(-1, MgmtEvent::Opcode::LOCAL_OOB_DATA_UPDATED,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
522 addMgmtEventCallback(-1, MgmtEvent::Opcode::PAIR_DEVICE_COMPLETE,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
523 addMgmtEventCallback(-1, MgmtEvent::Opcode::HCI_ENC_CHANGED,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
524 addMgmtEventCallback(-1, MgmtEvent::Opcode::HCI_ENC_KEY_REFRESH_COMPLETE,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
525 addMgmtEventCallback(-1, MgmtEvent::Opcode::HCI_LE_REMOTE_USR_FEATURES,
jau::bindMemberFunc(
this, &BTManager::mgmtEventAnyCB));
538 void BTManager::close() noexcept {
543 DBG_PRINT(
"DBTManager::close: Not open");
547 adapterIOCapability.
clear();
553 const std::lock_guard<std::recursive_mutex> lock(mtx_sendReply);
561 DBG_PRINT(
"DBTManager::close::shutdownAdapter: %d/%d processing: %s", i, adapters.
size(), a->
toString().c_str());
568 adapterIOCapability.
clear();
576 std::unique_lock<std::mutex> lockReader(mtx_mgmtReaderLifecycle);
577 const pthread_t tid_self = pthread_self();
578 const pthread_t tid_reader = mgmtReaderThreadId;
579 mgmtReaderThreadId = 0;
580 const bool is_reader = tid_reader == tid_self;
581 DBG_PRINT(
"DBTManager::close: mgmtReader[running %d, shallStop %d, isReader %d, tid %p)",
582 mgmtReaderRunning.
load(), mgmtReaderShallStop.
load(), is_reader, (
void*)tid_reader);
583 if( mgmtReaderRunning ) {
584 mgmtReaderShallStop =
true;
585 if( !is_reader && 0 != tid_reader ) {
587 if( 0 != ( kerr = pthread_kill(tid_reader, SIGALRM) ) ) {
588 ERR_PRINT(
"DBTManager::close: pthread_kill %p FAILED: %d", (
void*)tid_reader, kerr);
592 while(
true == mgmtReaderRunning ) {
593 cv_mgmtReaderInit.wait(lockReader);
600 struct sigaction sa_setup;
601 bzero(&sa_setup,
sizeof(sa_setup));
602 sa_setup.sa_handler = SIG_DFL;
603 sigemptyset(&(sa_setup.sa_mask));
604 sa_setup.sa_flags = 0;
605 if( 0 != sigaction( SIGALRM, &sa_setup, NULL ) ) {
606 ERR_PRINT(
"DBTManager.sigaction: Resetting sighandler");
616 for (; !it.
is_end(); ++it) {
617 if( (*it)->isPowered() ) {
626 for (; !it.
is_end(); ++it) {
627 if ( (*it)->dev_id == dev_id ) {
634 std::shared_ptr<BTAdapter> BTManager::addAdapter(
const AdapterInfo& ai ) noexcept {
635 typename adapters_t::iterator it = adapters.begin();
636 for (; !it.is_end(); ++it) {
637 if ( (*it)->dev_id == ai.dev_id ) {
643 std::shared_ptr<BTAdapter> adapter = BTAdapter::make_shared(*
this, ai);
644 it.push_back( adapter );
645 adapterIOCapability.push_back(BTManager::defaultIOCapability);
651 std::shared_ptr<BTAdapter> adapter = *it;
652 WARN_PRINT(
"DBTManager::addAdapter: Already existing %s, overwriting %s", ai.toString().c_str(), adapter->
toString().c_str())
653 adapter->adapterInfo = ai;
659 typename adapters_t::iterator it = adapters.begin();
660 for(; !it.is_end(); ++it ) {
661 std::shared_ptr<BTAdapter> & ai = *it;
662 if( ai->
dev_id == dev_id ) {
663 adapterIOCapability.erase( adapterIOCapability.cbegin() + it.dist_begin() );
664 std::shared_ptr<BTAdapter> res = ai;
671 DBG_PRINT("DBTManager::removeAdapter:
Not found: dev_id %d", dev_id)
676 typename adapters_t::iterator it = adapters.begin();
677 for(; !it.is_end(); ++it ) {
678 std::shared_ptr<BTAdapter> & ai = *it;
679 if( ai.get() == adapter ) {
680 adapterIOCapability.erase( adapterIOCapability.cbegin() + it.dist_begin() );
681 DBG_PRINT(
"DBTManager::removeAdapter: Remove: %p -> %s", adapter, ai->
toString().c_str())
687 DBG_PRINT("DBTManager::removeAdapter:
Not found: %p", adapter)
693 #if USE_LINUX_BT_SECURITY
695 for (; !it.
is_end(); ++it) {
696 if( (*it)->dev_id == dev_id ) {
701 adapterIOCapability.at(index) = io_cap;
716 for (; !it.
is_end(); ++it) {
717 if( (*it)->dev_id == dev_id ) {
718 return adapterIOCapability.at( it.
dist_begin() );
726 std::unique_ptr<MgmtEvent> reply = sendWithReply(req);
728 if(
nullptr != reply ) {
744 DBG_PRINT(
"DBTManager::setMode[%d, %s]: %s, result %s %s", dev_id,
752 std::unique_ptr<MgmtEvent> reply = sendWithReply(req);
754 if(
nullptr != reply ) {
770 DBG_PRINT(
"DBTManager::setDiscoverable[%d]: %s, result %s %s", dev_id,
781 std::unique_ptr<MgmtEvent> res = sendWithReply(req);
786 const uint8_t *p = res1.
getData();
788 ERR_PRINT(
"DBTManager::startDiscovery: Impossible MgmtEvtCmdComplete data nullptr: %s - %s", res1.
toString().c_str(), req.
toString().c_str());
791 type =
static_cast<ScanType>( p[0] );
798 std::unique_ptr<MgmtEvent> res = sendWithReply(req);
807 const uint16_t conn_min_interval,
const uint16_t conn_max_interval,
808 const uint16_t conn_latency,
const uint16_t supervision_timeout) noexcept {
809 MgmtConnParam connParam{ addressAndType.
address, addressAndType.type, conn_min_interval, conn_max_interval, conn_latency, supervision_timeout };
811 std::unique_ptr<MgmtEvent> res = sendWithReply(req);
820 #if USE_LINUX_BT_SECURITY
822 std::unique_ptr<MgmtEvent> res = sendWithReply(req);
835 #if USE_LINUX_BT_SECURITY
838 std::unique_ptr<MgmtEvent> reply = sendWithReply(req);
839 if(
nullptr != reply ) {
850 DBG_PRINT(
"DBTManager::uploadLongTermKeyInfo[%d]: %s, result %s", dev_id,
860 #if USE_LINUX_BT_SECURITY
863 ltk.isResponder(), ltk.enc_size, ltk.ediv, ltk.rand, ltk.ltk };
866 std::unique_ptr<MgmtEvent> reply = sendWithReply(req);
867 if(
nullptr != reply ) {
878 DBG_PRINT(
"DBTManager::uploadLongTermKeyInfo[%d]: %s -> %s, result %s", dev_id,
887 #if USE_LINUX_BT_SECURITY
889 std::unique_ptr<MgmtEvent> res = sendWithReply(cmd);
902 #if USE_LINUX_BT_SECURITY
904 std::unique_ptr<MgmtEvent> res = sendWithReply(cmd);
917 #if USE_LINUX_BT_SECURITY
918 std::unique_ptr<MgmtEvent> res;
921 res = sendWithReply(cmd);
924 res = sendWithReply(cmd);
938 #if USE_LINUX_BT_SECURITY
947 #if USE_LINUX_BT_SECURITY
949 std::unique_ptr<MgmtEvent> res = sendWithReply(cmd);
963 auto it = whitelist.cbegin();
964 for(
auto end = whitelist.cend(); it != end; ++it) {
965 std::shared_ptr<WhitelistElem> wle = *it;
966 if( wle->dev_id == dev_id && wle->address_and_type == addressAndType ) {
977 if( isDeviceWhitelisted(dev_id, addressAndType) ) {
978 ERR_PRINT(
"DBTManager::addDeviceToWhitelist: Already in local whitelist, remove first: %s", req.
toString().c_str());
981 std::unique_ptr<MgmtEvent> res = sendWithReply(req);
985 whitelist.push_back( std::make_shared<WhitelistElem>(dev_id, addressAndType, ctype) );
996 DBG_PRINT(
"DBTManager::removeAllDevicesFromWhitelist.A: Start %zd elements", whitelist_copy.
size());
998 for(
auto it = whitelist_copy.
cbegin(); it != whitelist_copy.
cend(); ++it) {
999 std::shared_ptr<WhitelistElem> wle = *it;
1005 DBG_PRINT(
"DBTManager::removeAllDevicesFromWhitelist.B: Start %d elements", count);
1014 DBG_PRINT(
"DBTManager::removeAllDevicesFromWhitelist: End: Removed %d elements, remaining %zd elements",
1015 count, whitelist.
size());
1022 auto it = whitelist.cbegin();
1023 for(
auto end = whitelist.cend(); it != end; ) {
1024 std::shared_ptr<WhitelistElem> wle = *it;
1025 if( wle->dev_id == dev_id && wle->address_and_type == addressAndType ) {
1026 it = whitelist.erase(it);
1035 std::unique_ptr<MgmtEvent> res = sendWithReply(req);
1055 std::unique_ptr<MgmtEvent> res = sendWithReply(req);
1063 if( !ioErrorCause ) {
1074 std::unique_ptr<MgmtEvent> res = sendWithReply(req);
1085 std::shared_ptr<NameAndShortName>
BTManager::setLocalName(
const uint16_t dev_id,
const std::string & name,
const std::string & short_name) noexcept {
1087 std::unique_ptr<MgmtEvent> res = sendWithReply(req);
1118 if( !isValidMgmtEventCallbackListsIndex(opc) ) {
1127 if( !isValidMgmtEventCallbackListsIndex(opc) ) {
1141 for(
size_t i=0; i<mgmtAdapterEventCallbackLists.size(); i++) {
1149 if( !isValidMgmtEventCallbackListsIndex(opc) ) {
1153 mgmtAdapterEventCallbackLists[
static_cast<uint16_t
>(opc)].
clear();
1156 for(
size_t i=0; i<mgmtAdapterEventCallbackLists.size(); i++) {
1157 mgmtAdapterEventCallbackLists[i].clear();
1159 mgmtChangedAdapterSetCallbackList.
clear();
1162 void BTManager::processAdapterAdded(std::unique_ptr<MgmtEvent> e) noexcept {
1163 const uint16_t dev_id = e->getDevID();
1165 std::unique_ptr<AdapterInfo> adapterInfo =
initAdapter(dev_id, defaultBTMode);
1167 if(
nullptr != adapterInfo ) {
1168 std::shared_ptr<BTAdapter> adapter = addAdapter( *adapterInfo );
1169 DBG_PRINT(
"DBTManager::Adapter[%d] Added: Start %s, added %d", dev_id, adapter->
toString().c_str());
1171 DBG_PRINT(
"DBTManager::Adapter[%d] Added: User_ %s", dev_id, adapter->
toString().c_str());
1173 cb.
invoke(
true , adapter);
1175 DBG_PRINT(
"DBTManager::Adapter[%d] Added: End__ %s", dev_id, adapter->
toString().c_str());
1177 DBG_PRINT(
"DBTManager::Adapter[%d] Added: InitAI failed", dev_id);
1180 void BTManager::processAdapterRemoved(std::unique_ptr<MgmtEvent> e) noexcept {
1181 const uint16_t dev_id = e->getDevID();
1182 std::shared_ptr<BTAdapter> ai = removeAdapter(dev_id);
1183 if(
nullptr != ai ) {
1184 DBG_PRINT(
"DBTManager::Adapter[%d] Removed: Start: %s", dev_id, ai->
toString().c_str());
1186 DBG_PRINT(
"DBTManager::Adapter[%d] Removed: User_: %s", dev_id, ai->
toString().c_str());
1191 DBG_PRINT(
"DBTManager::Adapter[%d] Removed: End__: %s", dev_id, ai->
toString().c_str());
1193 DBG_PRINT(
"DBTManager::Adapter[%d] Removed: RemoveAI failed", dev_id);
1196 bool BTManager::mgmtEvNewSettingsCB(
const MgmtEvent& e) noexcept {
1198 std::shared_ptr<BTAdapter> adapter = getAdapter(event.getDevID());
1199 if(
nullptr != adapter ) {
1201 const AdapterSetting new_settings = adapter->adapterInfo.setCurrentSettingMask(event.getSettings());
1202 DBG_PRINT(
"DBTManager:mgmt:NewSettings: Adapter[%d] %s -> %s - %s",
1206 e.toString().c_str());
1208 DBG_PRINT(
"DBTManager:mgmt:NewSettings: Adapter[%d] %s -> adapter not present - %s",
1211 e.toString().c_str());
1216 bool BTManager::mgmtEventAnyCB(
const MgmtEvent& e) noexcept {
1217 DBG_PRINT(
"DBTManager:mgmt:Any: %s", e.toString().c_str());
1232 mgmtChangedAdapterSetCallbackList.
push_back(l);