13#include <NimBLEDevice.h>
14#include "../../Defines.h"
31static NimBLERemoteCharacteristic* _BLEClientCharacteristicFeed;
36static NimBLEAdvertisedDevice* _advertisedDevice;
38static bool _doConnect =
false;
39static bool _isConnected_BLEClient =
false;
58 SerialTemp.print(
"set skipAddress: ");
59 SerialTemp.println(nameOrAddress);
79 SerialTemp.printf(
"containsSkipAddress(%d): ", flag);
80 SerialTemp.print(deviceInfo);
81 SerialTemp.print(
" skip=");
90 void onConnect(NimBLEClient* pClient) {
92 SerialMin.println(
" BLE Connected");
107 pClient->updateConnParams(120, 120, 0, 60);
111 _isConnected_BLEClient =
true;
114 void onDisconnect(NimBLEClient* pClient) {
118 SerialMin.println(
" BLE Disconnected - Starting scan");
119 SerialMin.print(pClient->getPeerAddress().toString().c_str());
127 SerialMin.println(
"*** in OTA update . no scanning ***");
132 _isConnected_BLEClient =
false;
139 bool onConnParamsUpdateRequest(NimBLEClient* pClient,
const ble_gap_upd_params* params) {
141 SerialMin.println(
" onConnParamsUpdateRequest");
142 if (params->itvl_min < 24) {
145 else if (params->itvl_max > 40) {
148 else if (params->latency > 2) {
151 else if (params->supervision_timeout > 100) {
160 uint32_t onPassKeyRequest() {
161 SerialLots.println(
"Client Passkey Request");
166 bool onConfirmPIN(uint32_t pass_key) {
167 SerialLots.print(
"The passkey YES/NO number: ");
168 SerialLots.println(pass_key);
174 void onAuthenticationComplete(ble_gap_conn_desc* desc) {
175 if (!desc->sec_state.encrypted) {
176 SerialDebug.println(
"Encrypt connection failed - disconnecting");
178 NimBLEDevice::getClientByID(desc->conn_handle)->disconnect();
181 _isConnected_BLEClient =
false;
191 void onResult(NimBLEAdvertisedDevice* advertisedDevice) {
192 SerialLots.printf(
" *** onResult adv, useBLEClient = %d\n",
useBLEClient());
200 SerialLots.print(
"BLE Devices Advertised: ");
201 SerialLots.println(advertisedDevice->toString().c_str());
203 String deviceInfo = advertisedDevice->toString().c_str();
207 boolean foundGEN3 =
false;
210 if (advertisedDevice->isAdvertisingService(NimBLEUUID(
"DEAD")))
212 SerialMin.print(
"Device advertised: ");
213 SerialMin.println(advertisedDevice->getName().c_str());
214 SerialLots.print(
"Device URI: ");
215 SerialLots.println(advertisedDevice->getURI().c_str());
219 if (
getDiscoverM5PTClicker() && (strncmp(advertisedDevice->getName().c_str(), M5_BLE_CLIENT_SERVICE, strlen(M5_BLE_CLIENT_SERVICE)) == 0))
221 SerialDebug.printf(
"** DiscoverM5PTClicker && Found a PTCLICKER .. go for it.. %w\n",advertisedDevice->getName().c_str() );
226 SerialDebug.printf(
"** DiscoverM5PTClicker && **** ESP32 Feeder (%s) but not 'PTClicker M5' skipping..\n", advertisedDevice->getName().c_str());
229 else if (strncmp(advertisedDevice->getName().c_str(), MAIN_BLE_CLIENT_SERVICE, strlen(MAIN_BLE_CLIENT_SERVICE)) != 0)
231 SerialDebug.printf(
" **** ESP32 Feeder (%s) but not 'PTFeeder' skipping..\n", advertisedDevice->getName().c_str());
236 else if (advertisedDevice->isAdvertisingService(NimBLEUUID(_BLEClientServiceUUID)) || (deviceInfo.indexOf(
PT_SERVICE_UUID) > 0))
239 SerialDebug.println(
" **** Found a GEN3 Device");
242 if (requireGEN3 and !foundGEN3)
244 SerialDebug.println(
" **** Looking for GEN3 but didn't find it .. so not connecting");
249 if (advertisedDevice->isAdvertisingService(NimBLEUUID(_BLEClientServiceUUID)) || (deviceInfo.indexOf(
PT_SERVICE_UUID) > 0))
251 SerialTemp.println(
"Found candidate BLE Service: ");
252 SerialTemp.println(advertisedDevice->toString().c_str());
253 String deviceInfo = advertisedDevice->toString().c_str();
263 SerialTemp.print(
"Found device, but skip is max .. so connect");
271 SerialTemp.print(
"Found device, but will skip as it contains nameOrAddress: ");
296#ifdef NO_MORE_PREFERENCE_BLE_USE_DISCOVERED_PAIRED_DEVICE_SETTING
311 boolean found =
false;
318 SerialTemp.printf(
" containsSubstring(%d, %s)\n", found, pairedDeviceName);
326 SerialTemp.printf(
" containsSubstring(%d, '%s')\n", found, pairedDeviceAddress);
328 if (!found && foundGEN3 && strlen(pairedDeviceAddress)==0)
331 SerialTemp.printf(
" no paired address but a GEN3 so good(%d)\n", found);
337 SerialTemp.println(
"*** FOUND GEN3 PAIRED Device Name: ");
339 SerialTemp.println(
"*** FOUND BLE PAIRED Device Name: ");
341 SerialTemp.println(pairedDeviceName);
346 SerialTemp.println(
" *** Nothing paired ****");
351 SerialTemp.print(
"Not matching desired device name: '");
353 SerialTemp.print(
"' .. or address: ");
367 NimBLEDevice::getScan()->stop();
369 _advertisedDevice = advertisedDevice;
378void notifyCB(NimBLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData,
size_t length,
bool isNotify) {
379#if (SERIAL_DEBUG_DEBUG)
380 std::string str = (isNotify ==
true) ?
"Notification" :
"Indication";
383 str += std::string(pRemoteCharacteristic->getRemoteService()->getClient()->getPeerAddress());
384 str +=
": Service = " + std::string(pRemoteCharacteristic->getRemoteService()->getUUID());
385 str +=
", Characteristic = " + std::string(pRemoteCharacteristic->getUUID());
386 str +=
", Value = " + std::string((
char*)pData, length);
387 SerialDebug.println(str.c_str());
394 SerialLots.println(
"Scan Ended");
403 SerialCall.println(
"connectToServer_BLEClient");
404 NimBLEClient* pClient =
nullptr;
406 if (NimBLEDevice::getClientListSize()) {
411 pClient = NimBLEDevice::getClientByPeerAddress(_advertisedDevice->getAddress());
413 if (!pClient->connect(_advertisedDevice,
false)) {
414 SerialLots.println(
"Reconnect failed");
417 SerialDebug.println(
"Reconnected pClient");
424 pClient = NimBLEDevice::getDisconnectedClient();
427 SerialLots.printf(
"Reusing a disconnected pClient: %s\n",pClient? pClient->getPeerAddress().toString().c_str():
"NULL");
436#ifdef ONLY_DIFFERENCE_FROM_WORKING_VERSION
437 if (NimBLEDevice::getClientListSize() >= NIMBLE_MAX_CONNECTIONS)
439 if (NimBLEDevice::getClientListSize() >= 1 )
446 pClient = NimBLEDevice::createClient();
448 SerialDebug.printf(
"***New client created(%d)\n", pClient);
450 pClient->setClientCallbacks(&_clientCB_BLEClient,
false);
467 pClient->setConnectionParams(12, 12, 0, 51);
471 pClient->setConnectTimeout(5);
472 Serial.printf(
"pClient=%d\n",pClient);
473 if (!_advertisedDevice)
475 SerialMin.println(
" **** ERROR: advertisedDevice == NULL");
478 Serial.printf(
"_advertisedDevice=%d\n",_advertisedDevice);
480 if (!pClient->connect(_advertisedDevice)) {
483 NimBLEDevice::deleteClient(pClient);
484 SerialDebug.println(
"Failed to connect, deleted client");
492 if (!pClient->isConnected()) {
493 if (!pClient->connect(_advertisedDevice)) {
494 SerialDebug.println(
"Failed to connect");
497 _isConnected_BLEClient =
false;
503 SerialLots.printf(
"number clients= %d \n\r", NimBLEDevice::getClientListSize());
505 SerialMin.print(
" - Connected to pClient: ");
506 SerialMin.println(pClient->getPeerAddress().toString().c_str());
507 SerialLots.print(
"RSSI: ");
508 SerialLots.println(pClient->getRssi());
511 NimBLERemoteService* pSvc =
nullptr;
512 NimBLERemoteCharacteristic* pChr =
nullptr;
513 NimBLERemoteDescriptor* pDsc =
nullptr;
517 pSvc = pClient->getService(
"DEAD");
521 SerialTemp.printf(
"*** v2.0 This is an ESP Based Feeder (not GEN3)***\n");
529 SerialTemp.println(
"*** v2.0 This is an GEN3 Feeder (not ESP32)***");
538 pSvc = pClient->getService(_BLEClientServiceUUID);
541 pChr = pSvc->getCharacteristic(_BLEClientCharacteristicUUID);
542 _BLEClientCharacteristicFeed = pChr;
545 SerialLots.println(
" **** BLEClientNetworking is nil in creation...");
551 SerialLots.print(pChr->getUUID().toString().c_str());
552 SerialLots.print(
" Value: ");
553 SerialLots.println(pChr->readValue().c_str());
558#ifdef DO_IT_ANOTHER_WAY_WITHOUT_SENDING_VALUE
559 String sentValue =
"_ESP_32";
561 if (pChr->canWrite())
565 if (pChr->writeValue(sentValue)) {
567 SerialDebug.print(
"Wrote new value(1) to: ");
568 SerialDebug.println(pChr->getUUID().toString().c_str());
569 SerialDebug.printf(
"'%s'\n", sentValue);
573 SerialDebug.println(
"Disconnecting if write failed");
575 pClient->disconnect();
583 SerialDebug.print(
"The value(1) of: ");
584 SerialDebug.print(pChr->getUUID().toString().c_str());
585 SerialDebug.print(
" is now: '");
586 SerialDebug.print(pChr->readValue().c_str());
587 SerialDebug.println(
"'");
588 if (sentValue.compareTo(pChr->readValue().c_str()) == 0)
591 SerialTemp.printf(
"*** This is an ESP Based Feeder (not GEN3)***\n");
599 SerialTemp.println(
"*** This is an GEN3 Feeder (not ESP32)***");
614 if (pChr->canNotify())
617 if (!pChr->subscribe(
true,
notifyCB)) {
619 pClient->disconnect();
624 else if (pChr->canIndicate())
629 if (!pChr->subscribe(
false,
notifyCB))
632 pClient->disconnect();
641 SerialLots.println(
"DEAD service not found.");
656 SerialDebug.print(pChr->getUUID().toString().c_str());
657 SerialDebug.print(
" Value: ");
658 SerialDebug.println(pChr->readValue().c_str());
670#ifdef NOT_USED_FOR_SOME_REASON
671 pDsc = pChr->getDescriptor(NimBLEUUID(
"C01D"));
673 SerialDebug.println(
" .. DOESNT GET HERE");
677 SerialDebug.print(
"Descriptor: ");
678 SerialDebug.print(pDsc->getUUID().toString().c_str());
679 SerialDebug.print(
" Value: ");
680 SerialDebug.println(pDsc->readValue().c_str());
682 SerialDebug.println(
" .. 111");
684 if (pChr->canWrite())
686 if (pChr->writeValue(
"No tip!")) {
687 SerialDebug.print(
"Wrote new value(2) to: ");
688 SerialDebug.println(pChr->getUUID().toString().c_str());
692 pClient->disconnect();
696 if (pChr->canRead()) {
697 SerialDebug.print(
"The value(2) of: ");
698 SerialDebug.print(pChr->getUUID().toString().c_str());
699 SerialDebug.print(
" is now: ");
700 SerialDebug.println(pChr->readValue().c_str());
703 SerialDebug.println(
" .. 222");
709 if (pChr->canNotify()) {
711 if (!pChr->subscribe(
true,
notifyCB)) {
713 pClient->disconnect();
717 else if (pChr->canIndicate()) {
720 if (!pChr->subscribe(
false,
notifyCB)) {
722 pClient->disconnect();
726 SerialDebug.println(
" .. 333");
732 SerialLots.println(
"BAAD service not found.");
735 SerialDebug.println(
"Done with this device!");
746 boolean isConnected = _isConnected_BLEClient;
748 SerialLots.printf(
"isConnectedBLEClient: %d\n",isConnected);
755 SerialLots.println(
"sendFeedCommandBLEClient()");
759 std::string newValue =
"s";
760 const uint8_t newValueFeed = { 0x00 };
761 if (!_BLEClientCharacteristicFeed)
763 SerialLots.println(
" **** Error _BLEClientCharacteristicFeed is nil ***");
766 if (_BLEClientCharacteristicFeed->writeValue(newValueFeed, 1)) {
767 SerialMin.print(
"BLEClient writeValue: '");
768 SerialMin.print(newValue.c_str());
769 SerialMin.println(
"' - sent FEED");
785 SerialDebug.print(newValue.c_str());
786 SerialDebug.println(
"FAILED GATT write(1)");
793 if (_BLEClientCharacteristicFeed->canRead()) {
794 std::string value = _BLEClientCharacteristicFeed->readValue();
795 SerialTemp.printf(
"BLE Server response: '%s'\n",(value[0]==0x01)?(
char*)
"01":(
char*)
"");
798 if (value[0] == 0x01) {
813 SerialDebug.println(
"Didn't get a response 0x01");
833 SerialDebug.print(
"sendCommandBLEClient(");
834 SerialDebug.print(cmdString.length());
835 SerialDebug.print(
"): '");
836 SerialDebug.print(cmdString);
837 SerialDebug.print(
"' gateway=");
839 SerialDebug.println(isGatewayGEN3?
"gen3":
"esp32");
844 if (cmdString.length() > 0)
846 SerialDebug.println(
" *** GEN3 and command longer than 1 character .. not sending");
855 int len = cmdString.length();
856 String startCmd =
"#MSG_START";
859 for (
int i = 0; i < len;i+=13)
862 if (start + 13 > cmdString.length())
863 s = cmdString.substring(start);
865 s = cmdString.substring(start,start+13);
874 String endCmd =
"#MSG_END";
881 SerialDebug.print(
"sendCommandBLEClient13(");
882 SerialDebug.print(cmdString.length());
883 SerialDebug.print(
"): '");
884 SerialDebug.print(cmdString);
885 SerialDebug.println(
"'");
892 if (!_BLEClientCharacteristicFeed)
894 SerialDebug.println(
" **** Error _BLEClientCharacteristicFeed is nil ***");
897 if (_BLEClientCharacteristicFeed->writeValue(cmdString, cmdString.length()),
true) {
898 SerialDebug.print(
"writeValue:");
899 SerialDebug.println(cmdString.c_str());
903 SerialDebug.print(cmdString.c_str());
904 SerialDebug.println(
"FAILED GATT write(2)");
911 if (_BLEClientCharacteristicFeed->canRead()) {
912 std::string value = _BLEClientCharacteristicFeed->readValue();
913 SerialLots.print(
"BLE Server response: '");
914 SerialLots.print(value.c_str()); SerialDebug.println(
"'");
915 if (value[0] == 0x01) {
930 SerialDebug.println(
"Didn't get a response 0x01");
948 SerialDebug.println(
"Starting NimBLE BLEClientNetworking");
950 NimBLEDevice::init(
"");
974 NimBLEDevice::setSecurityAuth( BLE_SM_PAIR_AUTHREQ_SC);
977 NimBLEDevice::setPower(ESP_PWR_LVL_P9);
983 NimBLEScan* pScan = NimBLEDevice::getScan();
999 pScan->setActiveScan(
true);
1011 SerialDebug.println(
"calling _pClient->disconnect()");
1018 _isConnected_BLEClient =
false;
1021 SerialDebug.println(
"DONE calling _pClient->disconnect()");
1034 _isConnected_BLEClient =
false;
1050 if (_doConnect ==
true) {
1051 SerialLots.println(
"_doConnect == true");
1053 SerialDebug.println(
"!! Connected to BLE Server.");
1063#ifdef DONT_USE_ONLY_ONE_CONNECTED
1064 SerialDebug.println(
"We have failed to connect to the server; there is nothin more we will do.");
int _skipAddressCount
skip logic
char _skipNameOrAddress_BLEClientNetworking[50]
address to skip (for a number of times) .. how about 1 for now..
void loop_BLEClientNetworking()
the loop()
bool connectToServer_BLEClient()
void sendCommandBLEClient(String cmdString)
void stopSkip_BLEClientNetworking()
stops the skip after found something..
boolean isConnectedBLEClient()
returns whether connected over BLE as a client to a server(like a ESP feeder)
void scanEndedCB_BLEClient(NimBLEScanResults results)
NOTE: this is called all the time... 4.22.22 –even if the "scan-stop" invoked.
void sendFeedCommandBLEClient()
sends the "feed" command over bluetooth to the connected device..
void notifyCB(NimBLERemoteCharacteristic *pRemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify)
boolean useBLEClient()
returns if the BLEClient is turned on.. note, if connected to a BLE device, then disconnect
void setup_BLEClientNetworking(char *serviceName, char *serviceUUID, char *characteristicUUID)
the setup() and loop() passing the serviceName to look for..
void disconnect_BLEClientNetworking()
try to disconnect..
void skipNameOrAddress_BLEClientNetworking(char *nameOrAddress)
an address or name to skip (for at least 1 time)
boolean containsSkipAddress(String deviceInfo)
helper for skip, checking if an actuall address in the skip name or address
void sendCommandBLEClient_13orLess(String cmdString)
send a string of 13 characters or less
#define PSCAN_INTERVAL
https://esp32.com/viewtopic.php?t=2291
#define BLE_CLIENT_CALLBACK_BLINK_LIGHT
the BLE code wants to blink the light
#define BLE_CLIENT_CALLBACK_STATUS_MESSAGE
used to send a string message back (which might be sent to MQTT for example)
void setConnectedBLEDevice_mainModule(char *deviceName, boolean isGEN3)
boolean stopAllProcesses_mainModule()
if stopped
bool containsSubstring(String message, String substring)
check if the string contains the other string. This is a poor man's grammer checker
void callCallbackMain(int callbacksModuleId, int callbackType, char *message)
performs the indirect callback based on the callbackType
#define CALLBACKS_BLE_CLIENT
int getTimeStamp_mainModule()
boolean isValidPairedDevice_mainModule()
returns if the paired device is not NONE. Note, the paired Name might be an address now (see below)
#define PT_CHARACTERISTIC_UUID
boolean getDiscoverM5PTClicker()
get option
void savePreferenceBoolean_mainModule(int preferenceID, boolean flag)
save a boolean preference
boolean getPreferenceBoolean_mainModule(int preferenceID)
called to set a preference (which will be an identifier and a string, which can be converted to a num...
char * getPreferenceString_mainModule(int preferenceID)
returns the preference but in it's own string buffer. As long as you use it before calling getPrefere...
#define PREFERENCE_PAIRED_DEVICE_ADDRESS_SETTING
the paired device for guest device feeding (6.6.22) .. but the Address 9.3.22
#define PREFERENCE_ONLY_GEN3_CONNECT_SETTING
if true, only BLEClient connect to GEN3 feeders..
#define PREFERENCE_PAIRED_DEVICE_SETTING
the paired device for guest device feeding (6.6.22)
#define PREFERENCE_MAIN_GATEWAY_VALUE
#define PREFERENCE_MAIN_BLE_CLIENT_VALUE