Android Question Translate SDK RFID Bluetooth Reader to B4A

Christian García S.

Active Member
Licensed User
Hello Everyone,

I was making a connection with a Bluetooth RFID Reader via bluetooth admin and serial, as described in the following tutorial.

https://www.b4x.com/android/forum/threads/android-bluetooth-bluetoothadmin-tutorial.14768/

But I receive a timeout with the following error:

B4X:
java.io.IOException: read failed, socket might closed or timeout, read ret: -1
    at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:916)
    at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:928)
    at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:536)
    at anywheresoftware.b4a.objects.Serial$1.run(Serial.java:157)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:762)
connected: false

The reader comes with its own SDK, they send you the sources and an apk so you can make the connection with your own APP, I have tried that app on the phone and it works, connects correctly and reads the rfid tags.

I have read the java code of that sdk, but I can not identify any parameters to change in the connection so that it is successful with bluetooth admin.

I do not know if you can help me check the connection of that SDK and try to translate it into B4A code so I can exploit the functionality of the RFID and the full power of B4A.

Attached the link sdk https://goo.gl/nP8LBb, can you help me to review those sources ??? I have reviewed the original sources but I can not identify which parameter is different to change.

Also attached a small video https://goo.gl/ayPjKJ testing the application that comes with the reader and that is the application of that SDK to see how it works.

Thank you very much in advance.
 
Last edited:

Christian García S.

Active Member
Licensed User
Hello,

After reading some posts I tried with BLE 2 now I and can connect with reader. :)

