Skip to content

Commit 711ccfa

Browse files
committed
fix(ble): Fix Advertising data being overwritten
1 parent 3239ee2 commit 711ccfa

File tree

2 files changed

+151
-8
lines changed

2 files changed

+151
-8
lines changed

libraries/BLE/src/BLEAdvertisedDevice.cpp

Lines changed: 148 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ BLEAdvertisedDevice::BLEAdvertisedDevice() {
4646
m_txPower = 0;
4747
m_pScan = nullptr;
4848
m_advType = 0;
49+
m_payload = nullptr;
50+
m_payloadLength = 0;
4951

5052
#if defined(CONFIG_NIMBLE_ENABLED)
5153
m_callbackSent = false;
@@ -59,6 +61,108 @@ BLEAdvertisedDevice::BLEAdvertisedDevice() {
5961
m_isLegacyAdv = true;
6062
} // BLEAdvertisedDevice
6163

64+
BLEAdvertisedDevice::~BLEAdvertisedDevice() {
65+
if (m_payload != nullptr) {
66+
free(m_payload);
67+
m_payload = nullptr;
68+
m_payloadLength = 0;
69+
}
70+
} // ~BLEAdvertisedDevice
71+
72+
BLEAdvertisedDevice::BLEAdvertisedDevice(const BLEAdvertisedDevice &other) {
73+
m_adFlag = other.m_adFlag;
74+
m_appearance = other.m_appearance;
75+
m_deviceType = other.m_deviceType;
76+
m_manufacturerData = other.m_manufacturerData;
77+
m_name = other.m_name;
78+
m_rssi = other.m_rssi;
79+
m_serviceUUIDs = other.m_serviceUUIDs;
80+
m_serviceData = other.m_serviceData;
81+
m_serviceDataUUIDs = other.m_serviceDataUUIDs;
82+
m_txPower = other.m_txPower;
83+
m_pScan = other.m_pScan;
84+
m_advType = other.m_advType;
85+
m_address = other.m_address;
86+
m_addressType = other.m_addressType;
87+
88+
#if defined(CONFIG_NIMBLE_ENABLED)
89+
m_callbackSent = other.m_callbackSent;
90+
#endif
91+
92+
m_haveAppearance = other.m_haveAppearance;
93+
m_haveManufacturerData = other.m_haveManufacturerData;
94+
m_haveName = other.m_haveName;
95+
m_haveRSSI = other.m_haveRSSI;
96+
m_haveTXPower = other.m_haveTXPower;
97+
m_isLegacyAdv = other.m_isLegacyAdv;
98+
99+
// Deep copy the payload
100+
m_payloadLength = other.m_payloadLength;
101+
if (other.m_payload != nullptr && other.m_payloadLength > 0) {
102+
m_payload = (uint8_t *)malloc(m_payloadLength);
103+
if (m_payload != nullptr) {
104+
memcpy(m_payload, other.m_payload, m_payloadLength);
105+
} else {
106+
m_payloadLength = 0;
107+
}
108+
} else {
109+
m_payload = nullptr;
110+
m_payloadLength = 0;
111+
}
112+
} // BLEAdvertisedDevice copy constructor
113+
114+
BLEAdvertisedDevice &BLEAdvertisedDevice::operator=(const BLEAdvertisedDevice &other) {
115+
if (this == &other) {
116+
return *this;
117+
}
118+
119+
m_adFlag = other.m_adFlag;
120+
m_appearance = other.m_appearance;
121+
m_deviceType = other.m_deviceType;
122+
m_manufacturerData = other.m_manufacturerData;
123+
m_name = other.m_name;
124+
m_rssi = other.m_rssi;
125+
m_serviceUUIDs = other.m_serviceUUIDs;
126+
m_serviceData = other.m_serviceData;
127+
m_serviceDataUUIDs = other.m_serviceDataUUIDs;
128+
m_txPower = other.m_txPower;
129+
m_pScan = other.m_pScan;
130+
m_advType = other.m_advType;
131+
m_address = other.m_address;
132+
m_addressType = other.m_addressType;
133+
134+
#if defined(CONFIG_NIMBLE_ENABLED)
135+
m_callbackSent = other.m_callbackSent;
136+
#endif
137+
138+
m_haveAppearance = other.m_haveAppearance;
139+
m_haveManufacturerData = other.m_haveManufacturerData;
140+
m_haveName = other.m_haveName;
141+
m_haveRSSI = other.m_haveRSSI;
142+
m_haveTXPower = other.m_haveTXPower;
143+
m_isLegacyAdv = other.m_isLegacyAdv;
144+
145+
// Free existing payload and deep copy the new one
146+
if (m_payload != nullptr) {
147+
free(m_payload);
148+
}
149+
150+
m_payloadLength = other.m_payloadLength;
151+
if (other.m_payload != nullptr && other.m_payloadLength > 0) {
152+
m_payload = (uint8_t *)malloc(m_payloadLength);
153+
if (m_payload != nullptr) {
154+
memcpy(m_payload, other.m_payload, m_payloadLength);
155+
} else {
156+
m_payloadLength = 0;
157+
}
158+
} else {
159+
m_payload = nullptr;
160+
m_payloadLength = 0;
161+
}
162+
163+
return *this;
164+
} // BLEAdvertisedDevice assignment operator
165+
62166
bool BLEAdvertisedDevice::isLegacyAdvertisement() {
63167
return m_isLegacyAdv;
64168
}
@@ -308,8 +412,27 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t *payload, size_t total_len)
308412
uint8_t ad_type;
309413
uint8_t sizeConsumed = 0;
310414
bool finished = false;
311-
m_payload = payload;
312-
m_payloadLength = total_len;
415+
416+
// Store/append raw payload data for later retrieval
417+
// This handles both ADV and Scan Response packets by merging them
418+
if (m_payload != nullptr && m_payloadLength > 0) {
419+
// Append new payload data (scan response) to existing (advertisement)
420+
uint8_t *new_payload = (uint8_t *)realloc(m_payload, m_payloadLength + total_len);
421+
if (new_payload != nullptr) {
422+
memcpy(new_payload + m_payloadLength, payload, total_len);
423+
m_payload = new_payload;
424+
m_payloadLength += total_len;
425+
}
426+
} else {
427+
// First payload - make a copy since the original buffer may be reused
428+
m_payload = (uint8_t *)malloc(total_len);
429+
if (m_payload != nullptr) {
430+
memcpy(m_payload, payload, total_len);
431+
m_payloadLength = total_len;
432+
} else {
433+
m_payloadLength = 0;
434+
}
435+
}
313436

