Skip to content

CurieBLE: characteristic.writeInt(...) does not perform write request #385

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

Closed
sandeepmistry opened this issue Dec 30, 2016 · 17 comments
Closed
Assignees

Comments

@sandeepmistry
Copy link
Contributor

When using the [bleno echo example] on my Raspberry Pi, with the sketch below, echoCharacteristic.writeInt(i) returns true, but the write request does not succeed.

#include <CurieBLE.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);

  BLE.begin();

  BLE.scan();
}

void loop() {
  // check if a peripheral has been discovered
  BLEDevice peripheral = BLE.available();

  if (peripheral) {
    // discovered a peripheral, print out address, local name, and advertised service
    Serial.print("Found ");
    Serial.print(peripheral.address());
    Serial.print(" '");
    Serial.print(peripheral.localName());
    Serial.print("' ");
    Serial.print(peripheral.advertisedServiceUuid());
    Serial.println();

    if (peripheral.address() == "00:19:0E:11:24:06") {
      BLE.stopScan();

      if (peripheral.connect()) {
        Serial.println("connected");
      }

      if (peripheral.discoverAttributes()) {
        Serial.println("attributes discovered");
      }

      BLECharacteristic echoCharacteristic = peripheral.characteristic("ec0e");

      if (echoCharacteristic.canRead()) {
        Serial.println("canRead");
      }

      if (echoCharacteristic.canWrite()) {
        Serial.println("canWrite");
      }

      if (echoCharacteristic.canSubscribe()) {
        Serial.println("canSubscribe");
      }

      if (echoCharacteristic.subscribe()) {
        Serial.println("subscribed");
      }

      int i = 0;

      while(peripheral.connected()) {
        if (echoCharacteristic.writeInt(i)) {
          Serial.println("write success");
        } else {
          Serial.println("write fail");
        }

        i++;

        delay(1000);
      }
    }
  }
}

I ran hcidump on the Raspberry Pi, and the operation is failing:

2016-12-30 15:37:21.520761 > ACL data: handle 64 flags 0x02 dlen 11
    ATT: Write cmd (0x52)
      handle 0x000c value  0x79 0x00 0x00 0x00
2016-12-30 15:37:21.521400 < ACL data: handle 64 flags 0x00 dlen 9
    ATT: Error (0x01)
      Error: Write not permitted (3)
      Write cmd (0x52) on handle 0x000c

A write request should be sent instead of a write command because the characteristic only has the "write" property on not "write without response".

If I use LightBlue on my iPhone, the write succeeds using a write request:

2016-12-30 15:39:05.160968 > ACL data: handle 64 flags 0x02 dlen 9
    ATT: Write req (0x12)
      handle 0x000c value  0xab 0xcd
2016-12-30 15:39:05.162811 < ACL data: handle 64 flags 0x00 dlen 5
    ATT: Write resp (0x13)
@SidLeung
Copy link
Contributor

SidLeung commented Jan 6, 2017

@sandeepmistry Apparently, the same Central sketch, using writeInt(), behaves differently with two different Peripherals. Am I correct?

@SidLeung
Copy link
Contributor

SidLeung commented Jan 6, 2017

Logged as Jira 794.

@sandeepmistry
Copy link
Contributor Author

@SidLeung I don't think so, bleno might be more strict.

Here's the behaviour I expect:

  • If the characteristic property is "write", a write request should be used by the 101 central
  • If the characteristic property is "write without response" a write command should be used by the 101 central

To me it seems like a write command is always used, and the 101 peripheral accepts this even if the characteristic has a write property.

@noelpaz
Copy link
Contributor

noelpaz commented Feb 8, 2017

I think this is related to 414 #414

If you look at the screen capture from the namlyzer then this is already fixed

@SidLeung
Copy link
Contributor

@sandeepmistry , resolution is available in nightly build starting on 2/9/2017,

http://mkfs.ndg.intel.com/json/public/package_public-07.4_index.json

@sandeepmistry
Copy link
Contributor Author

I'm still experiencing this issue:

HCI dump capture snippet from Raspberry Pi:

2017-02-17 21:23:46.461390 > ACL data: handle 64 flags 0x02 dlen 11
    ATT: Write cmd (0x52)
      handle 0x000c value  0x37 0x00 0x00 0x00
