11#include < NimBLEDevice.h>
2+ #include < esp_hpl.hpp>
23#include < esp_timer.h>
34
45#define L2CAP_PSM 192
@@ -52,6 +53,9 @@ class L2CAPChannelCallbacks: public BLEL2CAPChannelCallbacks {
5253 // Append new data to buffer
5354 buffer.insert (buffer.end (), data.begin (), data.end ());
5455 totalBytesReceived += data.size ();
56+ if (startTime == 0 ) {
57+ startTime = esp_timer_get_time (); // start measuring once data flows
58+ }
5559
5660 // Process complete frames from buffer
5761 while (buffer.size () >= 3 ) { // Minimum frame size: seqno(1) + len(2)
@@ -73,7 +77,7 @@ class L2CAPChannelCallbacks: public BLEL2CAPChannelCallbacks {
7377 // Check sequence number
7478 if (seqno != expectedSequenceNumber) {
7579 sequenceErrors++;
76- printf (" Frame %lu : Sequence error - got %d, expected %d (payload=%d bytes)\n " ,
80+ printf (" Frame %zu : Sequence error - got %d, expected %d (payload=%d bytes)\n " ,
7781 totalFramesReceived, seqno, expectedSequenceNumber, payloadLen);
7882 }
7983
@@ -85,25 +89,49 @@ class L2CAPChannelCallbacks: public BLEL2CAPChannelCallbacks {
8589
8690 // Print progress every 100 frames
8791 if (totalFramesReceived % 100 == 0 ) {
88- printf (" Received %lu frames (%lu payload bytes)\n " , totalFramesReceived, totalPayloadBytes);
92+ double elapsedSeconds = (esp_timer_get_time () - startTime) / 1000000.0 ;
93+ double bytesPerSecond = elapsedSeconds > 0 ? totalBytesReceived / elapsedSeconds : 0.0 ;
94+ printf (" Received %zu frames (%zu payload bytes) - Bandwidth: %.2f KB/s (%.2f Mbps)\n " ,
95+ totalFramesReceived, totalPayloadBytes,
96+ bytesPerSecond / 1024.0 , (bytesPerSecond * 8 ) / 1000000.0 );
8997 }
9098 }
9199 }
92100
93101 void onDisconnect (NimBLEL2CAPChannel* channel) {
94102 printf (" \n L2CAP disconnected\n " );
103+ double elapsedSeconds = startTime > 0 ? (esp_timer_get_time () - startTime) / 1000000.0 : 0.0 ;
104+ double bytesPerSecond = elapsedSeconds > 0 ? totalBytesReceived / elapsedSeconds : 0.0 ;
105+
95106 printf (" Final statistics:\n " );
96- printf (" Total frames: %lu\n " , totalFramesReceived);
97- printf (" Total bytes: %lu\n " , totalBytesReceived);
98- printf (" Payload bytes: %lu\n " , totalPayloadBytes);
99- printf (" Sequence errors: %lu\n " , sequenceErrors);
100- printf (" Frame errors: %lu\n " , frameErrors);
107+ printf (" Total frames: %zu\n " , totalFramesReceived);
108+ printf (" Total bytes: %zu\n " , totalBytesReceived);
109+ printf (" Payload bytes: %zu\n " , totalPayloadBytes);
110+ printf (" Sequence errors: %zu\n " , sequenceErrors);
111+ printf (" Frame errors: %zu\n " , frameErrors);
112+ printf (" Bandwidth: %.2f KB/s (%.2f Mbps)\n " , bytesPerSecond / 1024.0 , (bytesPerSecond * 8 ) / 1000000.0 );
113+
114+ // Reset state for the next connection
115+ buffer.clear ();
116+ totalBytesReceived = 0 ;
117+ totalFramesReceived = 0 ;
118+ totalPayloadBytes = 0 ;
119+ expectedSequenceNumber = 0 ;
120+ sequenceErrors = 0 ;
121+ frameErrors = 0 ;
122+ startTime = 0 ;
101123 connected = false ;
124+
125+ // Restart advertising so another client can connect
126+ BLEDevice::startAdvertising ();
102127 }
103128};
104129
105130extern " C"
106131void app_main (void ) {
132+ // Install high performance logging before any other output
133+ esp_hpl::HighPerformanceLogger::init ();
134+
107135 printf (" Starting L2CAP server example [%lu free] [%lu min]\n " , esp_get_free_heap_size (), esp_get_minimum_free_heap_size ());
108136
109137 BLEDevice::init (" l2cap" ); // Match the name the client is looking for
@@ -112,12 +140,15 @@ void app_main(void) {
112140 auto cocServer = BLEDevice::createL2CAPServer ();
113141 auto l2capChannelCallbacks = new L2CAPChannelCallbacks ();
114142 auto channel = cocServer->createService (L2CAP_PSM , L2CAP_MTU , l2capChannelCallbacks);
143+ (void )channel; // prevent unused warning
115144
116145 auto server = BLEDevice::createServer ();
117146 server->setCallbacks (new GATTCallbacks ());
118147
119148 auto advertising = BLEDevice::getAdvertising ();
120- advertising->setScanResponse (true ); // Important for name visibility
149+ NimBLEAdvertisementData scanData;
150+ scanData.setName (" l2cap" );
151+ advertising->setScanResponseData (scanData);
121152
122153 BLEDevice::startAdvertising ();
123154 printf (" Server waiting for connection requests [%lu free] [%lu min]\n " , esp_get_free_heap_size (), esp_get_minimum_free_heap_size ());
@@ -159,11 +190,11 @@ void app_main(void) {
159190 lastHeap = currentHeap;
160191
161192 printf (" \n === STATUS UPDATE ===\n " );
162- printf (" Frames received: %lu (%.1f fps)\n " , l2capChannelCallbacks->totalFramesReceived , framesPerSecond);
163- printf (" Total bytes: %lu \n " , l2capChannelCallbacks->totalBytesReceived );
164- printf (" Payload bytes: %lu \n " , l2capChannelCallbacks->totalPayloadBytes );
193+ printf (" Frames received: %zu (%.1f fps)\n " , l2capChannelCallbacks->totalFramesReceived , framesPerSecond);
194+ printf (" Total bytes: %zu \n " , l2capChannelCallbacks->totalBytesReceived );
195+ printf (" Payload bytes: %zu \n " , l2capChannelCallbacks->totalPayloadBytes );
165196 printf (" Bandwidth: %.2f KB/s (%.2f Mbps)\n " , bytesPerSecond / 1024.0 , (bytesPerSecond * 8 ) / 1000000.0 );
166- printf (" Sequence errors: %lu \n " , l2capChannelCallbacks->sequenceErrors );
197+ printf (" Sequence errors: %zu \n " , l2capChannelCallbacks->sequenceErrors );
167198 printf (" Heap: %zu free (min: %zu), Used since start: %zu\n " ,
168199 currentHeap, minHeap, initialHeap > 0 ? initialHeap - currentHeap : 0 );
169200 printf (" ==================\n " );
0 commit comments