314437
while (!finished) {
315438
length = *payload; // Retrieve the length of the record.
@@ -446,21 +569,38 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t *payload, size_t total_len)
446569
} // parseAdvertisement
447570

448571
/**
449-
* @brief Parse the advertising payload.
572+
* @brief Set the advertising payload.
450573
* @param [in] payload The payload of the advertised device.
451574
* @param [in] total_len The length of payload
575+
* @param [in] append If true, append to existing payload (for scan response merging)
452576
*/
453577
void BLEAdvertisedDevice::setPayload(uint8_t *payload, size_t total_len, bool append) {
454-
if (m_payload == nullptr || m_payloadLength == 0) {
578+
if (total_len == 0 || payload == nullptr) {
455579
return;
456580
}
457581

458-
if (append) {
459-
m_payload = (uint8_t *)realloc(m_payload, m_payloadLength + total_len);
460-
memcpy(m_payload + m_payloadLength, payload, total_len);
582+
if (append && m_payload != nullptr && m_payloadLength > 0) {
583+
// Append scan response data to existing advertisement data
584+
uint8_t *new_payload = (uint8_t *)realloc(m_payload, m_payloadLength + total_len);
585+
if (new_payload == nullptr) {
586+
log_e("Failed to reallocate payload buffer");
587+
return;
588+
}
589+
memcpy(new_payload + m_payloadLength, payload, total_len);
590+
m_payload = new_payload;
461591
m_payloadLength += total_len;
462592
} else {
463-
m_payload = payload;
593+
// First payload or replacing existing - make a copy
594+
if (m_payload != nullptr && m_payloadLength > 0) {
595+
free(m_payload);
596+
}
597+
m_payload = (uint8_t *)malloc(total_len);
598+
if (m_payload == nullptr) {
599+
log_e("Failed to allocate payload buffer");
600+
m_payloadLength = 0;
601+
return;
602+
}
603+
memcpy(m_payload, payload, total_len);
464604
m_payloadLength = total_len;
465605
}
466606
} // setPayload

libraries/BLE/src/BLEAdvertisedDevice.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ class BLEAdvertisedDevice {
7474
***************************************************************************/
7575

7676
BLEAdvertisedDevice();
77+
~BLEAdvertisedDevice();
78+
BLEAdvertisedDevice(const BLEAdvertisedDevice &other);
79+
BLEAdvertisedDevice &operator=(const BLEAdvertisedDevice &other);
7780
BLEAddress getAddress();
7881
uint16_t getAppearance();
7982
String getManufacturerData();

0 commit comments

Comments
 (0)