capacitor-community / bluetooth-le

Capacitor plugin for Bluetooth Low Energy
MIT License
284 stars 86 forks source link

writeWithoutResponse method returns "value must be provided" error #689

Closed natehurley closed 1 month ago

natehurley commented 2 months ago

Describe the bug

When using the writeWithoutResponse method from @capacitor-community/bluetooth-le to send data to a BLE device, I receive an error stating that the value must be provided, even though the value parameter is included in the method call. I'm sure I'm attempting to write to the correct deviceId, service, and characteristic after checking the results of the debugCharacteristics method that I wrote.

Error message from Xcode console

⚡️  To Native ->  BluetoothLe connect 50922472
⚡️  BluetoothLe - Connecting to peripheral <CBPeripheral: 0x30192cdd0, identifier = 93BBD767-803D-5005-9DF6-07F7333D0977, name = Halcyon BLE Server, mtu = 0, state = disconnected>
⚡️  BluetoothLe - Connected to device <CBPeripheral: 0x30192cdd0, identifier = 93BBD767-803D-5005-9DF6-07F7333D0977, name = Halcyon BLE Server, mtu = 23, state = connected>
⚡️  BluetoothLe - Resolve connect|93BBD767-803D-5005-9DF6-07F7333D0977 Successfully connected.
⚡️  BluetoothLe - Connected to peripheral. Waiting for service discovery.
⚡️  BluetoothLe - didDiscoverServices
⚡️  BluetoothLe - didDiscoverCharacteristicsFor 1 1
⚡️  BluetoothLe - Resolve connect Connection successful.
⚡️  TO JS undefined
⚡️  [log] - Connected to device: Halcyon BLE Server
⚡️  To Native ->  BluetoothLe getServices 50922473
⚡️  TO JS {"services":[{"uuid":"0000abcd-cc7a-482a-984a-7f2ed5b3e58f","characteristics":[{"descriptors":[],"properties":{"write":true,"authenticatedSignedWrites":false,"extendedProperties":false,"notifyEncryptionRequired":false,"read":false,"indicate":false,"writeWi
⚡️  [log] - All services and characteristics: {
  "services": [
    {
      "uuid": "0000abcd-cc7a-482a-984a-7f2ed5b3e58f",
      "characteristics": [
        {
          "descriptors": [],
          "properties": {
            "write": true,
            "authenticatedSignedWrites": false,
            "extendedProperties": false,
            "notifyEncryptionRequired": false,
            "read": false,
            "indicate": false,
            "writeWithoutResponse": true,
            "broadcast": false,
            "notify": false,
            "indicateEncryptionRequired": false
          },
          "uuid": "00001234-8e22-4541-9d4c-21edae82ed19"
        },
        {
          "properties": {
            "authenticatedSignedWrites": false,
            "write": false,
            "extendedProperties": false,
            "notifyEncryptionRequired": false,
            "read": false,
            "indicate": false,
            "broadcast": false,
            "writeWithoutResponse": false,
            "notify": true,
            "indicateEncryptionRequired": false
          },
          "descriptors": [
            {
              "uuid": "00002902-0000-1000-8000-00805f9b34fb"
            }
          ],
          "uuid": "00005678-8e22-4541-9d4c-21edae82ed19"
        }
      ]
    }
  ]
}
⚡️  [log] - Target characteristic properties: {"authenticatedSignedWrites":false,"write":false,"extendedProperties":false,"notifyEncryptionRequired":false,"read":false,"indicate":false,"broadcast":false,"writeWithoutResponse":false,"notify":true,"indicateEncryptionRequired":false}
⚡️  To Native ->  BluetoothLe writeWithoutResponse 50922474
ERROR MESSAGE:  {"message":"value must be provided","errorMessage":"value must be provided"}
⚡️  [error] - {"message":"value must be provided","errorMessage":"value must be provided"}

To Reproduce

await BluetoothLe.connect({ deviceId: device.deviceId, timeout: 5000 });
console.log('Connected to device:', device.name || device.deviceId);

await this.debugCharacteristics(device.deviceId);

await BluetoothLe.writeWithoutResponse({
  deviceId: device.deviceId,
  service: this.serviceUUID,
  characteristic: this.readCharacteristic,
  value: textToDataView('?')
});

Expected behavior I expect the writeWithoutResponse method to successfully write the provided data to the BLE device without errors. The data should be transmitted to the specified characteristic of the connected BLE device.

Screenshots

Plugin version:

Smartphone:

natehurley commented 2 months ago

So I realized my first mistake was using DataView objects for the value parameter instead of strings while developing for iOS/Android. However, when I make the change I'm getting a different error in XCode.

Changed code

await BluetoothLe.connect({ deviceId: device.deviceId, timeout: 5000 });
console.log('Connected to device:', device.name || device.deviceId);

await this.debugCharacteristics(device.deviceId);

await BluetoothLe.writeWithoutResponse({
  deviceId: device.deviceId,
  service: this.serviceUUID,
  characteristic: this.readCharacteristic,
  value: '?'
});

Error message from Xcode console

⚡️  To Native ->  BluetoothLe connect 38183105
⚡️  [log] - Scan stopped
⚡️  BluetoothLe - Connecting to peripheral <CBPeripheral: 0x3026bc750, identifier = 93BBD767-803D-5005-9DF6-07F7333D0977, name = Halcyon BLE Server, mtu = 0, state = disconnected>
⚡️  BluetoothLe - Connected to device <CBPeripheral: 0x3026bc750, identifier = 93BBD767-803D-5005-9DF6-07F7333D0977, name = Halcyon BLE Server, mtu = 23, state = connected>
⚡️  BluetoothLe - Resolve connect|93BBD767-803D-5005-9DF6-07F7333D0977 Successfully connected.
⚡️  BluetoothLe - Connected to peripheral. Waiting for service discovery.
⚡️  BluetoothLe - didDiscoverServices
⚡️  BluetoothLe - didDiscoverCharacteristicsFor 1 1
⚡️  BluetoothLe - Resolve connect Connection successful.
⚡️  TO JS undefined
⚡️  [log] - Connected to device: Halcyon BLE Server
⚡️  To Native ->  BluetoothLe getServices 38183106
⚡️  TO JS {"services":[{"uuid":"0000abcd-cc7a-482a-984a-7f2ed5b3e58f","characteristics":[{"uuid":"00001234-8e22-4541-9d4c-21edae82ed19","properties":{"notifyEncryptionRequired":false,"read":false,"authenticatedSignedWrites":false,"notify":false,"broadcast":false,"in
⚡️  [log] - All services and characteristics: {
  "services": [
    {
      "uuid": "0000abcd-cc7a-482a-984a-7f2ed5b3e58f",
      "characteristics": [
        {
          "uuid": "00001234-8e22-4541-9d4c-21edae82ed19",
          "properties": {
            "notifyEncryptionRequired": false,
            "read": false,
            "authenticatedSignedWrites": false,
            "notify": false,
            "broadcast": false,
            "indicateEncryptionRequired": false,
            "extendedProperties": false,
            "indicate": false,
            "write": true,
            "writeWithoutResponse": true
          },
          "descriptors": []
        },
        {
          "uuid": "00005678-8e22-4541-9d4c-21edae82ed19",
          "properties": {
            "notifyEncryptionRequired": false,
            "read": false,
            "authenticatedSignedWrites": false,
            "notify": true,
            "broadcast": false,
            "indicateEncryptionRequired": false,
            "extendedProperties": false,
            "indicate": false,
            "write": false,
            "writeWithoutResponse": false
          },
          "descriptors": [
            {
              "uuid": "00002902-0000-1000-8000-00805f9b34fb"
            }
          ]
        }
      ]
    }
  ]
}
⚡️  To Native ->  BluetoothLe writeWithoutResponse 38183107
CapacitorCommunityBluetoothLe/Conversion.swift:30: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Screenshot

Screenshot 2024-09-23 at 5 38 23 PM

natehurley commented 1 month ago

I figured out the issue—it was due to me using BluetoothLe directly instead of utilizing BleClient as recommended in the README. My apologies for the confusion. I'll go ahead and close this issue. Thank you to the developers for your hard work!

peitschie commented 1 month ago

Thanks for reporting back with your eventual solution here @natehurley

Glad you were able to figure this out in the end!