diff options
-rw-r--r-- | api/direct_bt/BTDevice.hpp | 24 | ||||
-rw-r--r-- | api/direct_bt/BTTypes0.hpp | 34 | ||||
-rw-r--r-- | examples/dbt_repeater00.cpp | 12 | ||||
-rw-r--r-- | examples/dbt_scanner10.cpp | 4 | ||||
-rw-r--r-- | examples/java/DBTScanner10.java | 4 | ||||
-rw-r--r-- | java/jau/direct_bt/DBTDevice.java | 20 | ||||
-rw-r--r-- | java/jni/direct_bt/DBTDevice.cxx | 30 | ||||
-rw-r--r-- | java/jni/direct_bt/EInfoReport.cxx | 10 | ||||
-rw-r--r-- | java/org/direct_bt/BTDevice.java | 18 | ||||
-rw-r--r-- | java/org/direct_bt/EIRDataTypeSet.java | 4 | ||||
-rw-r--r-- | java/org/direct_bt/EInfoReport.java | 37 | ||||
-rw-r--r-- | src/direct_bt/BTAdapter.cpp | 4 | ||||
-rw-r--r-- | src/direct_bt/BTDevice.cpp | 20 | ||||
-rw-r--r-- | src/direct_bt/BTTypes0.cpp | 78 |
14 files changed, 256 insertions, 43 deletions
diff --git a/api/direct_bt/BTDevice.hpp b/api/direct_bt/BTDevice.hpp index 2835a2a3..5a379cb9 100644 --- a/api/direct_bt/BTDevice.hpp +++ b/api/direct_bt/BTDevice.hpp @@ -84,7 +84,9 @@ namespace direct_bt { std::string name; int8_t rssi = 127; // The core spec defines 127 as the "not available" value int8_t tx_power = 127; // The core spec defines 127 as the "not available" value - std::shared_ptr<EInfoReport> eir; // shared_ptr to allow CoW style update + std::shared_ptr<EInfoReport> eir; // Merged EIR (using shared_ptr to allow CoW style update) + std::shared_ptr<EInfoReport> eir_ind; // AD_IND EIR + std::shared_ptr<EInfoReport> eir_scan_rsp; // AD_SCAN_RSP EIR jau::relaxed_atomic_uint16 hciConnHandle; jau::ordered_atomic<LE_Features, std::memory_order_relaxed> le_features; jau::ordered_atomic<LE_PHYs, std::memory_order_relaxed> le_phy_tx; @@ -333,18 +335,26 @@ namespace direct_bt { /** * Return the merged advertised EInfoReport for this remote device. * - * The EInfoReport is replaced by new scan-reports (update) and when disconnected (empty). + * The EInfoReport is updated by new scan-reports (update) and when disconnected (empty). * @since 2.5.3 */ - std::shared_ptr<const EInfoReport> getEIR() const noexcept; + std::shared_ptr<EInfoReport> getEIR() noexcept; /** - * Return the merged advertised EInfoReport for this remote device. + * Return the latest advertised EInfoReport AD_IND variant for this remote device. * - * The EInfoReport is replaced by new scan-reports (update) and when disconnected (empty). - * @since 2.5.3 + * The EInfoReport is replaced by new scan-reports only. + * @since 2.6.6 */ - std::shared_ptr<EInfoReport> getEIR() noexcept; + std::shared_ptr<EInfoReport> getEIRInd() noexcept; + + /** + * Return the latest advertised EInfoReport AD_SCAN_RSP for this remote device. + * + * The EInfoReport is replaced by new scan-reports only. + * @since 2.6.6 + */ + std::shared_ptr<EInfoReport> getEIRScanRsp() noexcept; std::string toString() const noexcept override { return toString(false); } diff --git a/api/direct_bt/BTTypes0.hpp b/api/direct_bt/BTTypes0.hpp index e28d6c5a..3319645f 100644 --- a/api/direct_bt/BTTypes0.hpp +++ b/api/direct_bt/BTTypes0.hpp @@ -851,12 +851,16 @@ namespace direct_bt { ALL = 0xffffffff }; constexpr uint32_t number(const EIRDataType rhs) noexcept { return static_cast<uint32_t>(rhs); } + constexpr EIRDataType operator |(const EIRDataType lhs, const EIRDataType rhs) noexcept { return static_cast<EIRDataType> ( number(lhs) | number(rhs) ); } constexpr EIRDataType operator &(const EIRDataType lhs, const EIRDataType rhs) noexcept { return static_cast<EIRDataType> ( number(lhs) & number(rhs) ); } + constexpr EIRDataType operator ~(const EIRDataType rhs) noexcept { + return static_cast<EIRDataType> ( ~number(rhs) ); + } constexpr bool operator ==(const EIRDataType lhs, const EIRDataType rhs) noexcept { return number(lhs) == number(rhs); } @@ -867,6 +871,10 @@ namespace direct_bt { constexpr void setEIRDataTypeSet(EIRDataType &mask, const EIRDataType bit) noexcept { mask = mask | bit; } std::string to_string(const EIRDataType mask) noexcept; + /** Explicit mask to erase all implicit set EIRDataType fields: EVT_TYPE, EXT_EVT_TYPE, BDADDR_TYPE, BDADDR and RSSI. */ + inline constexpr const EIRDataType EIR_DATA_TYPE_MASK = ~( EIRDataType::EVT_TYPE | EIRDataType::EXT_EVT_TYPE | + EIRDataType::BDADDR_TYPE | EIRDataType::BDADDR | EIRDataType::RSSI ); + /** * Collection of 'Extended Advertising Data' (EAD), 'Advertising Data' (AD) * or 'Extended Inquiry Response' (EIR) information. @@ -884,20 +892,26 @@ namespace direct_bt { class EInfoReport { public: enum class Source : int { - /** not available */ - NA, - /* Advertising Data (AD) */ - AD, - /* Extended Advertising Data (EAD) */ - EAD, + /** Not Available */ + NA = 0, + /** (Extended) Advertising Data (AD or EAD) Indication Variant, i.e. initial passive scan data. */ + AD_IND = 1, + /** (Extended) Advertising Data (AD or EAD) Scan Response, i.e. optional active scanning data after AD_IND. */ + AD_SCAN_RSP = 2, /** Extended Inquiry Response (EIR) */ - EIR, + EIR = 3, /** Extended Inquiry Response (EIR) from Kernel Mgmt */ - EIR_MGMT + EIR_MGMT = 4 }; + static constexpr int number(const Source rhs) noexcept { return static_cast<int>(rhs); } + static Source toSource(const AD_PDU_Type type); + static Source toSource(const EAD_Event_Type type); private: + /** Source */ Source source = Source::NA; + /** Flag whether source originated from an extended BT5 data set, i.e. EAD */ + bool source_ext = false; uint64_t timestamp = 0; EIRDataType eir_data_mask = static_cast<EIRDataType>(0); @@ -956,7 +970,7 @@ namespace direct_bt { */ EIRDataType set(const EInfoReport& eir) noexcept; - void setSource(Source s) noexcept { source = s; } + void setSource(Source s, bool ext) noexcept { source = s; source_ext = ext; } void setTimestamp(uint64_t ts) noexcept { timestamp = ts; } void setEvtType(AD_PDU_Type et) noexcept { evt_type = et; set(EIRDataType::EVT_TYPE); } void setExtEvtType(EAD_Event_Type eadt) noexcept { ead_type = eadt; set(EIRDataType::EXT_EVT_TYPE); } @@ -1081,6 +1095,8 @@ namespace direct_bt { jau::nsize_t write_data(EIRDataType write_mask, uint8_t * data, jau::nsize_t const data_length) const noexcept; Source getSource() const noexcept { return source; } + bool getSourceExt() const noexcept { return source_ext; } + uint64_t getTimestamp() const noexcept { return timestamp; } bool isSet(EIRDataType bit) const noexcept { return EIRDataType::NONE != (eir_data_mask & bit); } EIRDataType getEIRDataMask() const noexcept { return eir_data_mask; } diff --git a/examples/dbt_repeater00.cpp b/examples/dbt_repeater00.cpp index e8c04471..62293d40 100644 --- a/examples/dbt_repeater00.cpp +++ b/examples/dbt_repeater00.cpp @@ -433,7 +433,9 @@ static void connectToDiscoveredServer(BTDeviceRef device) { } } std::shared_ptr<const EInfoReport> eir = device->getEIR(); - fprintf_td(stderr, "To Server: Using EIR %s\n", eir->toString().c_str()); + fprintf_td(stderr, "To Server: EIR-1 %s\n", device->getEIRInd()->toString().c_str()); + fprintf_td(stderr, "To Server: EIR-2 %s\n", device->getEIRScanRsp()->toString().c_str()); + fprintf_td(stderr, "To Server: EIR-+ %s\n", eir->toString().c_str()); uint16_t conn_interval_min = (uint16_t)12; uint16_t conn_interval_max = (uint16_t)12; @@ -741,8 +743,8 @@ static bool startAdvertisingToClient(BTAdapterRef a, std::string msg) { } EInfoReport eir = *devToServer->getEIR(); - EIRDataType adv_mask = EIRDataType::FLAGS | EIRDataType::SERVICE_UUID; - EIRDataType scanrsp_mask = EIRDataType::NAME | EIRDataType::CONN_IVAL; + const EIRDataType ind_mask = EIR_DATA_TYPE_MASK & devToServer->getEIRInd()->getEIRDataMask(); + const EIRDataType scanrsp_mask = EIR_DATA_TYPE_MASK & devToServer->getEIRScanRsp()->getEIRDataMask(); DBGattServerRef dbGattServer( new DBGattServer( devToServer ) ); fprintf_td(stderr, "To Client: Start advertising: GattServer %s\n", dbGattServer->toString().c_str()); @@ -755,9 +757,9 @@ static bool startAdvertisingToClient(BTAdapterRef a, std::string msg) { } fprintf_td(stderr, "****** To Client: Start advertising (%s): EIR %s\n", msg.c_str(), eir.toString().c_str()); - fprintf_td(stderr, "****** To Client: Start advertising (%s): adv %s, scanrsp %s\n", msg.c_str(), to_string(adv_mask).c_str(), to_string(scanrsp_mask).c_str()); + 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()); - HCIStatusCode status = a->startAdvertising(dbGattServer, eir, adv_mask, scanrsp_mask, + HCIStatusCode status = a->startAdvertising(dbGattServer, eir, ind_mask, scanrsp_mask, adv_interval_min, adv_interval_max, adv_type, adv_chan_map, filter_policy); fprintf_td(stderr, "****** To Client: Start advertising (%s) result: %s: %s\n", msg.c_str(), to_string(status).c_str(), a->toString().c_str()); diff --git a/examples/dbt_scanner10.cpp b/examples/dbt_scanner10.cpp index a4d61020..0c5857e7 100644 --- a/examples/dbt_scanner10.cpp +++ b/examples/dbt_scanner10.cpp @@ -398,7 +398,9 @@ static void connectDiscoveredDevice(BTDeviceRef device) { } } std::shared_ptr<const EInfoReport> eir = device->getEIR(); - fprintf_td(stderr, "Using EIR %s\n", eir->toString().c_str()); + fprintf_td(stderr, "EIR-1 %s\n", device->getEIRInd()->toString().c_str()); + fprintf_td(stderr, "EIR-2 %s\n", device->getEIRScanRsp()->toString().c_str()); + fprintf_td(stderr, "EIR-+ %s\n", eir->toString().c_str()); uint16_t conn_interval_min = (uint16_t)8; // 10ms uint16_t conn_interval_max = (uint16_t)12; // 15ms diff --git a/examples/java/DBTScanner10.java b/examples/java/DBTScanner10.java index 3d81900e..e4aa18a0 100644 --- a/examples/java/DBTScanner10.java +++ b/examples/java/DBTScanner10.java @@ -367,7 +367,9 @@ public class DBTScanner10 { } } final EInfoReport eir = device.getEIR(); - BTUtils.println(System.err, "Using EIR "+eir.toString()); + BTUtils.println(System.err, "EIR-1 "+device.getEIRInd().toString()); + BTUtils.println(System.err, "EIR-2 "+device.getEIRScanRsp().toString()); + BTUtils.println(System.err, "EIR-+ "+eir.toString()); short conn_interval_min = (short)8; // 10ms short conn_interval_max = (short)12; // 15ms diff --git a/java/jau/direct_bt/DBTDevice.java b/java/jau/direct_bt/DBTDevice.java index 56c8c432..b3945db8 100644 --- a/java/jau/direct_bt/DBTDevice.java +++ b/java/jau/direct_bt/DBTDevice.java @@ -71,6 +71,8 @@ public class DBTDevice extends DBTObject implements BTDevice private volatile String name_cached; /* pp */ final List<WeakReference<DBTGattService>> serviceCache = new ArrayList<WeakReference<DBTGattService>>(); private final EInfoReport eir_ = new EInfoReport(); + private final EInfoReport eir_ind_ = new EInfoReport(); + private final EInfoReport eir_scan_rsp_ = new EInfoReport(); private final AtomicBoolean isClosing = new AtomicBoolean(false); @@ -636,6 +638,24 @@ public class DBTDevice extends DBTObject implements BTDevice private native void getEIRImpl(final EInfoReport eir); @Override + public EInfoReport getEIRInd() { + synchronized( eir_ind_ ) { + getEIRIndImpl(eir_ind_); + return eir_ind_; + } + } + private native void getEIRIndImpl(final EInfoReport eir); + + @Override + public EInfoReport getEIRScanRsp() { + synchronized( eir_scan_rsp_ ) { + getEIRScanRspImpl(eir_scan_rsp_); + return eir_scan_rsp_; + } + } + private native void getEIRScanRspImpl(final EInfoReport eir); + + @Override public native short getTxPower (); /** diff --git a/java/jni/direct_bt/DBTDevice.cxx b/java/jni/direct_bt/DBTDevice.cxx index 84783f15..86f22c09 100644 --- a/java/jni/direct_bt/DBTDevice.cxx +++ b/java/jni/direct_bt/DBTDevice.cxx @@ -965,6 +965,36 @@ void Java_jau_direct_1bt_DBTDevice_getEIRImpl(JNIEnv *env, jobject obj, jobject } } +void Java_jau_direct_1bt_DBTDevice_getEIRIndImpl(JNIEnv *env, jobject obj, jobject jeir_sink) { + try { + BTDevice *device = getJavaUplinkObject<BTDevice>(env, obj); + std::shared_ptr<EInfoReport>* eir_sink_ptr_ref = jau::getInstance<std::shared_ptr<EInfoReport>>(env, jeir_sink); + + std::shared_ptr<EInfoReport> eir = device->getEIRInd(); + + // replace the shared managed object + *eir_sink_ptr_ref = eir; + + } catch(...) { + rethrow_and_raise_java_exception(env); + } +} + +void Java_jau_direct_1bt_DBTDevice_getEIRScanRspImpl(JNIEnv *env, jobject obj, jobject jeir_sink) { + try { + BTDevice *device = getJavaUplinkObject<BTDevice>(env, obj); + std::shared_ptr<EInfoReport>* eir_sink_ptr_ref = jau::getInstance<std::shared_ptr<EInfoReport>>(env, jeir_sink); + + std::shared_ptr<EInfoReport> eir = device->getEIRScanRsp(); + + // replace the shared managed object + *eir_sink_ptr_ref = eir; + + } catch(...) { + rethrow_and_raise_java_exception(env); + } +} + jshort Java_jau_direct_1bt_DBTDevice_getTxPower(JNIEnv *env, jobject obj) { try { diff --git a/java/jni/direct_bt/EInfoReport.cxx b/java/jni/direct_bt/EInfoReport.cxx index d2ef7c7d..eecf2d84 100644 --- a/java/jni/direct_bt/EInfoReport.cxx +++ b/java/jni/direct_bt/EInfoReport.cxx @@ -366,6 +366,16 @@ jint Java_org_direct_1bt_EInfoReport_getEIRDataMaskImpl(JNIEnv *env, jobject obj return 0; } +jint Java_org_direct_1bt_EInfoReport_getSourceImpl(JNIEnv *env, jobject obj) { + try { + std::shared_ptr<EInfoReport>& eir_ptr = *jau::getInstance<std::shared_ptr<EInfoReport>>(env, obj); + return static_cast<jint>( EInfoReport::number( eir_ptr->getSource() ) ); + } catch(...) { + rethrow_and_raise_java_exception(env); + } + return static_cast<jint>( EInfoReport::number( EInfoReport::Source::NA ) ); +} + /* * Class: org_direct_bt_EInfoReport * Method: getFlagsImpl diff --git a/java/org/direct_bt/BTDevice.java b/java/org/direct_bt/BTDevice.java index 97253069..4894b04a 100644 --- a/java/org/direct_bt/BTDevice.java +++ b/java/org/direct_bt/BTDevice.java @@ -800,11 +800,27 @@ public interface BTDevice extends BTObject /** * Return the merged advertised {@link EInfoReport} for this remote device. * - * The EInfoReport is replaced by new scan-reports (update) and when disconnected (empty). + * The EInfoReport is updated by new scan-reports (update) and when disconnected (empty). * @since 2.5.3 */ EInfoReport getEIR(); + /** + * Return the latest advertised EInfoReport AD_IND variant for this remote device. + * + * The EInfoReport is replaced by new scan-reports only. + * @since 2.6.6 + */ + EInfoReport getEIRInd(); + + /** + * Return the latest advertised EInfoReport AD_SCAN_RSP for this remote device. + * + * The EInfoReport is replaced by new scan-reports only. + * @since 2.6.6 + */ + EInfoReport getEIRScanRsp(); + /** Returns the connected state of the device. * @return The connected state of the device. */ diff --git a/java/org/direct_bt/EIRDataTypeSet.java b/java/org/direct_bt/EIRDataTypeSet.java index a5525662..0d375c6f 100644 --- a/java/org/direct_bt/EIRDataTypeSet.java +++ b/java/org/direct_bt/EIRDataTypeSet.java @@ -65,6 +65,10 @@ public class EIRDataTypeSet { DataType(final int v) { value = v; } public final int value; } + /** Explicit mask to erase all implicit set EIRDataType fields: EVT_TYPE, EXT_EVT_TYPE, BDADDR_TYPE, BDADDR and RSSI. */ + static final EIRDataTypeSet EIR_DATA_TYPE_MASK = + new EIRDataTypeSet( ~( DataType.EVT_TYPE.value | DataType.EXT_EVT_TYPE.value | + DataType.BDADDR_TYPE.value | DataType.BDADDR.value | DataType.RSSI.value ) ); public int mask; diff --git a/java/org/direct_bt/EInfoReport.java b/java/org/direct_bt/EInfoReport.java index 0cd94989..98018d9c 100644 --- a/java/org/direct_bt/EInfoReport.java +++ b/java/org/direct_bt/EInfoReport.java @@ -51,6 +51,39 @@ public final class EInfoReport implements AutoCloseable, Cloneable private volatile long nativeInstance; /* pp */ long getNativeInstance() { return nativeInstance; } + public enum Source { + /** Not Available */ + NA( 0 ), + /** (Extended) Advertising Data (AD or EAD) Indication Variant, i.e. initial passive scan data. */ + AD_IND( 1 ), + /** (Extended) Advertising Data (AD or EAD) Scan Response, i.e. optional active scanning data after AD_IND. */ + AD_SCAN_RSP( 2 ), + /** Extended Inquiry Response (EIR) */ + EIR( 3 ), + /** Extended Inquiry Response (EIR) from Kernel Mgmt */ + EIR_MGMT( 4 ); + + Source(final int v) { + value = v; + } + public final int value; + + /** + * Maps the specified integer value to a constant of {@link Source}. + * @param value the integer value to be mapped to a constant of this enum type. + * @return the corresponding constant of this enum type, using {@link #NA} if not supported. + */ + public static Source get(final int value) { + switch(value) { + case 1: return AD_IND; + case 2: return AD_SCAN_RSP; + case 3: return EIR; + case 4: return EIR_MGMT; + default: return NA; + } + } + } + /** * New independent EInfoReport instance */ @@ -166,7 +199,9 @@ public final class EInfoReport implements AutoCloseable, Cloneable */ public native void setConnInterval(final short min, final short max); - // public native Source getSource(); + public final Source getSource() { return Source.get( getSourceImpl() ); } + private native int getSourceImpl(); + public native long getTimestamp(); public final EIRDataTypeSet getEIRDataMask() { diff --git a/src/direct_bt/BTAdapter.cpp b/src/direct_bt/BTAdapter.cpp index c6204575..65f25bb2 100644 --- a/src/direct_bt/BTAdapter.cpp +++ b/src/direct_bt/BTAdapter.cpp @@ -660,7 +660,7 @@ HCIStatusCode BTAdapter::uploadKeys(SMPKeyBin& bin, const bool write) noexcept { } EInfoReport ad_report; { - ad_report.setSource( EInfoReport::Source::NA ); + ad_report.setSource( EInfoReport::Source::NA, false ); ad_report.setTimestamp( jau::getCurrentMilliseconds() ); ad_report.setAddressType( bin.getRemoteAddrAndType().type ); ad_report.setAddress( bin.getRemoteAddrAndType().address ); @@ -1899,7 +1899,7 @@ bool BTAdapter::mgmtEvDeviceConnectedHCI(const MgmtEvent& e) noexcept { const MgmtEvtDeviceConnected &event = *static_cast<const MgmtEvtDeviceConnected *>(&e); EInfoReport ad_report; { - ad_report.setSource(EInfoReport::Source::EIR); + ad_report.setSource(EInfoReport::Source::EIR, false); ad_report.setTimestamp(event.getTimestamp()); ad_report.setAddressType(event.getAddressType()); ad_report.setAddress( event.getAddress() ); diff --git a/src/direct_bt/BTDevice.cpp b/src/direct_bt/BTDevice.cpp index 5d1cc160..86c1710a 100644 --- a/src/direct_bt/BTDevice.cpp +++ b/src/direct_bt/BTDevice.cpp @@ -51,6 +51,8 @@ BTDevice::BTDevice(const ctor_cookie& cc, BTAdapter & a, EInfoReport const & r) ts_last_update(ts_last_discovery), name(), eir( std::make_shared<EInfoReport>() ), + eir_ind( std::make_shared<EInfoReport>() ), + eir_scan_rsp( std::make_shared<EInfoReport>() ), hciConnHandle(0), le_features(LE_Features::NONE), le_phy_tx(LE_PHYs::NONE), @@ -113,14 +115,19 @@ std::string const BTDevice::getName() const noexcept { return res; } -std::shared_ptr<const EInfoReport> BTDevice::getEIR() const noexcept { +std::shared_ptr<EInfoReport> BTDevice::getEIR() noexcept { const std::lock_guard<std::mutex> lock(mtx_eir); // RAII-style acquire and relinquish via destructor return eir; } -std::shared_ptr<EInfoReport> BTDevice::getEIR() noexcept { +std::shared_ptr<EInfoReport> BTDevice::getEIRInd() noexcept { const std::lock_guard<std::mutex> lock(mtx_eir); // RAII-style acquire and relinquish via destructor - return eir; + return eir_ind; +} + +std::shared_ptr<EInfoReport> BTDevice::getEIRScanRsp() noexcept { + const std::lock_guard<std::mutex> lock(mtx_eir); // RAII-style acquire and relinquish via destructor + return eir_scan_rsp; } std::string BTDevice::toString(bool includeDiscoveredServices) const noexcept { @@ -156,6 +163,8 @@ void BTDevice::clearData() noexcept { { const std::lock_guard<std::mutex> lock(mtx_eir); // RAII-style acquire and relinquish via destructor eir = std::make_shared<EInfoReport>(); + eir_ind = std::make_shared<EInfoReport>(); + eir_scan_rsp = std::make_shared<EInfoReport>(); } // hciConnHandle = 0; // already done le_features = LE_Features::NONE; @@ -178,6 +187,11 @@ EIRDataType BTDevice::update(EInfoReport const & data) noexcept { if( EIRDataType::NONE != res0 ) { eir = eir_new; } + if( EInfoReport::Source::AD_IND == data.getSource() ) { + eir_ind = std::make_shared<EInfoReport>( data ); + } else if( EInfoReport::Source::AD_SCAN_RSP == data.getSource() ) { + eir_scan_rsp = std::make_shared<EInfoReport>( data ); + } ts_last_update = data.getTimestamp(); if( data.isSet(EIRDataType::BDADDR) ) { diff --git a/src/direct_bt/BTTypes0.cpp b/src/direct_bt/BTTypes0.cpp index f64f7e3d..14a11c18 100644 --- a/src/direct_bt/BTTypes0.cpp +++ b/src/direct_bt/BTTypes0.cpp @@ -818,7 +818,7 @@ EIRDataType EInfoReport::set(const EInfoReport& eir) noexcept { } } if( EIRDataType::NONE != res ) { - setSource(eir.getSource()); + setSource(eir.getSource(), eir.getSourceExt()); setTimestamp(eir.getTimestamp()); } return res; @@ -839,8 +839,8 @@ int EInfoReport::findService(const jau::uuid_t& uuid) const noexcept std::string direct_bt::to_string(EInfoReport::Source source) noexcept { switch (source) { case EInfoReport::Source::NA: return "N/A"; - case EInfoReport::Source::AD: return "AD"; - case EInfoReport::Source::EAD: return "EAD"; + case EInfoReport::Source::AD_IND: return "AD_IND"; + case EInfoReport::Source::AD_SCAN_RSP: return "AD_SCAN_RSP"; case EInfoReport::Source::EIR: return "EIR"; case EInfoReport::Source::EIR_MGMT: return "EIR_MGMT"; } @@ -926,11 +926,12 @@ bool EInfoReport::addService(const jau::uuid_t& uuid) noexcept { } std::string EInfoReport::eirDataMaskToString() const noexcept { - return std::string("DataSet"+ direct_bt::to_string(eir_data_mask) ); + return std::string("Set"+ direct_bt::to_string( EIR_DATA_TYPE_MASK & eir_data_mask ) ); } std::string EInfoReport::toString(const bool includeServices) const noexcept { - std::string out("EInfoReport::"+to_string(source)+ - "[address["+address.toString()+", "+to_string(getAddressType())+"/"+std::to_string(ad_address_type)+ + const std::string source_ext_s = source_ext ? "bt5" : "bt4"; + std::string out(to_string(source)+ + "["+source_ext_s+", address["+address.toString()+", "+to_string(getAddressType())+"/"+std::to_string(ad_address_type)+ "], "+eirDataMaskToString()+", "); if( isSet(EIRDataType::NAME) || isSet(EIRDataType::NAME_SHORT) ) { out += "name['"+name+"'/'"+name_short+"'], "; @@ -1383,6 +1384,49 @@ jau::nsize_t EInfoReport::write_data(EIRDataType write_mask, uint8_t * data, jau } // #define AD_DEBUG 1 +EInfoReport::Source EInfoReport::toSource(const AD_PDU_Type type) { + switch( type ) { + case AD_PDU_Type::ADV_IND: + [[fallthrough]]; + case AD_PDU_Type::ADV_DIRECT_IND: + [[fallthrough]]; + case AD_PDU_Type::ADV_SCAN_IND: + [[fallthrough]]; + case AD_PDU_Type::ADV_NONCONN_IND: + [[fallthrough]]; + case AD_PDU_Type::ADV_IND2: + [[fallthrough]]; + case AD_PDU_Type::DIRECT_IND2: + [[fallthrough]]; + case AD_PDU_Type::SCAN_IND2: + [[fallthrough]]; + case AD_PDU_Type::NONCONN_IND2: + return Source::AD_IND; + + case AD_PDU_Type::SCAN_RSP: + [[fallthrough]]; + case AD_PDU_Type::SCAN_RSP_to_ADV_IND: + [[fallthrough]]; + case AD_PDU_Type::SCAN_RSP_to_ADV_SCAN_IND: + return Source::AD_SCAN_RSP; + default: + return Source::NA; + } +} + +EInfoReport::Source EInfoReport::toSource(const EAD_Event_Type type) { + if( isEAD_Event_TypeSet(type, EAD_Event_Type::CONN_ADV) || + isEAD_Event_TypeSet(type, EAD_Event_Type::SCAN_ADV) || + isEAD_Event_TypeSet(type, EAD_Event_Type::DIR_ADV) ) { + return Source::AD_IND; + } + if( isEAD_Event_TypeSet(type, EAD_Event_Type::SCAN_RSP) ) { + return Source::AD_SCAN_RSP; + } + return Source::NA; +} + + jau::darray<std::unique_ptr<EInfoReport>> EInfoReport::read_ad_reports(uint8_t const * data, jau::nsize_t const data_length) noexcept { jau::nsize_t const num_reports = (jau::nsize_t) data[0]; jau::darray<std::unique_ptr<EInfoReport>> ad_reports; @@ -1401,7 +1445,7 @@ jau::darray<std::unique_ptr<EInfoReport>> EInfoReport::read_ad_reports(uint8_t c for(i = 0; i < num_reports && i_octets < limes; i++) { // seg 1 ad_reports.push_back( std::make_unique<EInfoReport>() ); - ad_reports[i]->setSource(Source::AD); + ad_reports[i]->setSource(Source::AD_IND, false /* ext */); // first guess ad_reports[i]->setTimestamp(timestamp); if( i_octets + seg4_size > limes ) { @@ -1413,7 +1457,11 @@ jau::darray<std::unique_ptr<EInfoReport>> EInfoReport::read_ad_reports(uint8_t c } // seg 1: 1 - ad_reports[i]->setEvtType(static_cast<AD_PDU_Type>(*i_octets++)); + { + const AD_PDU_Type ad_type = static_cast<AD_PDU_Type>(*i_octets++); + ad_reports[i]->setEvtType( ad_type ); + ad_reports[i]->setSource( toSource( ad_type ), false /* ext */); + } // seg 2: 1 ad_reports[i]->setADAddressType(*i_octets++); @@ -1484,7 +1532,7 @@ jau::darray<std::unique_ptr<EInfoReport>> EInfoReport::read_ext_ad_reports(uint8 for(i = 0; i < num_reports; i++) { ad_reports.push_back( std::make_unique<EInfoReport>() ); - ad_reports[i]->setSource(Source::EAD); + ad_reports[i]->setSource( Source::AD_IND, true /* ext */); // first guess ad_reports[i]->setTimestamp(timestamp); if( i_octets + seg12_size > limes ) { @@ -1497,11 +1545,15 @@ jau::darray<std::unique_ptr<EInfoReport>> EInfoReport::read_ext_ad_reports(uint8 // seg 1: 2 { - const EAD_Event_Type ead_type_ = static_cast<EAD_Event_Type>(jau::get_uint16(i_octets, 0, true /* littleEndian */)); - ad_reports[i]->setExtEvtType(ead_type_); + const EAD_Event_Type ead_type = static_cast<EAD_Event_Type>(jau::get_uint16(i_octets, 0, true /* littleEndian */)); + ad_reports[i]->setExtEvtType(ead_type); i_octets+=2; - if( isEAD_Event_TypeSet(ead_type_, EAD_Event_Type::LEGACY_PDU) ) { - ad_reports[i]->setEvtType(static_cast<AD_PDU_Type>(number(ead_type_))); + if( isEAD_Event_TypeSet(ead_type, EAD_Event_Type::LEGACY_PDU) ) { + const AD_PDU_Type ad_type = static_cast<AD_PDU_Type>( ::number(ead_type) ); + ad_reports[i]->setEvtType( ad_type ); + ad_reports[i]->setSource( toSource( ad_type ), true /* ext */); + } else { + ad_reports[i]->setSource( toSource( ead_type ), true /* ext */); } } |