3

I am writing an open source framework to use BLE Mini module with Android and iOS mobile devices using Unity engine.

This framework should allow to establish a connection between the mobile device and the BLE Mini module, and to send/receive data using it. The framework can be theoretically adapted to work with any BLE module.

The idea is to make the existing BLE Mini frameworks (available for iOS and Android) work in Unity engine, hence I am writing native plugins for iOS and Android that will allow Unity apps use the native frameworks.

The iOS plugin is working as expected, while I am having problems writing the Android plugin.

Everything works as expected except the fact that I cannot send data to my characteristic. If I send the data the BLE Mini module does not receive it. The code controlling the BLE Mini data reception is correct because it works when iOS sends the data. So I am pretty sure the problem is in the Android plugin.

The Android plugin is composed by Android native code that can be found here: https://github.com/giomurru/ble-framework/tree/master/AndroidPlugin/src/com/gmurru/bleframework and by Unity c# code that can call the public java methods: https://github.com/giomurru/ble-framework/blob/master/Unity/Assets/BLE/BLEController.cs

The code contained in RBLGattAttributes.java and RBLService.java is correct because it is the framework provided by RedBearLab and I tested it and it works correctly with native Android apps.

The code in which I need help and that probably contains the bug is the one in BleFramework.java

The BleFramework class contains a series of functions that can be called by the Unity engine. The functions are called following this order:

  • Call the get static method BleFramework.getInstance() to get a singleton instance of the class BleFramework. This method returns one and only one instance of the BleFramework class.

  • After I have the instance of the class I can call the BleFramework methods using this instance (which is always the same instance).

  • The methods are called following this order:

1) Call the function _InitBLEFramework from Unity. The function should initialize the BLE framework. When the initialization is finished the Android plugin answer to Unity with a OnBleDidInitialize "Success" message.

2) If Unity receives the OnBleDidInitialize "Success" message, I can call the function _ScanForPeripherals from Unity. The function scans for available BLE modules peripherals. When the available peripherals are found the plugin answer to Unity with a OnBleDidCompletePeripheralScan "Success" message.

3) If Unity receives the OnBleDidCompletePeripheralScan "Success" message, I can call the function _GetListOfDevices to get the list of found devices.

4) Once I have the list of BLE module devices I found, I can try to connect to one of them using the function _ConnectPeripheralAtIndex(int peripheralIndex). When the _mGattUpdateReceiver receives RBLService.ACTION_GATT_SERVICES_DISCOVERED I can say the connection is established and I can let Unity know I am ready to send/receive data by sending a OnBleDidConnect "Success" message.

Up to here the plugin works as expected, and the connection is established.

The problem is when I try to send data in step 5.

5) When Unity receives the OnBleDidConnect "Success" message it is ready to send data through the established connection. Hence I try to send the data by using _SendData function in the plugin. Unfortunately it does not work.

This is the code:

public void _SendData(byte[] data)
{
    Log.d(TAG,"_SendData: ");

    BluetoothGattCharacteristic characteristic = _map.get(RBLService.UUID_BLE_SHIELD_TX);
    Log.d(TAG, "Set data in the _characteristicTx");
    byte[] tx = hexStringToByteArray("fefefe");
    characteristic.setValue(tx);

    Log.d(TAG, "Write _characteristicTx in the _mBluetoothLeService: " + tx[0] + " " + tx[1] + " " + tx[2]);
    if (_mBluetoothLeService==null)
    {
        Log.d(TAG, "_mBluetoothLeService is null");
    }
    _mBluetoothLeService.writeCharacteristic(characteristic);

}

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

Just for the purpose of testing I ignored byte[] data parameter and I try to send byte[] tx data that I create inside the _SendData function using hexStringToByteArray function (that I found in this StackOverflow post: Convert a string representation of a hex dump to a byte array using Java?)

I also tried to create the tx data as:

byte tx[] = new byte[] { (byte) 0xfe, (byte) 0xfe, (byte) 0xfe };

or to send the data directly like this:

public void _SendData(byte[] data)
{
    Log.d(TAG,"_SendData: ");

    BluetoothGattCharacteristic characteristic = _map.get(RBLService.UUID_BLE_SHIELD_TX);
    Log.d(TAG, "Set data in the _characteristicTx");
    characteristic.setValue(data);

    Log.d(TAG, "Write _characteristicTx in the _mBluetoothLeService: " + data[0] + " " + data[1] + " " + data[2]);
    if (_mBluetoothLeService==null)
    {
        Log.d(TAG, "_mBluetoothLeService is null");
    }
    _mBluetoothLeService.writeCharacteristic(characteristic);

}

In all the cases I failed to send the data.

I really can't understand why this is happening. The code I am using to search ble devices, establish connection, send receive data is very similar to the Android native samples available in ReadBearLab github page: https://github.com/RedBearLab/Android/tree/master/Examples

The only difference is that I am not extending Activity. I tried to make BleFramework class an extension of Activity but it didn't work. The problem I had was that while BleFramework activity was running I was not able to send messages back to Unity using the UnityPlayer.UnitySendMessage function.

Community
  • 1
  • 1
kaharoth
  • 160
  • 1
  • 9

1 Answers1

0

I answer my own question just for reference if anybody is interested in the solution I found. I fixed the bug by updating the code to the latest Android APIs. Please check out the commits from June 15th 2019 to June 22nd 2019 in the repository if you are interested in the modifications. In particular the commit named "Android tx/rx works" https://github.com/giomurru/ble-framework

kaharoth
  • 160
  • 1
  • 9