Skip to content

subscribe()/valueUpdated() not working #71

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
willtmakinen78 opened this issue May 1, 2020 · 10 comments
Open

subscribe()/valueUpdated() not working #71

willtmakinen78 opened this issue May 1, 2020 · 10 comments
Labels
status: waiting for information More information must be provided before work can proceed type: imperfection Perceived defect in any part of project

Comments

@willtmakinen78
Copy link

I've been using an Arduino Nano 33 BLE to communicate with my PC over the BlueFruit LE Friend's UART characteristic. Using the default ArduinoBLE library, I'm able to connect to the BlueFruit from the Nano33 as a central device, and write to the BlueFruit and have it show up in a serial terminal. I can get the Nano33 to read from the Bluefruit as well, by sending a Characteristic.read() request and a subsequent Charcterisitc.readValue() command. Subscribing to the rx characterisitic on the Nano33 is an issue, however, even though the Bluefruit's info page says that the rx characterisitc (address 0x0003) is capable of Notify. At first, Charcteristic.subscribe() would always return false, until I followed @gdsport's advice here and modified BLERemoteDescriptor.cpp. Now, although subscribe() returns true, Charcteristic.valueUpdated() always returns false, even when opening up a serial port to the BlueFruit and sending data with the UART service. This is the relevant Arduino code:

BLECharacteristic rxCharacteristic = peripheral.characteristic("6e400003-b5a3-f393-e0a9-e50e24dcca9e");

  // make sure BlueFruit UART characteristics have been loaded properly are of
  // proper format
  if (!rxCharacteristic) {
    Serial.println("Peripheral does not have RX characteristic!");
    peripheral.disconnect();
    return;
  } else if (!rxCharacteristic.canSubscribe()) {
    Serial.println("rxCharacteristic is not subscribable!");
    peripheral.disconnect();
    return;
  } else if (!rxCharacteristic.subscribe()) {
    Serial.println("rxCharacteristic subscription failed!");
    peripheral.disconnect();
    return;
  }
  Serial.println("subscribed");

  while (peripheral.connected()) {

      if (rxCharacteristic.valueUpdated()) {
        Serial.println("value updated");
      }
}

For reference, this is the modified code from BLERemoteDescriptor.cpp:

int BLERemoteDescriptor::writeValue(const uint8_t value[], int length)
{
  if (!ATT.connected(_connectionHandle)) {
    return false;
  }

  uint16_t maxLength = ATT.mtu(_connectionHandle) - 3;

  if (length > (int)maxLength) {
    // cap to MTU max length
    length = maxLength;
  }

  _value = (uint8_t*)realloc(_value, length);
  if (_value == NULL) {
    // realloc failed
    return 0;
  }  

#if 0
  uint8_t resp[4];
  int respLength = ATT.writeReq(_connectionHandle, _handle, value, length, resp);

  if (!respLength) {
    return 0;
  }

  if (resp[0] == 0x01) {
    // error
    return 0;
  }
#else 
    ATT.writeCmd(_connectionHandle, _handle, value, length);
#endif

  memcpy(_value, value, length);
  _valueLength = length;

  return 1;
}

Any thoughts on what might be causing this?

Arduino IDE version 1.8.12 and ArduinoBLE version 1.1.2

@willtmakinen78 willtmakinen78 changed the title subscribe()/valueUpdated() with Nano33 BLE and Adafruit BlueFruit LE Friend not working subscribe()/valueUpdated() not working May 1, 2020
@Gerriko
Copy link

Gerriko commented May 3, 2020

I had noticed the question raised about the failure to subscribe on the Arduino Forum and began to investigate.

For what it's worth, I discovered that within this function BLERemoteCharacteristic::writeCccd(uint16_t value) it determines the number of descriptors with this call int numDescriptors = descriptorCount();

For some reason the Bluefruit device is returning 0.

I ran the identical peripheral example using a BBC microbit and this correctly returns the value 2 (as in, there are two descriptors present for that characteristic 2901 and 2902).

