Samo Penic
2022-05-20 3e4d4c2df4f4be8447ce268f4de0688610c0bbda
commit | author | age
e0a3ca 1
SP 2 /** NimBLE_Server Demo:
3  *
4  *  Demonstrates many of the available features of the NimBLE client library.
5  *
6  *  Created: on March 24 2020
7  *      Author: H2zero
8  *
9 */
10
11 #include <NimBLEDevice.h>
12
13 void scanEndedCB(NimBLEScanResults results);
14
15 static NimBLEAdvertisedDevice* advDevice=nullptr;
16
17 static bool doConnect = false;
18 static uint32_t scanTime = 0; /** 0 = scan forever */
19 static NimBLEClient* BTClient=nullptr;
20 NimBLERemoteCharacteristic* BTChr = nullptr;
21
22 /** Define a class to handle the callbacks when advertisments are received */
23 class AdvertisedDeviceCallbacks: public NimBLEAdvertisedDeviceCallbacks {
24
25     void onResult(NimBLEAdvertisedDevice* advertisedDevice) {
26 //        Serial.print("Advertised Device found: ");
27 //        Serial.println(advertisedDevice->toString().c_str());
28         if(advertisedDevice->isAdvertisingService(NimBLEUUID("DEAD")))
29         {
30 //            Serial.println("Found Our Service");
31             /** stop scan before connecting */
32             NimBLEDevice::getScan()->stop();
33             /** Save the device reference in a global for the client to use*/
34             advDevice = advertisedDevice;
35             /** Ready to connect now */
36             doConnect = true;
37         }
38     };
39 };
40
41
42
43
44 /** Callback to process the results of the last scan or restart it */
45 void scanEndedCB(NimBLEScanResults results){
46 //    Serial.println("Scan Ended");
47 }
48
49
50 /** Handles the provisioning of clients and connects / interfaces with the server */
51 bool connectToServer() {
52     NimBLEClient* pClient = nullptr;
53
54     /** Check if we have a client we should reuse first **/
55     if(NimBLEDevice::getClientListSize()) {
56         /** Special case when we already know this device, we send false as the
57          *  second argument in connect() to prevent refreshing the service database.
58          *  This saves considerable time and power.
59          */
60         pClient = NimBLEDevice::getClientByPeerAddress(advDevice->getAddress());
61         if(pClient){
62             if(!pClient->connect(advDevice, false)) {
63   //              Serial.println("Reconnect failed");
64                 return false;
65             }
66  //           Serial.println("Reconnected client");
67         }
68         /** We don't already have a client that knows this device,
69          *  we will check for a client that is disconnected that we can use.
70          */
71         else {
72             pClient = NimBLEDevice::getDisconnectedClient();
73         }
74     }
75
76     /** No client to reuse? Create a new one. */
77     if(!pClient) {
78         if(NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS) {
79 //            Serial.println("Max clients reached - no more connections available");
80             return false;
81         }
82
83         pClient = NimBLEDevice::createClient();
84
85 //        Serial.println("New client created");
86
87 //        pClient->setClientCallbacks(&clientCB, false);
88         /** Set initial connection parameters: These settings are 15ms interval, 0 latency, 120ms timout.
89          *  These settings are safe for 3 clients to connect reliably, can go faster if you have less
90          *  connections. Timeout should be a multiple of the interval, minimum is 100ms.
91          *  Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 51 * 10ms = 510ms timeout
92          */
93         pClient->setConnectionParams(12,12,0,51);
94         /** Set how long we are willing to wait for the connection to complete (seconds), default is 30. */
95         pClient->setConnectTimeout(5);
96
97
98         if (!pClient->connect(advDevice)) {
99             /** Created a client but failed to connect, don't need to keep it as it has no data */
100             NimBLEDevice::deleteClient(pClient);
101   //          Serial.println("Failed to connect, deleted client");
102             return false;
103         }
104     }
105
106     if(!pClient->isConnected()) {
107         if (!pClient->connect(advDevice)) {
108 //            Serial.println("Failed to connect");
109             return false;
110         }
111     }
112
113   //  Serial.print("Connected to: ");
114   //  Serial.println(pClient->getPeerAddress().toString().c_str());
115  //   Serial.print("RSSI: ");
116  //   Serial.println(pClient->getRssi());
117
118     /** Now we can read/write/subscribe the charateristics of the services we are interested in */
119     NimBLERemoteService* pSvc = nullptr;
120     NimBLERemoteCharacteristic* pChr = nullptr;
121     NimBLERemoteDescriptor* pDsc = nullptr;
122     BTClient = NimBLEDevice::getClientByPeerAddress(advDevice->getAddress());
123     pSvc = pClient->getService("DEAD");
124     if(pSvc) {     /** make sure it's not null */
125         pChr = pSvc->getCharacteristic("BEEF");
126         BTChr = pSvc->getCharacteristic("BEEF");
127         if(pChr) {     /** make sure it's not null */
128             if(pChr->canRead()) {
129         //        Serial.print(pChr->getUUID().toString().c_str());
130         //        Serial.print(" Value: ");
131         //        Serial.println(pChr->readValue().c_str());
132             }
133
134         }
135
136     } else {
137 //        Serial.println("DEAD service not found.");
138     }
139
140
141 //    Serial.println("Done with this device!");
142     return true;
143 }
144
145 void setup (){
146     Serial.begin(115200);
147 //    Serial.println("Starting NimBLE Client");
148     /** Initialize NimBLE, no device name spcified as we are not advertising */
149     NimBLEDevice::init("");
150
151     /** Set the IO capabilities of the device, each option will trigger a different pairing method.
152      *  BLE_HS_IO_KEYBOARD_ONLY    - Passkey pairing
153      *  BLE_HS_IO_DISPLAY_YESNO   - Numeric comparison pairing
154      *  BLE_HS_IO_NO_INPUT_OUTPUT - DEFAULT setting - just works pairing
155      */
156     //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_KEYBOARD_ONLY); // use passkey
157     //NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_YESNO); //use numeric comparison
158
159     /** 2 different ways to set security - both calls achieve the same result.
160      *  no bonding, no man in the middle protection, secure connections.
161      *
162      *  These are the default values, only shown here for demonstration.
163      */
164     //NimBLEDevice::setSecurityAuth(false, false, true);
165     NimBLEDevice::setSecurityAuth(/*BLE_SM_PAIR_AUTHREQ_BOND | BLE_SM_PAIR_AUTHREQ_MITM |*/ BLE_SM_PAIR_AUTHREQ_SC);
166
167     /** Optional: set the transmit power, default is 3db */
168     NimBLEDevice::setPower(ESP_PWR_LVL_P9); /** +9db */
169
170     /** Optional: set any devices you don't want to get advertisments from */
171     // NimBLEDevice::addIgnored(NimBLEAddress ("aa:bb:cc:dd:ee:ff"));
172
173     /** create new scan */
174     NimBLEScan* pScan = NimBLEDevice::getScan();
175
176     /** create a callback that gets called when advertisers are found */
177     pScan->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallbacks());
178
179     /** Set scan interval (how often) and window (how long) in milliseconds */
180     pScan->setInterval(45);
181     pScan->setWindow(15);
182
183     /** Active scan will gather scan response data from advertisers
184      *  but will use more energy from both devices
185      */
186     pScan->setActiveScan(true);
187     /** Start scanning for advertisers for the scan time specified (in seconds) 0 = forever
188      *  Optional callback for when scanning stops.
189      */
190     pScan->start(scanTime, scanEndedCB);
191
192 }
193
194
195 void loop (){
196     /** Loop here until we find a device we want to connect to */
197     while(!doConnect){
198       if(BTClient){
199         Serial.print(millis());
200         Serial.print(": "); 
201          Serial.println( (int)(BTChr->readValue().data()[0]));
202                   }
203              //Serial.println(millis());     
204         delay(10);
205     }
206    
207     doConnect = false;
208     connectToServer();
209     
210   //  NimBLEDevice::getScan()->start(scanTime,scanEndedCB);
211 }