11#include " AgWiFiConnector.h"
2+ #include " Arduino.h"
23#include " Libraries/WiFiManager/WiFiManager.h"
34
45#define WIFI_CONNECT_COUNTDOWN_MAX 180
56#define WIFI_HOTSPOT_PASSWORD_DEFAULT " cleanair"
67
78#define WIFI () ((WiFiManager *)(this ->wifi))
89
10+ static bool g_isBLEConnect = false ;
11+
12+
13+ class ServerCallbacks : public NimBLEServerCallbacks {
14+ void onConnect (NimBLEServer *pServer, NimBLEConnInfo &connInfo) override {
15+ Serial.printf (" Client address: %s\n " , connInfo.getAddress ().toString ().c_str ());
16+ g_isBLEConnect = true ;
17+ }
18+
19+ void onDisconnect (NimBLEServer *pServer, NimBLEConnInfo &connInfo, int reason) override {
20+ Serial.printf (" Client disconnected - start advertising\n " );
21+ NimBLEDevice::startAdvertising ();
22+ g_isBLEConnect = false ;
23+ }
24+
25+ void onAuthenticationComplete (NimBLEConnInfo &connInfo) override {
26+ Serial.println (" \n ========== PAIRING COMPLETE ==========" );
27+ Serial.printf (" Peer Address: %s\n " , connInfo.getAddress ().toString ().c_str ());
28+
29+ Serial.printf (" Encrypted: %s\n " , connInfo.isEncrypted () ? " YES" : " NO" );
30+ Serial.printf (" Authenticated: %s\n " , connInfo.isAuthenticated () ? " YES" : " NO" );
31+ Serial.printf (" Key Size: %d bits\n " , connInfo.getSecKeySize () * 8 );
32+
33+ Serial.println (" ======================================\n " );
34+ }
35+ };
36+
37+ /* * Handler class for characteristic actions */
38+ class CharacteristicCallbacks : public NimBLECharacteristicCallbacks {
39+ void onRead (NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo) override {
40+ Serial.printf (" %s : onRead(), value: %s\n " , pCharacteristic->getUUID ().toString ().c_str (),
41+ pCharacteristic->getValue ().c_str ());
42+ }
43+
44+ void onWrite (NimBLECharacteristic *pCharacteristic, NimBLEConnInfo &connInfo) override {
45+ Serial.printf (" %s : onWrite(), value: %s\n " , pCharacteristic->getUUID ().toString ().c_str (),
46+ pCharacteristic->getValue ().c_str ());
47+ }
48+ };
49+
950/* *
1051 * @brief Set reference AirGradient instance
1152 *
@@ -101,6 +142,11 @@ bool WifiConnector::connect(void) {
101142 [](void *obj) {
102143 WifiConnector *connector = (WifiConnector *)obj;
103144 while (connector->_wifiConfigPortalActive ()) {
145+ if (g_isBLEConnect) {
146+ Serial.println (" Stopping portal because BLE connected" );
147+ connector->_wifiStop ();
148+ break ;
149+ }
104150 connector->_wifiProcess ();
105151 vTaskDelay (1 );
106152 }
@@ -113,9 +159,11 @@ bool WifiConnector::connect(void) {
113159 uint32_t ledPeriod = millis ();
114160 bool clientConnectChanged = false ;
115161
162+ setupBLE ();
163+
116164 AgStateMachineState stateOld = sm.getDisplayState ();
117165 while (WIFI ()->getConfigPortalActive ()) {
118- /* * LED animatoin and display update content */
166+ /* * LED animation and display update content */
119167 if (WiFi.isConnected () == false ) {
120168 /* * Display countdown */
121169 uint32_t ms;
@@ -145,6 +193,8 @@ bool WifiConnector::connect(void) {
145193 clientConnectChanged = clientConnected;
146194 if (clientConnectChanged) {
147195 sm.handleLeds (AgStateMachineWiFiManagerPortalActive);
196+ Serial.println (" Stopping BLE since wifi is connected" );
197+ stopBLE ();
148198 } else {
149199 sm.ledAnimationInit ();
150200 sm.handleLeds (AgStateMachineWiFiManagerMode);
@@ -161,6 +211,26 @@ bool WifiConnector::connect(void) {
161211 _wifiProcess ();
162212#endif
163213
214+ while (1 ) {
215+ delay (1000 );
216+ }
217+
218+
219+ /* * Set wifi connect */
220+ WiFi.begin (" hbonfam" , " 51burian" );
221+
222+ /* * Wait for wifi connect to AP */
223+ int count = 0 ;
224+ while (WiFi.status () != WL_CONNECTED) {
225+ delay (1000 );
226+ count++;
227+ if (count >= 15 ) {
228+ logError (" Try connect to default wifi \" " + String (this ->defaultSsid ) +
229+ String (" \" failed" ));
230+ break ;
231+ }
232+ }
233+
164234 /* * Show display wifi connect result failed */
165235 if (WiFi.isConnected () == false ) {
166236 sm.handleLeds (AgStateMachineWiFiManagerConnectFailed);
@@ -248,6 +318,10 @@ bool WifiConnector::_wifiConfigPortalActive(void) {
248318}
249319void WifiConnector::_wifiTimeoutCallback (void ) { connectorTimeout = true ; }
250320
321+ void WifiConnector::_wifiStop () {
322+ WIFI ()->stopConfigPortal ();
323+ }
324+
251325/* *
252326 * @brief Process WiFiManager connection
253327 *
@@ -411,3 +485,34 @@ bool WifiConnector::isConfigurePorttalTimeout(void) { return connectorTimeout; }
411485void WifiConnector::setDefault (void ) {
412486 WiFi.begin (" airgradient" , " cleanair" );
413487}
488+
489+
490+ void WifiConnector::setupBLE () {
491+ NimBLEDevice::init (" AirGradient" );
492+ NimBLEDevice::setPower (3 ); /* * +3db */
493+
494+ /* * bonding, MITM, don't need BLE secure connections as we are using passkey pairing */
495+ NimBLEDevice::setSecurityAuth (false , false , true );
496+ NimBLEDevice::setSecurityIOCap (BLE_HS_IO_NO_INPUT_OUTPUT);
497+
498+ NimBLEServer *pServer = NimBLEDevice::createServer ();
499+ pServer->setCallbacks (new ServerCallbacks ());
500+
501+ NimBLEService *pService = pServer->createService (" acbcfea8-e541-4c40-9bfd-17820f16c95c" );
502+ NimBLECharacteristic *pSecureCharacteristic =
503+ pService->createCharacteristic (" 703fa252-3d2a-4da9-a05c-83b0d9cacb8e" ,
504+ NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::READ_ENC |
505+ NIMBLE_PROPERTY::WRITE | NIMBLE_PROPERTY::WRITE_ENC);
506+ pSecureCharacteristic->setCallbacks (new CharacteristicCallbacks ());
507+
508+ pService->start ();
509+
510+ NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising ();
511+ pAdvertising->addServiceUUID (pService->getUUID ());
512+ pAdvertising->start ();
513+ }
514+
515+ void WifiConnector::stopBLE () {
516+ NimBLEDevice::deinit ();
517+
518+ }
0 commit comments