22
33#ifdef TARGET_NRF
44BLEDfu bledfu;
5- BLEService imageService (" 1337 " );
6- BLECharacteristic imageCharacteristic (" 1337 " , BLEWrite | BLEWriteWithoutResponse | BLENotify, 512 );
5+ BLEService imageService (" 2446 " );
6+ BLECharacteristic imageCharacteristic (" 2446 " , BLEWrite | BLEWriteWithoutResponse | BLENotify, 512 );
77#endif
88
99#ifdef TARGET_ESP32
10- // BLE Server Callbacks
10+ // Define queue sizes and structures first
11+ #define RESPONSE_QUEUE_SIZE 10
12+ #define MAX_RESPONSE_SIZE 512
13+ #define COMMAND_QUEUE_SIZE 5
14+ #define MAX_COMMAND_SIZE 512
15+
16+ struct ResponseQueueItem {
17+ uint8_t data[MAX_RESPONSE_SIZE];
18+ uint16_t len;
19+ bool pending;
20+ };
21+
22+ struct CommandQueueItem {
23+ uint8_t data[MAX_COMMAND_SIZE];
24+ uint16_t len;
25+ bool pending;
26+ };
27+
28+ ResponseQueueItem responseQueue[RESPONSE_QUEUE_SIZE];
29+ uint8_t responseQueueHead = 0 ;
30+ uint8_t responseQueueTail = 0 ;
31+
32+ CommandQueueItem commandQueue[COMMAND_QUEUE_SIZE];
33+ uint8_t commandQueueHead = 0 ;
34+ uint8_t commandQueueTail = 0 ;
35+
1136class MyBLEServerCallbacks : public BLEServerCallbacks {
1237 void onConnect (BLEServer* pServer) {
1338 writeSerial (" === BLE CLIENT CONNECTED (ESP32) ===" );
1439 writeSerial (" Client connected to ESP32 BLE server" );
1540 delay (100 ); // Give connection time to fully establish
1641 writeSerial (" Number of connected clients: " + String (pServer->getConnectedCount ()));
1742 }
18-
1943 void onDisconnect (BLEServer* pServer) {
2044 writeSerial (" === BLE CLIENT DISCONNECTED (ESP32) ===" );
2145 writeSerial (" Client disconnected from ESP32 BLE server" );
2246 writeSerial (" Number of remaining clients: " + String (pServer->getConnectedCount ()));
23-
24- if (currentImage.data || currentImage.blocksReceived ||
25- currentImage.blockBytesReceived || currentImage.blockPacketsReceived ) {
26- writeSerial (" Cleaning up image data due to disconnect..." );
27- cleanupImageMemory ();
28- }
29-
30- // Restart advertising to allow new connections
3147 writeSerial (" Waiting before restarting advertising..." );
3248 delay (500 );
33-
3449 if (pServer->getConnectedCount () == 0 ) {
3550 BLEDevice::startAdvertising ();
3651 writeSerial (" Advertising restarted" );
@@ -40,14 +55,13 @@ class MyBLEServerCallbacks : public BLEServerCallbacks {
4055 }
4156};
4257
43- // BLE Characteristic Callbacks
4458class MyBLECharacteristicCallbacks : public BLECharacteristicCallbacks {
4559public:
4660 void onWrite (BLECharacteristic* pCharacteristic) {
4761 writeSerial (" === BLE WRITE RECEIVED (ESP32) ===" );
4862 String value = pCharacteristic->getValue ();
4963 writeSerial (" Received data length: " + String (value.length ()) + " bytes" );
50- if (value.length () > 0 ) {
64+ if (value.length () > 0 && value. length () <= MAX_COMMAND_SIZE ) {
5165 uint8_t * data = (uint8_t *)value.c_str ();
5266 uint16_t len = value.length ();
5367 // Log first few bytes
@@ -57,15 +71,26 @@ class MyBLECharacteristicCallbacks : public BLECharacteristicCallbacks {
5771 hexDump += String (data[i], HEX) + " " ;
5872 }
5973 writeSerial (hexDump);
60- imageDataWritten (NULL , NULL , data, len);
74+
75+ // Queue command for processing in main loop to avoid blocking callback
76+ uint8_t nextHead = (commandQueueHead + 1 ) % COMMAND_QUEUE_SIZE;
77+ if (nextHead != commandQueueTail) {
78+ memcpy (commandQueue[commandQueueHead].data , data, len);
79+ commandQueue[commandQueueHead].len = len;
80+ commandQueue[commandQueueHead].pending = true ;
81+ commandQueueHead = nextHead;
82+ writeSerial (" ESP32: Command queued for processing" );
83+ } else {
84+ writeSerial (" ERROR: Command queue full, dropping command" );
85+ }
86+ } else if (value.length () > MAX_COMMAND_SIZE) {
87+ writeSerial (" WARNING: Command too large, dropping" );
6188 } else {
6289 writeSerial (" WARNING: Empty data received" );
6390 }
6491 }
6592};
66- #endif
6793
68- #ifdef TARGET_ESP32
6994BLEServer* pServer = nullptr ;
7095BLEService* pService = nullptr ;
7196BLECharacteristic* pTxCharacteristic = nullptr ;
@@ -91,15 +116,57 @@ void setup() {
91116}
92117
93118void loop () {
119+ #ifdef TARGET_ESP32
120+ // Process queued commands outside of callback context
121+ if (commandQueueTail != commandQueueHead) {
122+ writeSerial (" ESP32: Processing queued command (" + String (commandQueue[commandQueueTail].len ) + " bytes)" );
123+ imageDataWritten (NULL , NULL , commandQueue[commandQueueTail].data , commandQueue[commandQueueTail].len );
124+ commandQueue[commandQueueTail].pending = false ;
125+ commandQueueTail = (commandQueueTail + 1 ) % COMMAND_QUEUE_SIZE;
126+ writeSerial (" Command processed" );
127+ }
128+
129+ // Process queued BLE responses outside of callback context (one per loop for better responsiveness)
130+ if (responseQueueTail != responseQueueHead && pTxCharacteristic && pServer && pServer->getConnectedCount () > 0 ) {
131+ writeSerial (" ESP32: Sending queued response (" + String (responseQueue[responseQueueTail].len ) + " bytes)" );
132+ pTxCharacteristic->setValue (responseQueue[responseQueueTail].data , responseQueue[responseQueueTail].len );
133+ pTxCharacteristic->notify ();
134+ responseQueue[responseQueueTail].pending = false ;
135+ responseQueueTail = (responseQueueTail + 1 ) % RESPONSE_QUEUE_SIZE;
136+ writeSerial (" Response sent successfully" );
137+ delay (20 ); // Brief delay to let BLE stack process
138+ }
139+ #endif
140+
94141 if (currentImage.ready ) {
95142 writeSerial (" Processing received image..." );
96143 displayReceivedImage ();
97144 currentImage.ready = false ;
98145 cleanupImageMemory ();
99146 writeSerial (" Image processing complete" );
100147 }
101- if (globalConfig.power_option .sleep_timeout_ms > 0 )delay (globalConfig.power_option .sleep_timeout_ms );
102- else delay (2000 );
148+
149+ #ifdef TARGET_ESP32
150+ // Use shorter delay when BLE transfers are active for faster response
151+ bool bleActive = (commandQueueTail != commandQueueHead) ||
152+ (responseQueueTail != responseQueueHead) ||
153+ (pServer && pServer->getConnectedCount () > 0 );
154+
155+ if (bleActive) {
156+ delay (10 ); // Fast polling when BLE is active
157+ } else {
158+ if (globalConfig.power_option .sleep_timeout_ms > 0 )
159+ delay (globalConfig.power_option .sleep_timeout_ms );
160+ else
161+ delay (2000 );
162+ }
163+ #else
164+ if (globalConfig.power_option .sleep_timeout_ms > 0 )
165+ delay (globalConfig.power_option .sleep_timeout_ms );
166+ else
167+ delay (2000 );
168+ #endif
169+
103170 writeSerial (" Loop end: " + String (millis () / 100 ));
104171}
105172
@@ -144,7 +211,7 @@ void updatemsdata(){
144211// THIS IS A PLACEHOLDER FOR THE ACTUAL PAYLOAD
145212// carefull, the size is limited
146213uint8_t msd_payload[13 ];
147- uint16_t msd_cid = 0x1337 ;
214+ uint16_t msd_cid = 0x2446 ;
148215memset (msd_payload, 0 , sizeof (msd_payload));
149216memcpy (msd_payload, (uint8_t *)&msd_cid, sizeof (msd_cid));
150217msd_payload[2 ] = 0x02 ;
@@ -192,7 +259,7 @@ void ble_init(){
192259 bledfu.begin ();
193260 writeSerial (" BLE DFU initialized successfully" );
194261 writeSerial (" BLE initialized successfully" );
195- writeSerial (" Setting up BLE service 0x1337 ..." );
262+ writeSerial (" Setting up BLE service 0x2446 ..." );
196263 imageService.begin ();
197264 writeSerial (" BLE service started" );
198265 imageCharacteristic.setWriteCallback (imageDataWritten);
@@ -235,14 +302,14 @@ void ble_init(){
235302 MyBLEServerCallbacks* serverCallbacks = new MyBLEServerCallbacks ();
236303 pServer->setCallbacks (serverCallbacks);
237304 writeSerial (" Server callbacks configured" );
238- BLEUUID serviceUUID (" 00001337 -0000-1000-8000-00805F9B34FB" );
305+ BLEUUID serviceUUID (" 00002446 -0000-1000-8000-00805F9B34FB" );
239306 pService = pServer->createService (serviceUUID);
240307 if (pService == nullptr ) {
241308 writeSerial (" ERROR: Failed to create BLE service" );
242309 return ;
243310 }
244- writeSerial (" BLE service 0x1337 created successfully" );
245- BLEUUID charUUID (" 00001337 -0000-1000-8000-00805F9B34FB" );
311+ writeSerial (" BLE service 0x2446 created successfully" );
312+ BLEUUID charUUID (" 00002446 -0000-1000-8000-00805F9B34FB" );
246313 pTxCharacteristic = pService->createCharacteristic (
247314 charUUID,
248315 BLECharacteristic::PROPERTY_READ |
@@ -266,10 +333,12 @@ void ble_init(){
266333 }
267334 pAdvertising->addServiceUUID (serviceUUID);
268335 writeSerial (" Service UUID added to advertising" );
269- // Add manufacturer data
270336 BLEAdvertisementData advertisementData;
337+ advertisementData.setName (deviceName);
338+ writeSerial (" Device name added to advertising" );
339+ // Add manufacturer data
271340 uint8_t msd_payload[13 ];
272- uint16_t msd_cid = 0x1337 ;
341+ uint16_t msd_cid = 0x2446 ;
273342 memset (msd_payload, 0 , sizeof (msd_payload));
274343 memcpy (msd_payload, (uint8_t *)&msd_cid, sizeof (msd_cid));
275344 msd_payload[2 ] = 0x02 ;
@@ -290,7 +359,7 @@ void ble_init(){
290359 advertisementData.setManufacturerData (manufacturerDataStr);
291360 pAdvertising->setAdvertisementData (advertisementData);
292361 writeSerial (" Manufacturer data added to advertising" );
293- pAdvertising->setScanResponse (true );
362+ pAdvertising->setScanResponse (false );
294363 pAdvertising->setMinPreferred (0x0006 );
295364 pAdvertising->setMinPreferred (0x0012 );
296365 writeSerial (" Advertising intervals set" );
@@ -424,11 +493,6 @@ void disconnect_callback(uint16_t conn_handle, uint8_t reason) {
424493 (void )reason;
425494 writeSerial (" === BLE CLIENT DISCONNECTED ===" );
426495 writeSerial (" Disconnect reason: " + String (reason));
427- if (currentImage.data || currentImage.blocksReceived ||
428- currentImage.blockBytesReceived || currentImage.blockPacketsReceived ) {
429- writeSerial (" Cleaning up image data due to disconnect..." );
430- cleanupImageMemory ();
431- }
432496}
433497
434498String getChipIdHex () {
@@ -738,18 +802,26 @@ void sendResponse(uint8_t* response, uint8_t len){
738802 writeSerial (" Response notified (nRF52)" );
739803 #endif
740804 #ifdef TARGET_ESP32
741- if (pTxCharacteristic) {
742- writeSerial (" ESP32: Setting characteristic value..." );
743- pTxCharacteristic->setValue (response, len);
744- // Need to explicitly notify for ESP32
745- pTxCharacteristic->notify (true );
746- writeSerial (" SetValue and notify called successfully" );
805+ // Queue response to avoid calling notify() from callback context
806+ if (len <= MAX_RESPONSE_SIZE) {
807+ uint8_t nextHead = (responseQueueHead + 1 ) % RESPONSE_QUEUE_SIZE;
808+ if (nextHead != responseQueueTail) {
809+ memcpy (responseQueue[responseQueueHead].data , response, len);
810+ responseQueue[responseQueueHead].len = len;
811+ responseQueue[responseQueueHead].pending = true ;
812+ responseQueueHead = nextHead;
813+ writeSerial (" ESP32: Response queued (queue size: " + String ((responseQueueHead - responseQueueTail + RESPONSE_QUEUE_SIZE) % RESPONSE_QUEUE_SIZE) + " )" );
814+ } else {
815+ writeSerial (" ERROR: Response queue full, dropping response" );
816+ }
747817 } else {
748- writeSerial (" ERROR: pTxCharacteristic is null " );
818+ writeSerial (" ERROR: Response too large for queue ( " + String (len) + " > " + String (MAX_RESPONSE_SIZE) + " ) " );
749819 }
750820 #endif
821+ #ifndef TARGET_ESP32
751822 delay (20 );
752823 writeSerial (" Response sent successfully" );
824+ #endif
753825}
754826
755827uint32_t calculateCRC32 (uint8_t * data, uint32_t len) {
0 commit comments