2017-02-17 21:23:46.461914 < ACL data: handle 64 flags 0x00 dlen 9
    ATT: Error (0x01)
      Error: Write not permitted (3)
      Write cmd (0x52) on handle 0x000c

@SidLeung
Copy link
Contributor

@sandeepmistry , can this failure be duplicated with iOS devices? Thanks.

@sandeepmistry
Copy link
Contributor Author

@SidLeung with iOS everything is fine, see last block of comment #385 (comment)

If I use LightBlue on my iPhone, the write succeeds using a write request:

2016-12-30 15:39:05.160968 > ACL data: handle 64 flags 0x02 dlen 9
    ATT: Write req (0x12)
      handle 0x000c value  0xab 0xcd
2016-12-30 15:39:05.162811 < ACL data: handle 64 flags 0x00 dlen 5
    ATT: Write resp (0x13)

@SidLeung
Copy link
Contributor

@sandeepmistry , we need to use Raspberry Pi to see the issue then. @russmcinnis , @noelpaz .

@russmcinnis
Copy link
Contributor

I will grab a raspberry pi and try to reproduce this and get some scanner traces.

@sgbihu
Copy link
Contributor

sgbihu commented Feb 22, 2017

Hi @sandeepmistry ,

Can you share the raspberry pi's executing code? I want take a look.

Thanks!

@sandeepmistry
Copy link
Contributor Author

Hi @sgbihu,

Here are some instructions:

  1. Install Node.js
  2. Make test directory and cd into it.
  3. Run sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev
  4. Stop bluetoothd: sudo systemctl stop bluetooth
  5. Power up the Bluetooth adapter manually: sudo hciconfig hci0 up
  6. Run npm install bleno
  7. Run example: sudo node_modules/bleno/examples/echo/main.js

@kitsunami kitsunami modified the milestones: Elnath, Deneb Feb 24, 2017
@SidLeung
Copy link
Contributor

SidLeung commented Mar 3, 2017

Jira 860 is created to track this issue.

@sandeepmistry
Copy link
Contributor Author

This still occurs with the 2.0.1 RC1 preview.

screen shot 2017-03-15 at 11 44 34 am

@noelpaz
Copy link
Contributor

noelpaz commented Mar 22, 2017

Testing this now using the sketch from Sandeep and the bleno echo example. it looks like it is working. Will also run this on the Elisyss BLE Analyzer.

image

@noelpaz
Copy link
Contributor

noelpaz commented Mar 23, 2017

Note that in MacOS running bleno. Simply killing the node js app will not kill the bluetooth connection. You need to kill the underlying Mac BT layer by turning BT off.

This is the capture from the Elisyss Analyzer

image

@sandeepmistry
Copy link
Contributor Author

This looks good now with the 2.0.2 RC JSON @SidLeung provided me on my Mac.

However, my sketch is filtering based on the local name, and it doesn't work with the Raspberry Pi, I'll open a separate issue shortly on this.

#include <CurieBLE.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);

  BLE.begin();

  BLE.scan();
}

void loop() {
  // check if a peripheral has been discovered
  BLEDevice peripheral = BLE.available();

  if (peripheral) {
    // discovered a peripheral, print out address, local name, and advertised service
    Serial.print("Found ");
    Serial.print(peripheral.address());
    Serial.print(" '");
    Serial.print(peripheral.localName());
    Serial.print("' ");
    Serial.print(peripheral.advertisedServiceUuid());
    Serial.println();

    if (peripheral.localName() == "echo") {
      BLE.stopScan();

      if (peripheral.connect()) {
        Serial.println("connected");
      }

      if (peripheral.discoverAttributes()) {
        Serial.println("attributes discovered");
      }

      BLECharacteristic echoCharacteristic = peripheral.characteristic("ec0e");

      if (echoCharacteristic.canRead()) {
        Serial.println("canRead");
      }

      if (echoCharacteristic.canWrite()) {
        Serial.println("canWrite");
      }

      if (echoCharacteristic.canSubscribe()) {
        Serial.println("canSubscribe");
      }

      if (echoCharacteristic.subscribe()) {
        Serial.println("subscribed");
      }

      int i = 0;

      while(peripheral.connected()) {
        if (echoCharacteristic.writeInt(i)) {
          Serial.println("write success");
        } else {
          Serial.println("write fail");
        }

        i++;

        delay(1000);
      }
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants