Skip to content

Commit 7c7068d

Browse files
committed
Add channel index handling to NimBLEAdvertisedDevice and related structures
- Introduced m_channelIndex in NimBLEAdvertisedDevice to store the primary advertising channel. - Implemented getChannel() method to retrieve the advertising channel. - Updated setChannelIndex() method for setting the channel index. - Modified handleGapEvent() in NimBLEScan to set the channel index from the discovery event. - Added channel_index field to ble_gap_ext_disc_desc and ble_gap_disc_desc structures. - Enhanced ble_hs_hci_evt_le_adv_rpt() to handle channel index in advertising reports.
1 parent 18947bc commit 7c7068d

File tree

5 files changed

+42
-0
lines changed

5 files changed

+42
-0
lines changed

src/NimBLEAdvertisedDevice.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ NimBLEAdvertisedDevice::NimBLEAdvertisedDevice() :
3636
m_callbackSent = false;
3737
m_timestamp = 0;
3838
m_advLength = 0;
39+
m_channelIndex = 0xFF;
3940
} // NimBLEAdvertisedDevice
4041

4142

@@ -823,6 +824,19 @@ time_t NimBLEAdvertisedDevice::getTimestamp() {
823824
} // getTimestamp
824825

825826

827+
/**
828+
* @brief Get the primary advertising channel.
829+
* @return The advertising channel (37, 38, or 39) when available, or 0xFF when unknown.
830+
*/
831+
uint8_t NimBLEAdvertisedDevice::getChannel() {
832+
// Map controller channel index (0-2) to BLE advertising channels (37-39)
833+
if (m_channelIndex <= 2) {
834+
return 37 + m_channelIndex;
835+
}
836+
return 0xFF;
837+
} // getChannel
838+
839+
826840
/**
827841
* @brief Get the length of the payload advertised by the device.
828842
* @return The size of the payload in bytes.

src/NimBLEAdvertisedDevice.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ class NimBLEScan;
3838
*
3939
* When we perform a %BLE scan, the result will be a set of devices that are advertising. This
4040
* class provides a model of a detected device.
41+
*
42+
* The getChannel() method returns the primary advertising channel (37, 38, or 39) on which the
43+
* advertisement was received, or 0xFF if the channel information is not available from the controller.
4144
*/
4245
class NimBLEAdvertisedDevice {
4346
public:
@@ -120,6 +123,7 @@ class NimBLEAdvertisedDevice {
120123
size_t getPayloadLength();
121124
uint8_t getAddressType();
122125
time_t getTimestamp();
126+
uint8_t getChannel();
123127
bool isAdvertisingService(const NimBLEUUID &uuid);
124128
bool haveAppearance();
125129
bool haveManufacturerData();
@@ -149,6 +153,7 @@ class NimBLEAdvertisedDevice {
149153
void setAdvType(uint8_t advType, bool isLegacyAdv);
150154
void setPayload(const uint8_t *payload, uint8_t length, bool append);
151155
void setRSSI(int rssi);
156+
void setChannelIndex(uint8_t channel) { m_channelIndex = channel; }
152157
#if CONFIG_BT_NIMBLE_EXT_ADV
153158
void setSetId(uint8_t sid) { m_sid = sid; }
154159
void setPrimaryPhy(uint8_t phy) { m_primPhy = phy; }
@@ -164,6 +169,7 @@ class NimBLEAdvertisedDevice {
164169
time_t m_timestamp;
165170
bool m_callbackSent;
166171
uint8_t m_advLength;
172+
uint8_t m_channelIndex;
167173
#if CONFIG_BT_NIMBLE_EXT_ADV
168174
bool m_isLegacyAdv;
169175
uint8_t m_sid;

src/NimBLEScan.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ NimBLEScan::~NimBLEScan() {
130130

131131
advertisedDevice->m_timestamp = time(nullptr);
132132
advertisedDevice->setRSSI(disc.rssi);
133+
advertisedDevice->setChannelIndex(disc.channel_index);
133134
advertisedDevice->setPayload(disc.data, disc.length_data, (isLegacyAdv &&
134135
event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP));
135136

src/nimble/nimble/host/include/host/ble_gap.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,9 @@ struct ble_gap_ext_disc_desc {
403403
* set (BLE_ADDR_ANY otherwise).
404404
*/
405405
ble_addr_t direct_addr;
406+
407+
/** Primary advertising channel index (0xFF if unavailable) */
408+
uint8_t channel_index;
406409
};
407410
#endif
408411

@@ -433,6 +436,9 @@ struct ble_gap_disc_desc {
433436
* event type (BLE_ADDR_ANY otherwise).
434437
*/
435438
ble_addr_t direct_addr;
439+
440+
/** Primary advertising channel index (0xFF if unavailable) */
441+
uint8_t channel_index;
436442
};
437443

438444
struct ble_gap_repeat_pairing {

src/nimble/nimble/host/src/ble_hs_hci_evt.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,7 @@ ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, const void *data, unsigned int len)
501501
data += sizeof(*ev);
502502

503503
desc.direct_addr = *BLE_ADDR_ANY;
504+
desc.channel_index = 0xFF;
504505

505506
for (i = 0; i < ev->num_reports; i++) {
506507
rpt = data;
@@ -513,6 +514,10 @@ ble_hs_hci_evt_le_adv_rpt(uint8_t subevent, const void *data, unsigned int len)
513514
desc.length_data = rpt->data_len;
514515
desc.data = rpt->data;
515516
desc.rssi = rpt->data[rpt->data_len];
517+
/* Channel index follows RSSI if available */
518+
if (data - (const uint8_t*)rpt > sizeof(rpt) + rpt->data_len + 1) {
519+
desc.channel_index = rpt->data[rpt->data_len + 1];
520+
}
516521

517522
ble_gap_rx_adv_report(&desc);
518523
}
@@ -535,6 +540,7 @@ ble_hs_hci_evt_le_dir_adv_rpt(uint8_t subevent, const void *data, unsigned int l
535540
/* Data fields not present in a direct advertising report. */
536541
desc.data = NULL;
537542
desc.length_data = 0;
543+
desc.channel_index = 0xFF;
538544

539545
for (i = 0; i < ev->num_reports; i++) {
540546
desc.event_type = ev->reports[i].type;
@@ -612,6 +618,7 @@ ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, const void *data,
612618
report = &ev->reports[0];
613619
for (i = 0; i < ev->num_reports; i++) {
614620
memset(&desc, 0, sizeof(desc));
621+
desc.channel_index = 0xFF;
615622

616623
desc.props = (report->evt_type) & 0x1F;
617624
if (desc.props & BLE_HCI_ADV_LEGACY_MASK) {
@@ -649,6 +656,14 @@ ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, const void *data,
649656
desc.prim_phy = report->pri_phy;
650657
desc.sec_phy = report->sec_phy;
651658
desc.periodic_adv_itvl = report->periodic_itvl;
659+
/* Channel index may follow the data if available */
660+
if (report->data_len < 255) {
661+
const uint8_t *channel_ptr = &report->data[report->data_len];
662+
/* Verify we're not reading past the event data */
663+
if ((const uint8_t*)channel_ptr < (const uint8_t*)data + len) {
664+
desc.channel_index = *channel_ptr;
665+
}
666+
}
652667

653668
ble_gap_rx_ext_adv_report(&desc);
654669

0 commit comments

Comments
 (0)