1

I am working on transmitting the contents of a byte array from an Android mobile app to an MCU. I am able to successfully transfer the data byte by byte (multiple packets) but I am unable to successfully send the array as a whole (as one packet). It should be noted that the data will be transmitted via a GATT profile and that the array is successfully passed to this portion of the code.

    public void writeCustomUsernameCharacteristic(byte[] byteArray) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
        BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb"));

        if (mCustomService == null) {
            Log.w(TAG, "Custom BLE Service not found");
            return;
        }
        mBluetoothGatt.requestMtu(244); 

        for (int i = 0; i < credentials.length; i++) {
            individualBytes = byteArray[i];

            BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); 
            mWriteCharacteristic.setValue(individualBytes, BluetoothGattCharacteristic.FORMAT_UINT8, 0);  
            mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);

            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                System.out.println("got interrupted!");
            }
            if (mBluetoothGatt.writeCharacteristic(mWriteCharacteristic) == false) {
                Log.w(TAG, "Failed to write characteristic");
            }
        }
    }

However, if I try to set the value to the byte array itself I am unable to send the information. It should be noted that there are no errors being reported on the app side and the MCU side isn't reporting any packets being received.

public void writeCustomUsernameCharacteristic(byte[] byteArray) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
        BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("4880c12c-fdcb-4077-8920-a450d7f9b907"));

        if (mCustomService == null) {
            Log.w(TAG, "Custom BLE Service not found");
            return;
        }
        mBluetoothGatt.requestMtu(244);

        BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(UUID.fromString("fec26ec4-6d71-4442-9f81-55bc21d658d6"));
        mWriteCharacteristic.setValue(byteArray);
        mWriteCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
        mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
    }

Could anyone provide on any suggestions on how to transmit this byte array in on packet? Thanks in advance.

In response to the possible duplicate. It appears that the link is referencing code I have already attempted in the second block. The problem is that the mBluetoothGatt.writeCharacteristic(mWriteCharacteristic); is not sending the packets to the MCU.

public void writeCustomUsernameCharacteristic(byte[] byteArray) {
            if (mBluetoothAdapter == null || mBluetoothGatt == null) {
                Log.w(TAG, "BluetoothAdapter not initialized");
                return;
            }
            BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("4880c12c-fdcb-4077-8920-a450d7f9b907"));

            if (mCustomService == null) {
                Log.w(TAG, "Custom BLE Service not found");
                return;
            }
            mBluetoothGatt.requestMtu(244);

            BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(UUID.fromString("fec26ec4-6d71-4442-9f81-55bc21d658d6"));
            mWriteCharacteristic.setValue(byteArray);
            mWriteCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
            mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);

            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                System.out.println("got interrupted!");
            }
2
  • 1
    Possible duplicate of Android BLE, read and write characteristics Commented Jul 3, 2018 at 18:26
  • @Chisko I don't believe this is a duplicate as I am already implementing the gatt.writeCharacteristic() to no avail unless I missed something when examining the link. Was there something in particular that you were referencing? Commented Jul 3, 2018 at 18:57

2 Answers 2

1

You can only have one outstanding GATT request at a time. You need to wait for the onMtuChanged callback before you can perform a write. Then you need to wait for the onCharacteristicWrite callback before you perform another write.

See my answer at Android BLE BluetoothGatt.writeDescriptor() return sometimes false for a more thorough explanation.

Sign up to request clarification or add additional context in comments.

6 Comments

Although this seems to be something that I should account for in my code I'm not sure as to whether or not this is the actual issue that is preventing my code from sending the information as a single packet. I believe this due to the fact that I have verified that the MTU has successfully changed and I have been able to successfully transmit the data as multiple packets. Any idea why it wouldn't be able to send the data as a single packet?
Can you please update your question so that the code follows the requirements I mentioned?
Sorry I have a pretty busy schedule today/tomorrow and will update my code when I have time. However, it appears that even if I remove requestMtu(244) and account for it on the MCU side that I am still unable to write the byteArray to the characeristic unless it is the individual elements. Do you still believe that the only error is that the GATT server is still processing another task? Thanks for the help and I'll add the wait functionality as soon as possible
What is the length of the byte array you try to write?
I was able to fix the issue (see above). Thank you for all of your help!
|
0

If you can send byte by byte and the device accepts the MTU it is as simple as this:

mCustomService.writeCharacteristic(mWriteCharacteristic,byteArray );

or

mBluetoothGatt.writeCharacteristic(mWriteCharacteristic,byteArray);

To check if there is a MTU-size problem send a small (<20bytes) byte array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.