@willtmakinen78
Copy link
Author

I ran the identical peripheral example using a BBC microbit and this correctly returns the value 2 (as in, there are two descriptors present for that characteristic 2901 and 2902).

So would you say that it's a Nano33 BLE issue? Also I'm assuming you were able to subscribe on the BBC microbit.

@Gerriko
Copy link

Gerriko commented May 4, 2020

Yes, the Nano33 can subscribe to the BBC microbit as the Nano BLE central firmware can loop through the number of descriptors available from the BBC microbit and find 0x2902 to then apply the write value function. With Bluefruit, because number of descriptors is zero the Nano BLE central firmware bypasses and thus never updates the Bluefruit 0x2902.

@willtmakinen78
Copy link
Author

I see - any suggestions on how to fix the descriptorCount() function? Otherwise I'm going to order an ESP32 and be done with this :/.

@Gerriko
Copy link

Gerriko commented May 5, 2020

I've discovered that this is not as straightforward as one might think.

I created a PSoC4 peripheral with the same GATT service + characteristics as the Bluefruit device but this time I did not implement the NOTIFY update functionality, just to see what happens (i.e. this should throw up an error).

The ESP32 returns that all is OK, when it should not have done so - so in this case the ESP32 would have crashed or not received any values from NOTIFY.

The nano BLE33 board (with ArduinoBLE library) interestingly finds the 2 descriptors (2901 and 2902) and says that it was able to update 2902 but then does not update the "fallback" option as the "if (_properties & (BLENotify | BLEIndicate))" was not true (with the Bluefruit device this was true but the cccd.writeValue must not return true for what ever reason).

