summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2020-08-23 09:34:40 +0200
committerSven Gothel <[email protected]>2020-08-23 09:34:40 +0200
commita49ce8a8a72eb34cc6a4c8d23e4907684350d078 (patch)
treea5f3206d489afcd665ea419e91e824706199b383 /src
parent2bcbaa8bd744f2d255259ee999ccfd257f4af2b5 (diff)
HCIHandler: Produce MgmtEvtDeviceFound events from LE_ADVERTISING_REPORT; EInfoReport: Fix address-type AD -> BDAddressType
Parse LE_ADVERTISING_REPORT and produce MgmtEvtDeviceFound, call its listener. This removes dependency of Linux Mgmt's MgmtEvtDeviceFound events. MgmtEvtDeviceFound optionally holds the parsed std::shared_ptr<EInfoReport> instance, removing the need to process the raw EIR again in DBTAdapter later on. Misc: - Fix EInfoReport AD address-type -> BDAddressType conversion (missing) - Expose LEADVEventType enum w/ string presentation.
Diffstat (limited to 'src')
-rw-r--r--src/direct_bt/BTTypes.cpp55
-rw-r--r--src/direct_bt/HCIHandler.cpp69
2 files changed, 73 insertions, 51 deletions
diff --git a/src/direct_bt/BTTypes.cpp b/src/direct_bt/BTTypes.cpp
index b08b2eb9..2ab8bcd9 100644
--- a/src/direct_bt/BTTypes.cpp
+++ b/src/direct_bt/BTTypes.cpp
@@ -232,6 +232,23 @@ std::string direct_bt::getScanTypeString(const ScanType v) {
return "Unknown ScanType";
}
+#define LEADVEventType_ENUM(X) \
+ X(ADV_IND) \
+ X(ADV_DIRECT_IND) \
+ X(ADV_SCAN_IND) \
+ X(ADV_NONCONN_IND) \
+ X(SCAN_RSP) \
+
+#define LEADVEventType_CASE_TO_STRING(V) case LEADVEventType::V: return #V;
+
+std::string direct_bt::getLEADVEventTypeString(const LEADVEventType v) {
+ switch(v) {
+ LEADVEventType_ENUM(LEADVEventType_CASE_TO_STRING)
+ default: ; // fall through intended
+ }
+ return "Unknown LEADVEventType";
+}
+
#define APPEARANCECAT_ENUM(X) \
X(UNKNOWN) \
X(GENERIC_PHONE) \
@@ -376,10 +393,34 @@ std::string EInfoReport::getSourceString() const {
case Source::NA: return "N/A";
case Source::AD: return "AD";
case Source::EIR: return "EIR";
+ case Source::EIR_MGMT: return "EIR_MGMT";
}
return "N/A";
}
+void EInfoReport::setADAddressType(uint8_t adAddressType) {
+ ad_address_type = adAddressType;
+ switch( ad_address_type ) {
+ case 0x00: addressType = BDAddressType::BDADDR_LE_PUBLIC; break;
+ case 0x01: addressType = BDAddressType::BDADDR_LE_RANDOM; break;
+ case 0x02: addressType = BDAddressType::BDADDR_LE_RANDOM; break;
+ case 0x03: addressType = BDAddressType::BDADDR_LE_RANDOM; break;
+ default: addressType = BDAddressType::BDADDR_UNDEFINED; break;
+ }
+ set(EIRDataType::BDADDR_TYPE);
+}
+
+void EInfoReport::setAddressType(BDAddressType at) {
+ addressType = at;
+ switch( addressType ) {
+ case BDAddressType::BDADDR_BREDR: ad_address_type = 0; break;
+ case BDAddressType::BDADDR_LE_PUBLIC: ad_address_type = 0; break;
+ case BDAddressType::BDADDR_LE_RANDOM: ad_address_type = 1; break;
+ case BDAddressType::BDADDR_UNDEFINED: ad_address_type = 4; break;
+ }
+ set(EIRDataType::BDADDR_TYPE);
+}
+
void EInfoReport::setName(const uint8_t *buffer, int buffer_len) {
name = get_string(buffer, buffer_len, 30);
set(EIRDataType::NAME);
@@ -404,12 +445,12 @@ void EInfoReport::addService(std::shared_ptr<uuid_t> const &uuid)
std::string EInfoReport::eirDataMaskToString() const {
return std::string("DataSet"+ direct_bt::getEIRDataMaskString(eir_data_mask) );
}
-std::string EInfoReport::toString() const {
+std::string EInfoReport::toString(const bool includeServices) const {
std::string msdstr = nullptr != msd ? msd->toString() : "MSD[null]";
std::string out("EInfoReport::"+getSourceString()+
- "[address["+getAddressString()+", "+getBDAddressTypeString(getAddressType())+"], name['"+name+"'/'"+name_short+
- "'], "+eirDataMaskToString()+
- ", evt-type "+std::to_string(evt_type)+", rssi "+std::to_string(rssi)+
+ "[address["+getAddressString()+", "+getBDAddressTypeString(getAddressType())+"/"+std::to_string(ad_address_type)+
+ "], name['"+name+"'/'"+name_short+"'], "+eirDataMaskToString()+
+ ", evt-type "+getLEADVEventTypeString(evt_type)+", rssi "+std::to_string(rssi)+
", tx-power "+std::to_string(tx_power)+
", dev-class "+uint32HexString(device_class, true)+
", appearance "+uint16HexString(static_cast<uint16_t>(appearance))+" ("+getAppearanceCatString(appearance)+
@@ -421,7 +462,7 @@ std::string EInfoReport::toString() const {
", version "+uint16HexString(did_version, true)+
"], "+msdstr+"]");
- if(services.size() > 0 ) {
+ if( includeServices && services.size() > 0 ) {
out.append("\n");
for(auto it = services.begin(); it != services.end(); it++) {
std::shared_ptr<uuid_t> p = *it;
@@ -612,11 +653,11 @@ std::vector<std::shared_ptr<EInfoReport>> EInfoReport::read_ad_reports(uint8_t c
ad_reports.push_back(std::shared_ptr<EInfoReport>(new EInfoReport()));
ad_reports[i]->setSource(Source::AD);
ad_reports[i]->setTimestamp(timestamp);
- ad_reports[i]->setEvtType(*i_octets++);
+ ad_reports[i]->setEvtType(static_cast<LEADVEventType>(*i_octets++));
read_segments++;
}
for(i = 0; i < num_reports && i_octets < limes; i++) {
- ad_reports[i]->setAddressType(static_cast<BDAddressType>(*i_octets++));
+ ad_reports[i]->setADAddressType(*i_octets++);
read_segments++;
}
for(i = 0; i < num_reports && i_octets + 5 < limes; i++) {
diff --git a/src/direct_bt/HCIHandler.cpp b/src/direct_bt/HCIHandler.cpp
index 77fd6e39..6ade9e67 100644
--- a/src/direct_bt/HCIHandler.cpp
+++ b/src/direct_bt/HCIHandler.cpp
@@ -32,8 +32,6 @@
#include <algorithm>
-// #define SHOW_LE_ADVERTISING 1
-
// #define PERF_PRINT_ON 1
// #define VERBOSE_ON 1
#include <dbt_debug.hpp>
@@ -267,17 +265,7 @@ void HCIHandler::hciReaderThreadImpl() {
DBG_PRINT("HCIHandler::reader: Drop (meta filter) %s", event->toString().c_str());
continue; // next packet
}
-#ifdef SHOW_LE_ADVERTISING
- if( event->isMetaEvent(HCIMetaEventType::LE_ADVERTISING_REPORT) ) {
- std::vector<std::shared_ptr<EInfoReport>> eirlist = EInfoReport::read_ad_reports(event->getParam(), event->getParamSize());
- int i=0;
- for_each_idx(eirlist, [&](std::shared_ptr<EInfoReport> &eir) {
- INFO_PRINT("LE_ADV[%d]: %s", i, eir->toString().c_str());
- i++;
- });
- continue; // next packet
- }
-#endif /* SHOW_LE_ADVERTISING */
+
if( event->isEvent(HCIEventType::CMD_STATUS) || event->isEvent(HCIEventType::CMD_COMPLETE) )
{
if( hciEventRing.isFull() ) {
@@ -287,28 +275,22 @@ void HCIHandler::hciReaderThreadImpl() {
}
DBG_PRINT("HCIHandler::reader: CmdResult %s", event->toString().c_str());
hciEventRing.putBlocking( event );
+ } else if( event->isMetaEvent(HCIMetaEventType::LE_ADVERTISING_REPORT) ) {
+ // issue callbacks for the translated AD events
+ std::vector<std::shared_ptr<EInfoReport>> eirlist = EInfoReport::read_ad_reports(event->getParam(), event->getParamSize());
+ int i=0;
+ for_each_idx(eirlist, [&](std::shared_ptr<EInfoReport> &eir) {
+ std::shared_ptr<MgmtEvent> mevent( new MgmtEvtDeviceFound(dev_id, eir) );
+ DBG_PRINT("LE_ADV[%d]: %s", i, eir->toString().c_str());
+ sendMgmtEvent( mevent );
+ i++;
+ });
} else {
- // issue a callback
+ // issue a callback for the translated event
std::shared_ptr<MgmtEvent> mevent = translate(event);
if( nullptr != mevent ) {
- const std::lock_guard<std::recursive_mutex> lock(mtx_callbackLists); // RAII-style acquire and relinquish via destructor
- MgmtEventCallbackList & mgmtEventCallbackList = mgmtEventCallbackLists[static_cast<uint16_t>(mevent->getOpcode())];
- int invokeCount = 0;
- if( mgmtEventCallbackList.size() > 0 ) {
- for (auto it = mgmtEventCallbackList.begin(); it != mgmtEventCallbackList.end(); ++it) {
- try {
- it->invoke(mevent);
- } catch (std::exception &e) {
- ERR_PRINT("HCIHandler::fwdPacketReceived-CBs %d/%zd: MgmtEventCallback %s : Caught exception %s",
- invokeCount+1, mgmtEventCallbackList.size(),
- it->toString().c_str(), e.what());
- }
- invokeCount++;
- }
- }
- DBG_PRINT("HCIHandler::reader: Event %s -> %d/%zd callbacks; source %s",
- mevent->toString().c_str(), invokeCount, mgmtEventCallbackList.size(), event->toString().c_str());
- (void)invokeCount;
+ DBG_PRINT("HCIHandler::reader: Event source %s", event->toString().c_str());
+ sendMgmtEvent( mevent );
} else {
DBG_PRINT("HCIHandler::reader: Drop (no translation) %s", event->toString().c_str());
}
@@ -324,18 +306,19 @@ void HCIHandler::hciReaderThreadImpl() {
void HCIHandler::sendMgmtEvent(std::shared_ptr<MgmtEvent> event) {
const std::lock_guard<std::recursive_mutex> lock(mtx_callbackLists); // RAII-style acquire and relinquish via destructor
- const MgmtEvent::Opcode opc = event->getOpcode();
- MgmtEventCallbackList & mgmtEventCallbackList = mgmtEventCallbackLists[static_cast<uint16_t>(opc)];
+ MgmtEventCallbackList & mgmtEventCallbackList = mgmtEventCallbackLists[static_cast<uint16_t>(event->getOpcode())];
int invokeCount = 0;
- for (auto it = mgmtEventCallbackList.begin(); it != mgmtEventCallbackList.end(); ++it) {
- try {
- it->invoke(event);
- } catch (std::exception &e) {
- ERR_PRINT("HCIHandler::sendMgmtEvent-CBs %d/%zd: MgmtEventCallback %s : Caught exception %s",
- invokeCount+1, mgmtEventCallbackList.size(),
- it->toString().c_str(), e.what());
+ if( mgmtEventCallbackList.size() > 0 ) {
+ for (auto it = mgmtEventCallbackList.begin(); it != mgmtEventCallbackList.end(); ++it) {
+ try {
+ it->invoke(event);
+ } catch (std::exception &e) {
+ ERR_PRINT("HCIHandler::sendMgmtEvent-CBs %d/%zd: MgmtEventCallback %s : Caught exception %s",
+ invokeCount+1, mgmtEventCallbackList.size(),
+ it->toString().c_str(), e.what());
+ }
+ invokeCount++;
}
- invokeCount++;
}
DBG_PRINT("HCIHandler::sendMgmtEvent: Event %s -> %d/%zd callbacks",
event->toString().c_str(), invokeCount, mgmtEventCallbackList.size());
@@ -483,9 +466,7 @@ HCIHandler::HCIHandler(const BTMode btMode, const uint16_t dev_id, const int rep
uint32_t mask = 0;
// filter_all_metaevs(mask);
filter_set_metaev(HCIMetaEventType::LE_CONN_COMPLETE, mask);
-#ifdef SHOW_LE_ADVERTISING
filter_set_metaev(HCIMetaEventType::LE_ADVERTISING_REPORT, mask);
-#endif
filter_put_metaevs(mask);
}
#ifdef VERBOSE_ON