I was reading manual and I need send EPC C1G2 COMMAND (manual https://goo.gl/nPi8rK) for getting RFID tags.

The command I have to send, first to get Reader Info:

B4X:
Sub Command_GetReaderInfo

 
    Dim Msg() As Byte
 
'    aStream.Write(Array As Byte (2,Asc("?"),Asc("s"),Asc("t"),3,Asc("3"),Asc("5")))
    Dim cmdSecv As List
 
    cmdSecv.Initialize
                      
    cmdSecv.Add(0x04)
    cmdSecv.Add(0xFF)
    cmdSecv.Add(0x21)
    cmdSecv.Add(0x19)
    cmdSecv.Add(0x95)
 
    Msg = ListToBytes(cmdSecv) 
      
    manager.WriteData("0000180a-0000-1000-8000-00805f9b34fb","00002a50-0000-1000-8000-00805f9b34fb",Msg)
End Sub

based in this code from SDK

B4X:
public static int GetReaderInfo(byte[]Version,byte[] Power,byte[] Fre)
{
byte[] Msg = new byte[6];
Msg[0] = 0x04;
Msg[1] = (byte)0xFF;
Msg[2] = 0x21;
Msg[3] = 0x19;
Msg[4] = (byte)0x95;
CmdTime=500;
MyService.target_chara.setValue(Msg);
ArrayClear(RecvBuff,5000);
RecvLength=0;
MyService.RecvString="";
mBluetoothLeService.writeCharacteristic(MyService.target_chara);
if(GetData()==0){
       ComAddr = RecvBuff[1];
       Version[0] = RecvBuff[4];
       Version[1] = RecvBuff[5];
       Power[0] = RecvBuff[10];
       Fre[0] = RecvBuff[8];
       Fre[1] = RecvBuff[9];
          return RecvBuff[3];
       }
return -1;
}

But now I do not know which Characteristic I have to use, I get error message.

I wrote this code based in this example https://www.b4x.com/android/forum/threads/ble-2-bluetooth-low-energy.59937/#post-381524 for knowing the characteristics.

B4X:
Sub Manager_DataAvailable (ServiceId As String, Characteristics As Map)
    Log("***********************************")
    Log("Serviceid: "&ServiceId & " Char: "&Characteristics)
  
  
    For Each k As String In Characteristics.Keys
'        Log(k)
        Dim data1() As Byte = Characteristics.get(k)
        Dim bc As ByteConverter
'        Log("Data")
        Log("Key: " & k & " -> Value: " & bc.HexFromBytes(data1))  
      
        PrintCharProperties(k, manager.GetCharacteristicProperties(ServiceId, k))
          
    Next          
  
    CallSub3(Main, "DataAvailable", ServiceId, Characteristics)
End Sub

Sub PrintCharProperties(Characteristic As String, Properties As Int)
    Log($"${Characteristic} Properties:"$)
    Dim props As Map = CreateMap(1: "Broadcast", 2: "Read", 4: "WriteWithoutResponse", 8: "Write", _
     0x10: "Notify")
    For Each key As Int In props.Keys
        If Bit.And(Properties, key) <> 0 Then Log(props.Get(key))
    Next
End Sub

This is Output:

B4X:
***********************************
***********************************
Serviceid: 00001801-0000-1000-8000-00805f9b34fb Char: (MyMap) {00002a05-0000-1000-8000-00805f9b34fb=[B@bd065c8}
Key: 00002a05-0000-1000-8000-00805f9b34fb -> Value:
00002a05-0000-1000-8000-00805f9b34fb Properties:
***********************************
Serviceid: 00001800-0000-1000-8000-00805f9b34fb Char: (MyMap) {00002a00-0000-1000-8000-00805f9b34fb=[B@2202586, 00002a01-0000-1000-8000-00805f9b34fb=[B@ec2fe47, 00002a02-0000-1000-8000-00805f9b34fb=[B@46a1674, 00002a04-0000-1000-8000-00805f9b34fb=[B@5bb179d, 00002a03-0000-1000-8000-00805f9b34fb=[B@2491412}
Key: 00002a00-0000-1000-8000-00805f9b34fb -> Value: 554254313735323939313742
00002a00-0000-1000-8000-00805f9b34fb Properties:
Read
Key: 00002a01-0000-1000-8000-00805f9b34fb -> Value: 0000
00002a01-0000-1000-8000-00805f9b34fb Properties:
Read
Key: 00002a02-0000-1000-8000-00805f9b34fb -> Value: 00
00002a02-0000-1000-8000-00805f9b34fb Properties:
Read
Write
Key: 00002a04-0000-1000-8000-00805f9b34fb -> Value: 5000A0000000E803
00002a04-0000-1000-8000-00805f9b34fb Properties:
Read
Key: 00002a03-0000-1000-8000-00805f9b34fb -> Value:
00002a03-0000-1000-8000-00805f9b34fb Properties:
Write
***********************************
Serviceid: 0000180a-0000-1000-8000-00805f9b34fb Char: (MyMap) {00002a23-0000-1000-8000-00805f9b34fb=[B@52737e3, 00002a24-0000-1000-8000-00805f9b34fb=[B@14c25e0, 00002a25-0000-1000-8000-00805f9b34fb=[B@c369099, 00002a26-0000-1000-8000-00805f9b34fb=[B@2a05f5e, 00002a27-0000-1000-8000-00805f9b34fb=[B@c0b6f3f, 00002a28-0000-1000-8000-00805f9b34fb=[B@67dc00c, 00002a29-0000-1000-8000-00805f9b34fb=[B@9569d55, 00002a2a-0000-1000-8000-00805f9b34fb=[B@28f136a, 00002a50-0000-1000-8000-00805f9b34fb=[B@cd1c05b}
Key: 00002a23-0000-1000-8000-00805f9b34fb -> Value: 3F05110000831500
00002a23-0000-1000-8000-00805f9b34fb Properties:
Read
Key: 00002a24-0000-1000-8000-00805f9b34fb -> Value: 4D6F64656C204E756D62657200
00002a24-0000-1000-8000-00805f9b34fb Properties:
Read
Key: 00002a25-0000-1000-8000-00805f9b34fb -> Value: 53657269616C204E756D62657200
00002a25-0000-1000-8000-00805f9b34fb Properties:
Read
Key: 00002a26-0000-1000-8000-00805f9b34fb -> Value: 4669726D77617265205265766973696F6E00
00002a26-0000-1000-8000-00805f9b34fb Properties:
Read
Key: 00002a27-0000-1000-8000-00805f9b34fb -> Value: 4861726477617265205265766973696F6E00
00002a27-0000-1000-8000-00805f9b34fb Properties:
Read
Key: 00002a28-0000-1000-8000-00805f9b34fb -> Value: 536F667477617265205265766973696F6E00
00002a28-0000-1000-8000-00805f9b34fb Properties:
Read
Key: 00002a29-0000-1000-8000-00805f9b34fb -> Value: 4D616E756661637475726572204E616D6500
00002a29-0000-1000-8000-00805f9b34fb Properties:
Read
Key: 00002a2a-0000-1000-8000-00805f9b34fb -> Value: FE006578706572696D656E74616C
00002a2a-0000-1000-8000-00805f9b34fb Properties:
Read
Key: 00002a50-0000-1000-8000-00805f9b34fb -> Value: 010D0000001001
00002a50-0000-1000-8000-00805f9b34fb Properties:
Read
***********************************
Serviceid: 0000ffe0-0000-1000-8000-00805f9b34fb Char: (MyMap) {0000ffe1-0000-1000-8000-00805f9b34fb=[B@f4cd0f8}
Key: 0000ffe1-0000-1000-8000-00805f9b34fb -> Value: 06
0000ffe1-0000-1000-8000-00805f9b34fb Properties:
Read
WriteWithoutResponse
Write
Notify

I read this in SDK, but I don't have this variable mBluetoothGatt in B4A.

B4X:
public void getCharacteristicDescriptor(BluetoothGattDescriptor descriptor)
    {
         if (mBluetoothAdapter == null || mBluetoothGatt == null) {
             Log.w(TAG, "BluetoothAdapter not initialized");
             return;
         }
        
         mBluetoothGatt.readDescriptor(descriptor);
    }


Can someone help me know what characteristic I should use for each option???

EPC C1G2 COMMAND
  1. Inventory
  2. Read Data
  3. Write Data
  4. Write EPC
  5. etc.

Thanks in advance.
 
Last edited:
Upvote 0

Christian García S.

Active Member
Licensed User
Thanks Erel,

Right, that was the characteristic now I'm trying to write the values to that characteristic.

I am using the following function:

B4X:
Sub Command_GetReaderInfo
 
    Dim Msg() As Byte
    Dim ServiceId As String              = "0000ffe0-0000-1000-8000-00805f9b34fb"
    Dim Characteristic As String          = "0000ffe1-0000-1000-8000-00805f9b34fb"
 
    Log("Write data: ")

    Msg = Array As Byte (0x04,0xFF,0x21,0x19,0x95)
 
    manager.WriteData(ServiceId,Characteristic,Msg)
    ReadData
End Sub

Based on the function of the SDK:
B4X:
public static int GetReaderInfo(byte[]Version,byte[] Power,byte[] Fre)
{
byte[] Msg = new byte[6];
Msg[0] = 0x04;
Msg[1] = (byte)0xFF;
Msg[2] = 0x21;
Msg[3] = 0x19;
Msg[4] = (byte)0x95;
CmdTime=500;
MyService.target_chara.setValue(Msg);
ArrayClear(RecvBuff,5000);
RecvLength=0;
MyService.RecvString="";
mBluetoothLeService.writeCharacteristic(MyService.target_chara);
if(GetData()==0){
       ComAddr = RecvBuff[1];
       Version[0] = RecvBuff[4];
       Version[1] = RecvBuff[5];
       Power[0] = RecvBuff[10];
       Fre[0] = RecvBuff[8];
       Fre[1] = RecvBuff[9];
          return RecvBuff[3];
       }

But when I use function ReadData

B4X:
Public Sub ReadData
    For Each s As String In ConnectedServices
        manager.ReadData(s)
     
    Next
End Sub

You can guide me if I am writing the values correctly (0xFF and 0x95 In SDK are (byte)0xFF, (byte)0x95) or if I have to obtain them in another way.

I receive empty values:

B4X:
Write data:
Serviceid: 00001801-0000-1000-8000-00805f9b34fb Char: (MyMap) {00002a05-0000-1000-8000-00805f9b34fb=[B@960dee6}
***********************************
Key: 00002a05-0000-1000-8000-00805f9b34fb -> Value:
Key: 00002a05-0000-1000-8000-00805f9b34fb -> Value:
00002a05-0000-1000-8000-00805f9b34fb Properties:

Thank you.
 
Last edited:
Upvote 0

Christian García S.

Active Member
Licensed User
If I put

B4X:
manager.WriteData(ServiceId,Characteristic,Msg)
manager.SetIndication(ServiceId, Characteristic,True)

I receive this

B4X:
Write data:
Setting descriptor. Success = true
writing descriptor: true
Serviceid: 00001801-0000-1000-8000-00805f9b34fb Char: (MyMap) {00002a05-0000-1000-8000-00805f9b34fb=[B@8d15c0e}
***********************************
Key: 00002a05-0000-1000-8000-00805f9b34fb -> Value:
Key: 00002a05-0000-1000-8000-00805f9b34fb -> Value:
Serviceid: 0000ffe0-0000-1000-8000-00805f9b34fb Char: (MyMap) {0000ffe1-0000-1000-8000-00805f9b34fb=[B@ff7443c}
***********************************
Key: 0000ffe1-0000-1000-8000-00805f9b34fb -> Value: 110021000201100231801A0A010100004231

Is this (110021000201100231801A0A010100004231) the answer ??? If the answer is YES, how can I decode these values? In sdk there are some functions GetData,
getCRC, CheckCRC

Thanks
 

Attachments

  • upload_2018-2-22_17-49-14.png
    upload_2018-2-22_17-49-14.png
    26.4 KB · Views: 307
  • upload_2018-2-22_17-49-43.png
    upload_2018-2-22_17-49-43.png
    47.8 KB · Views: 326
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
B4X:
    Msg = Array As Byte (0x04,0xFF,0x21,0x19,0x95)
 
    manager.WriteData(ServiceId,Characteristic,Msg)
This code correctly writes the 5 bytes.

Is this (110021000201100231801A0A010100004231) the answer ???
This is the characteristic value.

If the answer is YES, how can I decode these values?
You will need to go over the SDK code and do the same thing in your B4A code. Each implementation is different.
 
Upvote 0

Christian García S.

Active Member
Licensed User
Thanks Erel, now I can read and write characteristics.

I am searching how to read data, in a post https://www.b4x.com/android/forum/threads/rfid-reader-connection.73322/#post-465827 you wrote "Make sure to initialize AsyncStreams in non-prefix mode"

I am trying the way to connect AsyncStreams, but I just found examples with Bluetooth Admin and serial.

I tried with serial, but the connection gives error.

B4X:
Sub Process_Globals

Public manager As BleManager2
Dim BTConnection As Serial
Dim Astream As AsyncStreams

End Sub

Sub Manager_DeviceFound (Name As String, Id As String, AdvertisingData As Map, RSSI As Double)
    Log("Found: " & Name & ", " & Id & ", RSSI = " & RSSI & ", " & AdvertisingData)
manager.StopScan
        manager.Connect2(Id, False) 'disabling auto connect can make the connection quicker
        BTConnection.Initialize("RFIDreader")
        BTConnection.Connect(Id)
End Sub

Sub RFIDreader_Connected (Success As Boolean)
    If Success Then
        Log("RFID conectado")
        Astream.Initialize(BTConnection.InputStream,Null,"RFIDreaderAs")
    Else
        ToastMessageShow("RFID no encontrado...",False)
    End If
End Sub

Can you help me with where or how I can get the data, with asyncstreams or by other way.

Thanks
 
Last edited:
Upvote 0

Christian García S.

Active Member
Licensed User
Thanks Erel,

I'm not sending the proper command to read the inventory, can you help me review it please ????

Manual is this https://goo.gl/nPi8rK, and java code (https://goo.gl/nP8LBb) is:

B4X:
public static void getCRC(byte[] data,int Len)
{
int i, j;
int current_crc_value = 0xFFFF;
for (i = 0; i <Len ; i++)
{
    current_crc_value = current_crc_value ^ (data[i] & 0xFF);
    for (j = 0; j < 8; j++)
    {
        if ((current_crc_value & 0x01) != 0)
            current_crc_value = (current_crc_value >> 1) ^ 0x8408;
        else
            current_crc_value = (current_crc_value >> 1);
    }
}
data[i++] = (byte) (current_crc_value & 0xFF);
data[i] = (byte) ((current_crc_value >> 8) & 0xFF);
}
public static int Inventory_G2(byte QValue,byte Session, byte AdrTID, byte LenTID,
             byte TIDFlag,int[] CardNum,byte[] EPCList,int[] EPCLength) {
         byte[] Msg=new byte[10];
         Msg[1]=(byte)(ComAddr & 255);
         Msg[2]=1;
         Msg[3]=QValue;
         Msg[4]=Session;
         if(TIDFlag==0)
         {
             Msg[0]=6;
             getCRC(Msg,5);
         }
         else
         {
             Msg[0]=8;
             Msg[5]=AdrTID;
             Msg[6]=LenTID;
             getCRC(Msg,7);
         }
         MyService.target_chara.setValue(Msg);;
         ArrayClear(RecvBuff,300);
         RecvLength=0;
         MyService.RecvString="";
         mBluetoothLeService.writeCharacteristic(MyService.target_chara);
         Log.d("Write data:", "AAAAAAAAAAAAAAAAA");
         if(GetInventoryData()==0)
         {
                byte[]szBuff=new byte[3000];
                byte[]szBuff1=new byte[3000];
                memcpy(RecvBuff,0,szBuff,0,RecvLength);
                int Nlen=0;
                while(RecvLength>0)
                {
                    int nLenszBuff=(szBuff[0]&255)+1;
                    if((szBuff[3]==0x01)||(szBuff[3]==0x02)||(szBuff[3]==0x03)||(szBuff[3]==0x04))
                    {
                        //*Ant=szBuff[4];
                        CardNum[0]+=(szBuff[5]&255);
                        memcpy(szBuff,6,szBuff1,Nlen,(szBuff[0]&255)-7);   
                        Nlen+=((szBuff[0]&255)-7);
                        if((RecvLength-(szBuff[0]&255)-1)>0)
                        {
                            byte[]daw=new byte[3000];
                            memcpy(szBuff,(szBuff[0]&255)+1,daw,0,RecvLength-(szBuff[0]*255)-1);
                            ArrayClear(szBuff,3000);
                            memcpy(daw,0,szBuff,0,RecvLength-(szBuff[0]*255)-1);
                        }
                    }
                    RecvLength=RecvLength-nLenszBuff;
                }
                memcpy(szBuff1,0,EPCList,0,Nlen);
                EPCLength[0]=Nlen;
                return  szBuff[3];
         }
         return 0x30;
    }

These is my code:

B4X:
Sub Command_GetReaderInfo   
    Dim Msg() As Byte

    Log("Write data: ")

    Msg = Array As Byte (0x04, 0xFF,0x21,0x19,0x95)
 
    manager.WriteData(ServiceId_G,Characteristic_G,Msg)
    manager.SetNotify(ServiceId_G,Characteristic_G, True)
    SetCommand = 1
    ReadData
End Sub

Sub Command_Inventory_G2
 
    Dim Msg() As Byte

    Log("Write data: ")

    'Msg = Array As Byte (0,1,2,3,4)
     Msg = Array As Byte (0x06,ComAddr & 255 ,0x01,0x04,0x00,0x00,0x00)
 
    manager.WriteData(ServiceId_G,Characteristic_G,Msg)
    manager.SetNotify(ServiceId_G,Characteristic_G, True)
    SetCommand = 2
    ReadData
End Sub

Sub memcpy (SourceByte() As Byte, StartBit_1 As Int, StartBit_2 As Int, Length As Int) As Byte()
    Dim TargetByte(Length) As Byte
 
    For m = 0 To Length-1
        TargetByte(StartBit_1+m) = SourceByte(StartBit_1+m)
    Next
 
    Return TargetByte
End Sub

Sub Manager_DataAvailable (ServiceId As String, Characteristics As Map)
 
    Log("Serviceid: "&ServiceId & " Char: "&Characteristics)
 
    For Each k As String In Characteristics.Keys
        Dim data1() As Byte = Characteristics.get(k)
        Dim bc As ByteConverter
        Log("***********************************")
        Log("Key: " & k & " -> Value: " & bc.HexFromBytes(data1))
        Log("Key: " & k & " -> Value: " & data1)

        If ServiceId = ServiceId_G And k = Characteristic_G Then
            Dim RecvBuff(), Version(2), PowerV(1), Fre(2) As Byte
   
            If SetCommand = 1 Then
                RecvBuff = memcpy(data1,0,0,data1.Length)
                ComAddr = RecvBuff(1)
                Version(0) = RecvBuff(4)
                Version(1) = RecvBuff(5)
                PowerV(0) = RecvBuff(10)
                Fre(0) = RecvBuff(8)
                Fre(1) = RecvBuff(9)
                Command_Inventory_G2
            End If
   
        End If   
 
'        PrintCharProperties(k, manager.GetCharacteristicProperties(ServiceId, k))
    Next       
    CallSub3(Main, "DataAvailable", ServiceId, Characteristics)
End Sub

Thanks
 
Last edited:
Upvote 0
Hello @Christian García S.

I am lost with that same SDK.
Did you solve your doubts?
I already spent a week trying to solve it.

Thank you,
Guilherme

PS: I'm trying to translate that SDK using Flutter and the FlutterBlue plugin. Although it is different technology, my doubts are similar to yours.
 
Upvote 0
Top