if (_properties & (BLENotify | BLEIndicate)) { // no CCCD descriptor found, fallback to _valueHandle + 1 BLERemoteDescriptor cccd(NULL, 0, _connectionHandle, _valueHandle + 1); return cccd.writeValue((uint8_t*)&value, sizeof(value)); }
Confirms the other post... as to what the real fix should be...

@Gerriko
Copy link

Gerriko commented May 5, 2020

Debug using BLE.debug(Serial) - nano BLE connecting with Bluefruit:

Found f7:0f:7f:2d:4e:56 'Adafruit Bluefruit LE' 6e400001-b5a3-f393-e0a9-e50e24dcca9e
HCI COMMAND TX -> 010C20020000
HCI EVENT RX <- 040E04010C2000
Connecting ...
HCI COMMAND TX -> 010D2019600030000001564E2D7F0FF70006000C000000C80004000600
HCI EVENT RX <- 040F0400010D20
HCI EVENT RX <- 043E13010000000001564E2D7F0FF708000000C80007
Connected
Discovering attributes ...
HCI ACLDATA TX -> 02000007000300040002F700
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 020020070003000400031700
HCI ACLDATA TX -> 0200000B0007000400100100FFFF0028
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 02002012000E000400110601000700001808000B000118
HCI ACLDATA TX -> 0200000B0007000400100C00FFFF0028
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200201A001600040011140C00130023D1BCEA5F782315DEEF121230150000
HCI ACLDATA TX -> 0200000B0007000400101400FFFF0028
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200C0008000400110614001E000A18
HCI ACLDATA TX -> 0200000B0007000400101F00FFFF0028
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200201A001600040011141F00FFFF9ECADC240EE5A9E093F3A3B50100406E
HCI ACLDATA TX -> 0200000B000700040008010007000328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200201B0017000400090702000A0300002A0400020500012A0600020700042A
HCI ACLDATA TX -> 0200000B000700040008080007000328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200900050004000108080001
HCI ACLDATA TX -> 0200000B00070004000808000B000328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200D000900040009070900200A00052A
HCI ACLDATA TX -> 0200000B0007000400080B000B000328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 02002009000500040001080B000A
HCI ACLDATA TX -> 0200000B0007000400080C0013000328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200201B001700040009150D00040E0023D1BCEA5F782315DEEF121232150000
HCI ACLDATA TX -> 0200000B0007000400080F0013000328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200201B001700040009150F0018100023D1BCEA5F782315DEEF121231150000
HCI ACLDATA TX -> 0200000B000700040008110013000328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200201B00170004000915120002130023D1BCEA5F782315DEEF121234150000
HCI ACLDATA TX -> 0200000B000700040008140013000328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200900050004000108140001
HCI ACLDATA TX -> 0200000B00070004000814001E000328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200201B001700040009071500021600292A1700021800242A1900021A00282A
HCI ACLDATA TX -> 0200000B0007000400081B001E000328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 02002014001000040009071B00021C00262A1D00021E00272A
HCI ACLDATA TX -> 0200000B0007000400081F001E000328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 02002009000500040001081F0001
HCI ACLDATA TX -> 0200000B0007000400081F00FFFF0328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200201B0017000400091520001021009ECADC240EE5A9E093F3A3B50300406E
HCI ACLDATA TX -> 0200000B0007000400082200FFFF0328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200201B0017000400091524000C25009ECADC240EE5A9E093F3A3B50200406E
HCI ACLDATA TX -> 0200000B0007000400082600FFFF0328
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 020020090005000400010826000A
HCI ACLDATA TX -> 020000090005000400040B000B00
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200A000600040005010B000229
HCI ACLDATA TX -> 020000090005000400040C000B00
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 02002009000500040001040C0001
HCI ACLDATA TX -> 020000090005000400042600FFFF
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200A0006000400050126000129
HCI ACLDATA TX -> 020000090005000400042700FFFF
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 020020090005000400010427000A
Attributes discovered
--- Number descriptors found: 0
HCI ACLDATA TX -> 0200000900050004001222000100
HCI EVENT RX <- 0413050100000100
HCI ACLDATA RX <- 0200200900050004000112220003
--- writevalue.cccd returned: 0
Fail to subscribe...
HCI ACLDATA RX <- 02002010000C000500120208001000200000002C01
HCI ACLDATA TX -> 0200000A0006000500130202000000
HCI COMMAND TX -> 0113200E00001000200000002C0104000600
HCI EVENT RX <- 0413050100000100
HCI EVENT RX <- 040F0400011320
HCI EVENT RX <- 043E0A03000000100000002C01

@Gerriko
Copy link

Gerriko commented May 5, 2020

I've found that within the writeValue function (BLERemoteDescriptor), the Bluefruit has resp[0] = 0x01, which triggers an error condition. Not sure what this means though.

Trawling through that debug log I found that with the Bluefruit device we get:
HCI ACLDATA TX -> 0200000900050004001222000100

and with the BBC microbit device we get:
HCI ACLDATA TX -> 0200000900050004001213000100

@willtmakinen78
Copy link
Author

Alright, so it seems that my issues are a combination of BlueFruit and ArduinoBLE incompatabilities. Debugging the library is unfortunately a bit past the scope of project, since it's due in a week. In general I would be interested in helping out however, so please let me know if there's anything you need me to do.

@polldo
Copy link
Contributor

polldo commented Jul 21, 2020

Hi @willtmakinen78 and @Gerriko ,
thanks a lot for detailing the issue. In particular to @Gerriko for trying many combinations and posting logs!
I should have found the problem with the library, you can check this out here #99

Could you please try if this fix solves the issue?
Thanks!

@polldo polldo added the status: waiting for information More information must be provided before work can proceed label Jul 21, 2020
@per1234 per1234 added the type: imperfection Perceived defect in any part of project label Mar 9, 2021
@kitoheedong
Copy link

I am having the same issue with Nano RP4020.
Is there someone who's facing the same issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting for information More information must be provided before work can proceed type: imperfection Perceived defect in any part of project
Projects
None yet
Development

No branches or pull requests

5 participants