Closed karthick1611 closed 1 year ago
fun writeData(data : String) {
writeCharacteristic(
fluxCapacitorControlPointWrite,
"$data\n".toByteArray(),
BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT
)
.split()
.with { device, data -> Log.e("Data Sent", String(data.value!!, Charsets.UTF_8)) }
.enqueue()
}
When I remove the request MTU, it's working fine but can able to read only 20 bytes of data. Can't able to read remaining.. How to read or merge remaining data?.
Hi, If the remote device accepts MTU = 512 then sending longer packets should work. Can you say what is not working exactly? Are you sure there are no issues on the firmware side? If you're using Nordic devices, please consult on DevZone.
However, whether MTU is 23 (max 20 bytes), or 512 (max 509 bytes of payload), if your actual payload is longer than that you need to split it on one side to fit packets and merge on the other side.
How to split and merge depend on the device specification. The received needs to know when to stop merging and return the reassembled value. The total size may be known beforehand, sent in the first packet, marked using a flag in each packet, etc. The sender implementation must match the received.
For example, let's say you want to send a JSON file. You don't have to send the length, as the receiver may try to parse the received data each time it gets a new packet. For that purpose use JsonMerger
on the receiver (if you're using Android on server side), or implement similar thing in the firmware.
If the data is not a JSON file, or you don't want to spend time/battery to parse it after each packet, you may decide to send the total length in bytes before the data. The first packet may contain 2 bytes of "total length in UINT16 in Little Endian" followed by some number of packets with given number of bytes. The receiver would receive the length, set up a buffer and collect packets until the desired length is obtained.
You may also append a flag to each packet sent. Let's say the first byte in each indicates "the last packet" or "more will come". The received buffers incoming packets (skipping the first byte) until the last packet is received.
If the size of the packet is known you may completely skip sending length, as the received knows the size.
Have a look s PacketSlitter
and PacketMerger
here: https://github.com/NordicSemiconductor/Android-BLE-Library/tree/main/examples/trivia/src/main/java/no/nordicsemi/android/ble/trivia/spec
For example, I'm writing the data like "setconf serialNumber" and my MTU was like 20. My response Should be like,
{
"result":"true",
"serialNumber":"ERFDSJBJKLL234234234"
}
But I'm getting response like,
{
"result":"true",
"serialNumber":"ERFD
}
See Json wasn't complete.
When using .split()
you'll receive (MTU - 4 + n) / (MTU-3)
notifications on the receiver side, each containing 20 or less bytes. You need to merge them to get the full data.
Also, seems like you're sending each line of the JSON separately for some reason. You may send it all together, better without line breaks to save some bytes. Only then you know the total size and can parse the JSON.
Ok. Is there any code snippet to merge the data?. I didn't find any sample code with it...
I already gave you the classes here: https://github.com/NordicSemiconductor/Android-BLE-Library/issues/453#issuecomment-1377172734. The splitter and merger are using the "total length" approach. The first packet sent is prefixed with 2 byte length field.
Also, seems like you're sending each line of the JSON separately for some reason. You may send it all together, better without line breaks to save some bytes. Only then you know the total size and can parse the JSON.
Json is response. "setconf serialNumber" this is command I'm passing to.
I already gave you the classes here: #453 (comment). The splitter and merger are using the "total length" approach. The first packet sent is prefixed with 2 byte length field.
Ok. Thanks. Let me check that and post here. Thanks for the quick response..
Hi,
I implemented your library, When I try to test it with Samsung Galaxy S22 series, Bluetooth 5.2 and Android OS version 13, I can't able to set MTU as 512. When I set MTU as 512 nothing working so I removed the request MTU, now my default MTU was like 23.
Now I'm writing characteristics, writing was working fine but I can able to read only 20 bytes of data.
How to read remaining data?.
I used Split() while writing Characteristics.
When I set request MTU as 512, Writing getting failed and disconnected.