0

I am making an app that communicates with a specific Bluetooth Low Energy device. It requires a specific handshake and this is all working perfectly in Objective-C for iOS, however, I am having trouble recreating this functionality in Java

Any thoughts greatly appreciated!

WORKING Objective-C code:

uint8_t bytes[] = {0x04,0x08,0x0F,0x66,0x99,0x41,0x52,0x43,0x55,0xAA};
NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];
[_btDevice writeValue:data forCharacteristic:_dataCommsCharacteristic type:CBCharacteristicWriteWithResponse];

So far for android I have the following as an equivalent:

byte[] handshake = {0x04,0x08,0x0F,0x66,(byte)0x99,0x41,0x52,0x43,0x55,(byte)0xAA};

characteristic.setValue(handshake);
boolean writeStatus = gatt.writeCharacteristic(characteristic);
Log.d(TAG,"Handshake sent: " + writeStatus);

As mentioned, iOS works great, but the equivalent in Java is getting no response from the device, leading me to think that the data being sent is wrong/not recognised

UPDATE So, after plenty of wrestling with this I have a little more insight into what is going on 'I think!'

As Scary Wombat mentioned below the maximum value of an int is 127 so the 2 values in the array of 0x99 and 0xAA are of course out of this range

The below is where I am at with the values:

byte bytes[] = {0x04,0x08,0x0F,0x66,(byte)0x99,0x41,0x52,0x43,0x55,(byte)0xAA};
Log.d(TAG, Arrays.toString(bytes));

Produces

[4, 8, 15, 102, -103, 65, 82, 67, 85, -86]

However the expected values need to be

[4, 8, 15, 102, 153, 65, 82, 67, 85, 170]

I have tried casting these troublesome bytes implicitly and also tried the below below:

byte bytes[] = {0x04,0x08,0x0F,0x66,(byte)(0x99 & 0xFF),0x41,0x52,0x43,0x55,(byte)(0xAA & 0xFF)};

However the resulting values in the array are always the same.

Please help!!! :)

UPDATE 2

After a day of digging it appears that although the values are logging incorrectly the values perceived by the Bluetooth device SHOULD still be correct, so I have modified this question and continuing over here

Community
  • 1
  • 1
Joel Spencer
  • 129
  • 1
  • 8
  • Can you elaborate and explain what the new code is doing and where it is not behaving as you would expect? – S. Miller Mar 23 '17 at 01:14

2 Answers2

0

Why are you not doing it the same way as for C

In this code

String handshakeString = "0x04,0x08,0x0F,0x66,0x99,0x41,0x52,0x43,0x55,0xAA";
byte[] value = handshakeString.getBytes();

this is just making a text String where the first char is 0 and the second is x etc

try

byte arr[] = {0x04,0x08,0x0F,0x66,0x99,0x41,0x52,0x43,0x55,0xAA};

edit

You maybe need to reconsider values such as 0x99 as in java the byte values are as per javadocs

It has a minimum value of -128 and a maximum value of 127 (inclusive).

See Can we make unsigned byte in Java

Community
  • 1
  • 1
Scary Wombat
  • 44,617
  • 6
  • 35
  • 64
  • Thanks for the suggestion, I have tried your suggestion but get a compile error as lossy conversion from int to byte. I have tried casting each item to byte (which seems wrong) and compile is fine but the device still doesnt recognise the command Unfortunately the command required is specified by the hardware manufacturer as a string of 0x66,0x99,0x41,0x52,0x43,0x55,0xaa so I am not able to change the 0x99 element – Joel Spencer Mar 23 '17 at 01:26
  • Have you tried using a short array as per the suggestion in the link? – Scary Wombat Mar 23 '17 at 01:28
  • I have just tried the suggestion of the short array, it doesnt seem to make a difference unfortunately. – Joel Spencer Mar 23 '17 at 01:57
  • Hmm, according to [this answer](http://stackoverflow.com/a/4266841/2310289) there is nothing to stop you from downcasting a short to a byte `byte arr[] = {0x04,0x08,0x0F,0x66,(byte)0x99,0x41,0x52,0x43,0x55, (byte)0xAA};` – Scary Wombat Mar 23 '17 at 02:04
  • Hmm, yes, that would make sense. I have added an update, to the original post above, unfortunately Im not really much closer to resolving the issue. – Joel Spencer Mar 23 '17 at 13:21
0
String handshakeString = "0x04,0x08,0x0F,0x66,0x99,0x41,0x52,0x43,0x55,0xAA";
byte[] value = handshakeString.getBytes();

will also account the , and so creates to much bytesand will not geht the same bytes AS in your c code.

Try to use a byte[] directly.

byte[] value=new byte[]{0x04,0x08,0x0F,0x66,0x99,0x41,0x52,0x43,0x55,0xAA};
Jérôme
  • 1,254
  • 2
  • 20
  • 25