Search code examples
reactjsreact-nativebluetooth-lowenergyreact-native-ble-plx

React Native + react-native-ble-plx. Writing to a BLE device


I'm writing an app with React Native and react-native-ble-plx. I already have scan devices, connect to a device and read from a device. Everything works as expected.

My main issue is writing to the device.
The device I'm writing to doesn't have characteristics for each function. It has 3 services (device service, read service and write service). To differentiate between two write operations, there are prefixes.

For example:

Write password (4 digits) — it will expect 0x5501 as prefix, and then password 01020304. So the payload will look like this: 0x550101020304.

Write to lock the device (boolean 0/1) — will be 0x5505 as prefix, 01020304 as password for security, 01 or 00 to lock/unlock the device. The payload will look like this: 0x550501020301, or 0x55050102030400


When I'm trying to write to the device (set password). I'm not getting an error, but also, the device is not really changing the password. (Testing with nordic actually changing the password to the device, so the device is working as expected).

What I tried (doesn't work):

const prefix = [55, 1];
let passwordWithHeader = [];
if (data) {
  if (data.length < 4) throw new Error("Password must be 4 digits");

  passwordWithHeader = Buffer.from(
    convertedArrayToHex(prefix.concat(data)) // will return ["55","01","01","02","03","04"]
  );
}

try {
  let res =
    await connectedDevice.device.writeCharacteristicWithResponseForService(
      SPS_SERVICE_UUID,
      SPS_SERVER_TX_UUID,
      passwordWithHeader.toString("base64")
    );

  return res;
  // Password set successfully
} catch (error) {
  console.log("err in write password", error);
  throw error;
  // Handle error while setting password
}
};

How do I write data with ble plx lib, to a device that expects 0x550101020304?

Probably, my confusion is that based on the react-native-ble-plx, it expects the data to be base16. Writing to devce doc.


Solution

  • Im answering my own question. So basically the main issue was that the device is expecting the prefix to be [55, 1] (as bytes) . this means that when im converting to hex (and then to base64) i need the 55 (index 0) to be a number that will be converted into 55 (which is 85). so the final solution will look like this:

     const prefix = [85, 1];
        let passwordWithHeader = [];
        if (data) {
          if (data.length < 4) throw new Error("Password must be 4 digits");
        }
        passwordWithHeader = Buffer.from(prefix.concat(data));
       
        // Convert to hex (will now return [55,1,1,2,3,4])
        const hexString = passwordWithHeader.toString("hex");
        
        // Convert hex to base64
        const base64String = Buffer.from(hexString, "hex").toString("base64");
    
        try {
          let res =
            await connectedDevice?.device.writeCharacteristicWithResponseForService(
              SPS_SERVICE_UUID,
              SPS_SERVER_TX_UUID,
              base64String
            );
    
          return res;
        } catch (error) {
          console.log("err in write password", error);
          throw error;
        }