summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/direct_bt/BTDevice.hpp24
-rw-r--r--api/direct_bt/BTTypes0.hpp34
-rw-r--r--examples/dbt_repeater00.cpp12
-rw-r--r--examples/dbt_scanner10.cpp4
-rw-r--r--examples/java/DBTScanner10.java4
-rw-r--r--java/jau/direct_bt/DBTDevice.java20
-rw-r--r--java/jni/direct_bt/DBTDevice.cxx30
-rw-r--r--java/jni/direct_bt/EInfoReport.cxx10
-rw-r--r--java/org/direct_bt/BTDevice.java18
-rw-r--r--java/org/direct_bt/EIRDataTypeSet.java4
-rw-r--r--java/org/direct_bt/EInfoReport.java37
-rw-r--r--src/direct_bt/BTAdapter.cpp4
-rw-r--r--src/direct_bt/BTDevice.cpp20
-rw-r--r--src/direct_bt/BTTypes0.cpp78
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 */);
}
}