Closed greatwuu closed 4 years ago
I've researched for bd address and found this solution to convert char from myDevice->getAddress().toString().c_str() into byte array to use with esp_ble_gattc_cache_refresh() ` byte addr[6];
void parseBytes(const char str, char sep, byte bytes, int maxBytes, int base) { for (int i = 0; i < maxBytes; i++) { bytes[i] = strtoul(str, NULL, base); // Convert byte str = strchr(str, sep); // Find next separator if (str == NULL || *str == '\0') { break; // No more separators, exit } str++; // Point to next character after separator } }
//in other functions. const char* devAddr = myDevice->getAddress().toString().c_str(); parseBytes(devAddr, ':', addr, 6, 16); for(int i =0 ; i<5 ; i++){Serial.println(addr[i], HEX);} ` I only try to print into serial monitor and esp_ble_gattc_cache_refresh() but can't see any different cause I have no LOG show when running on esp32 but everything seems okay. need to try again when able to write byte array into the server to activate hidden characteristics.
esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda)
You have BLEAddress->native()
esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda)
You have BLEAddress->native()
Dear Chegewara,
Sorry for a nonsense question because I’m new to this BLE but what do you mean about
BLEAddress->native()
I did not understand it do I have to call this class to activate refresh function and now I’m still stuck with writing byte array to server characteristic. But when I’m write a byte array with nRF Connect everything work fine. If I can write with esp32 I’m also can test the refresh service function. Anyway thanks for your support.
Update!!!
Now I can write byte array to my device by using
pRemoteCharacteristic->writeValue(newValue,4, true);
Just add TRUE at the end of the command and it can be used!!!
I've read this issue https://github.com/nkolban/esp32-snippets/issues/382 Big thanks to chegewara and vcmorini.
Next I'll try to refresh a service by using esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda)
There is class BLEAddress. In that class you have function that will return value or pointer to value you need: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEAddress.h#L26
BLE_client:216:52: error: cannot convert 'uint8_t ()[6] {aka unsigned char ()[6]}' to 'uint8_t {aka unsigned char}' for argument '1' to 'esp_err_t esp_ble_gattc_cache_refresh(uint8_t*)'
esp_ble_gattc_cache_refresh(myAddress->getNative());
Hi, I edit my code then got this error message. When edit to *myAddress->getNative()
Got this error
10:33:07.942 -> Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. 10:33:07.942 -> Core 1 register dump: 10:33:07.942 -> PC : 0x4000c310 PS : 0x00060130 A0 : 0x800fc2b5 A1 : 0x3ffc8650 10:33:07.942 -> A2 : 0x3ffc8670 A3 : 0x00000000 A4 : 0x00000006 A5 : 0x3ffc8670 10:33:07.942 -> A6 : 0x3ffbedb0 A7 : 0x00000000 A8 : 0x00000000 A9 : 0x3ffc8650 10:33:07.942 -> A10 : 0x00000002 A11 : 0x3f4020ef A12 : 0x0000001f A13 : 0x0000ff00 10:33:07.942 -> A14 : 0x00ff0000 A15 : 0xff000000 SAR : 0x00000004 EXCCAUSE: 0x0000001c 10:33:07.975 -> EXCVADDR: 0x00000000 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff
esp_ble_gattc_cache_refresh((uint8_t*)myAddress->getNative());
or
esp_ble_gattc_cache_refresh((uint8_t*)&myAddress->getNative()[0]);
After trying code with your suggestion the same error occurs
0x400d2454: connectToServer() at D:\BLE_client/BLE_client.ino line 216 0x400d2f12: loop() at D:\BLE_client/BLE_client.ino line 440 0x400d8635: loopTask(void*) at C:\Users\parin\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32\main.cpp line 19 0x4008e089: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143 PC: 0x4000c310 EXCVADDR: 0x00000000
I'm using a decoder to traceback the error and found this. Now I'm trying to find a solution
I'd do some research and found that my result from exception decoder is LoadProhibited from address 0x00000000
But I don't know where to look for. By the way, I declared a BLEAddress class as
static BLEAddress* myAddress;
And use as
esp_ble_gattc_cache_refresh((uint8_t*)myAddress->getNative());
oresp_ble_gattc_cache_refresh((uint8_t*)&myAddress->getNative()[0]);
Is they have anything to do with this exception?
static BLEAddress* myAddress;
This in NULL, try that:
bleClient->getPeerAddress().getNative()
Thanks for your advice. Now it's looking good can compile and run but it seems to have no service refresh at all.
But now I'm stuck at refresh UUID. Can I use any other method to refresh server UUID? Anyways thanks you so much for your support.
Hey!, I read reference from
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_gattc.html#_CPPv424esp_ble_gattc_cb_param_t
I have a question, Did esp_bd_addr_tserver_bda
and esp_bd_addr_tremote_bda
is the same value
because in BLERemoteCharacteristic
class esp_ble_gattc_register_for_notify
can use esp_bd_addr_tserver_bda
as *m_pRemoteService->getClient()->getPeerAddress().getNative()
but when I try to use the same method nothing happen.
esp_ble_gattc_cache_refresh((uint8_t*)pRemoteService->getClient()->getPeerAddress().getNative());
Yes, its the same address.
Yes, its the same address.
Did a GATTC API different version or older version than the one on https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_gattc.html
Now, I add a
bool BLEClient::serviceRefresh() { esp_err_t errRc = esp_ble_gattc_cache_refresh(*getPeerAddress().getNative()); if (errRc != ESP_OK) { log_e("esp_ble_gattc_cache_refresh: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); return false; } else return true; }
and call this in main program. `if (pClient->serviceRefresh()){ pRemoteService = pClient->getService(serviceUUID2); if (pRemoteService == nullptr) { Serial.print("Failed to find our service UUID: "); Serial.println(serviceUUID.toString().c_str()); pClient->disconnect(); return false; }
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID6); if (pRemoteCharacteristic == nullptr) { Serial.print("Failed to find our characteristic UUID: "); Serial.println(charUUID6.toString().c_str()); pClient->disconnect(); return false; }`
It seems that refresh function return TRUE after execute but still can not get characteristic UUID before resetting a device
@greatwuu How did you solve this issue
@greatwuu How did you solve this issue
Hi Soth,
Now I have no device to review my previous code. I will review and get back to you later.
Sorry for late reply, I have checked my code and found that the server that I have connected to will updated the Services and Char UUID automatically and if it is not updated software will try to reconnect it. `bool connectToServer() { Serial.print("Forming a connection to "); strAddr = myDevice->getAddress().toString().c_str(); Serial.println(strAddr); BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT_MITM); pClient = BLEDevice::createClient(); Serial.println(" - Created client"); pClient->setClientCallbacks(new MyClientCallback());
pClient->connect(myDevice); Serial.println(" - Connected to server"); Serial.print(devName); Serial.print(" RSSI = "); Serial.println(RSSIvalue);
pRemoteService = pClient->getService(serviceUUID); if (pRemoteService == nullptr) { Serial.print("ERROR : Failed to find GENERIC ACCESS UUID: "); Serial.println(serviceUUID.toString().c_str()); pClient->disconnect(); return false; }
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID); if (pRemoteCharacteristic == nullptr) { Serial.print("ERROR : Failed to find DEVICE NAME UUID: "); Serial.println(charUUID.toString().c_str()); pClient->disconnect(); return false; } Serial.println(" - Device name"); // Read the value of the characteristic. if (pRemoteCharacteristic->canRead()) { std::string value = pRemoteCharacteristic->readValue(); devName = value.c_str(); Serial.println(value.c_str()); }
pRemoteService = pClient->getService(serviceUUID2); if (pRemoteService == nullptr) { Serial.print("ERROR : Failed to find CUSTOM SERVICE UUID: "); Serial.println(serviceUUID.toString().c_str()); pClient->disconnect(); return false; } pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID5); if (pRemoteCharacteristic == nullptr) { Serial.print("Failed to find our CUSTOM CHAR. UUID: "); Serial.println(charUUID5.toString().c_str()); pClient->disconnect(); return false; } Serial.println(" - Test Mode Enable"); if (pRemoteCharacteristic->canWrite()) { pRemoteCharacteristic->writeValue(newValue, 4, true); Serial.println("**Write Test Mode Enable Complete**"); } delay(500); pRemoteService = pClient->getService(serviceUUID2); if (pRemoteService == nullptr) { Serial.print("ERROR : Failed to find CUSTOM service UUID: "); Serial.println(serviceUUID.toString().c_str()); pClient->disconnect(); } pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID6); if (pRemoteCharacteristic == nullptr) { Serial.print("ERROR : Reseting Device "); Serial.println(charUUID6.toString().c_str()); pClient->disconnect(); } connected = true; return true; }`
I want to write this value to custom UUID then refresh service and characteristic cache to catch new characteristic UUID. But when I try to write I can only write one byte but for this value that has 4 bytes, it has nothing happen. I've looked for some documentation and topics on this repo and esp32 Webboard but still did not understand. several function
esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t handle, uint16_t value_len, uint8_t *value, esp_gatt_write_type_t write_type, esp_gatt_auth_req_t auth_req);
For this function I don't know what the parameter I should add to.esp_ble_gattc_cache_refresh(myDevice->getAddress().toString().c_str());
for this one I can't compile because type of value didn't match Here's my part of code modified from Neil Koban client example.