11#include " SerialBLEInterface.h"
22
3+ static SerialBLEInterface* instance;
4+
5+ void SerialBLEInterface::onConnect (uint16_t connection_handle) {
6+ BLE_DEBUG_PRINTLN (" SerialBLEInterface: connected" );
7+ if (instance){
8+ instance->_isDeviceConnected = true ;
9+ // no need to stop advertising on connect, as the ble stack does this automatically
10+ }
11+ }
12+
13+ void SerialBLEInterface::onDisconnect (uint16_t connection_handle, uint8_t reason) {
14+ BLE_DEBUG_PRINTLN (" SerialBLEInterface: disconnected reason=%d" , reason);
15+ if (instance){
16+ instance->_isDeviceConnected = false ;
17+ instance->startAdv ();
18+ }
19+ }
20+
321void SerialBLEInterface::begin (const char * device_name, uint32_t pin_code) {
22+
23+ instance = this ;
24+
425 char charpin[20 ];
526 sprintf (charpin, " %d" , pin_code);
627
@@ -13,12 +34,28 @@ void SerialBLEInterface::begin(const char* device_name, uint32_t pin_code) {
1334 Bluefruit.Security .setMITM (true );
1435 Bluefruit.Security .setPIN (charpin);
1536
37+ Bluefruit.Periph .setConnectCallback (onConnect);
38+ Bluefruit.Periph .setDisconnectCallback (onDisconnect);
39+
1640 // To be consistent OTA DFU should be added first if it exists
1741 // bledfu.begin();
42+
43+ // Configure and start the BLE Uart service
44+ bleuart.setPermission (SECMODE_ENC_WITH_MITM, SECMODE_ENC_WITH_MITM);
45+ bleuart.begin ();
46+
1847}
1948
2049void SerialBLEInterface::startAdv () {
21- Bluefruit.Advertising .stop (); // always clean restart
50+
51+ BLE_DEBUG_PRINTLN (" SerialBLEInterface: starting advertising" );
52+
53+ // clean restart if already advertising
54+ if (Bluefruit.Advertising .isRunning ()){
55+ BLE_DEBUG_PRINTLN (" SerialBLEInterface: already advertising, stopping to allow clean restart" );
56+ Bluefruit.Advertising .stop ();
57+ }
58+
2259 Bluefruit.Advertising .clearData (); // clear advertising data
2360 Bluefruit.ScanResponse .clearData (); // clear scan response data
2461
@@ -42,10 +79,25 @@ void SerialBLEInterface::startAdv() {
4279 * For recommended advertising interval
4380 * https://developer.apple.com/library/content/qa/qa1931/_index.html
4481 */
45- Bluefruit.Advertising .restartOnDisconnect (false ); // don't restart automatically as already beeing done in checkRecvFrame()
82+ Bluefruit.Advertising .restartOnDisconnect (false ); // don't restart automatically as we handle it in onDisconnect
4683 Bluefruit.Advertising .setInterval (32 , 244 ); // in unit of 0.625 ms
4784 Bluefruit.Advertising .setFastTimeout (30 ); // number of seconds in fast mode
48- Bluefruit.Advertising .start (0 ); // 0 = Don't stop advertising after n seconds
85+ Bluefruit.Advertising .start (0 ); // 0 = Don't stop advertising after n seconds
86+
87+ }
88+
89+ void SerialBLEInterface::stopAdv () {
90+
91+ BLE_DEBUG_PRINTLN (" SerialBLEInterface: stopping advertising" );
92+
93+ // we only want to stop advertising if it's running, otherwise an invalid state error is logged by ble stack
94+ if (!Bluefruit.Advertising .isRunning ()){
95+ return ;
96+ }
97+
98+ // stop advertising
99+ Bluefruit.Advertising .stop ();
100+
49101}
50102
51103// ---------- public methods
@@ -56,25 +108,14 @@ void SerialBLEInterface::enable() {
56108 _isEnabled = true ;
57109 clearBuffers ();
58110
59- // Configure and start the BLE Uart service
60- bleuart.setPermission (SECMODE_ENC_WITH_MITM, SECMODE_ENC_WITH_MITM);
61- bleuart.begin ();
62-
63111 // Start advertising
64112 startAdv ();
65-
66- checkAdvRestart = false ;
67113}
68114
69115void SerialBLEInterface::disable () {
70116 _isEnabled = false ;
71-
72117 BLE_DEBUG_PRINTLN (" SerialBLEInterface::disable" );
73-
74- Bluefruit.Advertising .stop ();
75-
76- oldDeviceConnected = deviceConnected = false ;
77- checkAdvRestart = false ;
118+ stopAdv ();
78119}
79120
80121size_t SerialBLEInterface::writeFrame (const uint8_t src[], size_t len) {
@@ -83,7 +124,7 @@ size_t SerialBLEInterface::writeFrame(const uint8_t src[], size_t len) {
83124 return 0 ;
84125 }
85126
86- if (deviceConnected && len > 0 ) {
127+ if (_isDeviceConnected && len > 0 ) {
87128 if (send_queue_len >= FRAME_QUEUE_SIZE) {
88129 BLE_DEBUG_PRINTLN (" writeFrame(), send_queue is full!" );
89130 return 0 ;
@@ -119,44 +160,14 @@ size_t SerialBLEInterface::checkRecvFrame(uint8_t dest[]) {
119160 } else {
120161 int len = bleuart.available ();
121162 if (len > 0 ) {
122- deviceConnected = true ; // should probably use the callback to monitor cx
123163 bleuart.readBytes (dest, len);
124164 BLE_DEBUG_PRINTLN (" readBytes: sz=%d, hdr=%d" , len, (uint32_t ) dest[0 ]);
125165 return len;
126166 }
127167 }
128-
129- if (Bluefruit.connected () == 0 ) deviceConnected = false ;
130-
131- if (deviceConnected != oldDeviceConnected) {
132- if (!deviceConnected) { // disconnecting
133- clearBuffers ();
134-
135- BLE_DEBUG_PRINTLN (" SerialBLEInterface -> disconnecting..." );
136- delay (500 ); // give the bluetooth stack the chance to get things ready
137-
138- checkAdvRestart = true ;
139- } else {
140- BLE_DEBUG_PRINTLN (" SerialBLEInterface -> stopping advertising" );
141- BLE_DEBUG_PRINTLN (" SerialBLEInterface -> connecting..." );
142- // connecting
143- // do stuff here on connecting
144- Bluefruit.Advertising .stop ();
145- checkAdvRestart = false ;
146- }
147- oldDeviceConnected = deviceConnected;
148- }
149-
150- if (checkAdvRestart) {
151- if (Bluefruit.connected () == 0 ) {
152- BLE_DEBUG_PRINTLN (" SerialBLEInterface -> re-starting advertising" );
153- startAdv ();
154- }
155- checkAdvRestart = false ;
156- }
157168 return 0 ;
158169}
159170
160171bool SerialBLEInterface::isConnected () const {
161- return deviceConnected; // pServer != NULL && pServer->getConnectedCount() > 0 ;
172+ return _isDeviceConnected ;
162173}
0 commit comments