Packed Records (UDP)

qsrtech

Active Member
Licensed User
Longtime User
Hi, I'm working on an App to work in conjunction (talk) with my windows app written in Delphi. My Delphi app uses (sends) packed records when sending/receiving UDP messages. I need someone to help me with formatting my android UDP messages into the format my Delphi App can uderstand. Here's my Delphi Packed Record:

B4X:
//delphi
Type TNotifyClient=packed record
    TerminalID:integer;
    TransID:integer;
    EventID:integer;
    ProductID:integer;
    Data:string[100];
    AGuestID:integer;
end;

'B4A
Type TNotifyClient(TerminalID,TransID,EventID,ProductID as int,Data(100) as char,AGuestID as int)

I understand it's 120 bytes, but how would I build this in B4A to send it through UDP to my Delphi App? I don't really need the UDP code, just building the packet to be sent....

Thanks!
John
 

PaulR

Active Member
Licensed User
Longtime User
Here's a couple of Subs that although untested, should almost certainly work *cough*... Delphi needs reads little endian so there is an endian swapper there too.
B4X:
Dim os As OutputStream
Dim lastPos As Int  'keep track of last position written to in the outputstream
Dim Conv As ByteConverter     'need ByteConverter library


Sub AddIntToPacket (NewInt As Int)

   Dim IntArray(1) As Int
   IntArray(0) = NewInt
        Dim ba As Byte()
        ba=Conv.IntsToBytes(IntArray)
   os.WriteBytes(SwapEndian(ba), lastPos, 4) '4 is length of an int in bytes
        lastPos=lastPos+4

End Sub

'delphi is little endian, Java/B4a is big endian
Sub SwapEndian(be As Byte()) As Byte()
      
      Dim LEArray(be.Length) As Byte()
      For i = 0 to be.Length-1
           LEArray(i) = be(be.Length-1-i)
      Next
      Return LEArray()

End Sub


'length = desired padded length of string, in this case 100
Sub AddStringToPacket(NewString As String, length As Int)   
   
        If NewString.Length <= length Then
        Do Until NewString.Length = length
              NewString = NewString & Chr(0)
        Loop
        Else
             ToastMessageShow("String too long", True)
        End If
   
   os.WriteBytes(Conv.StringToBytes(NewString, "US-ASCII"), lastPos, length)
        lastPos=lastPos+length
   
End Sub
 
Upvote 0

qsrtech

Active Member
Licensed User
Longtime User
Packed record update

Hi, I tried your code but kept getting an index error. I did have some code I put together while waiting for a response. My problem was I was encoding UTF8 (didn't realize there was other codes, i.e. US-ASCII). Also, not sure but braces needed to be after variable name vs after byte in order to compile your code. My code below works 99% correct. Unfortunately my windows app always misses the first character in the data section. Not sure what's causing it, probably on the Delphi side. Don't have time to really investigate so for now I just plug in a dummy character at the begining and everything is A-OK.

B4X:
bc.LittleEndian=True
Dim aryint(5) As Int
aryint(0)=nc.TerminalID
aryint(1)=nc.TransID
aryint(2)=nc.EventID
aryint(3)=nc.ProductID
aryint(4)=nc.AGuestID
tempbytes=bc.IntsToBytes(aryint)
pos=-1
For a=1 To 16
    pos=pos+1
    SendBytes(pos)=tempbytes(a-1)
Next
Dim tempbytes2() As Byte
tempbytes2=bc.StringToBytes(nc.Data,"US-ASCII")
For a=1 To tempbytes2.Length
    pos=pos+1
    SendBytes(pos)=tempbytes2(a-1)
Next
pos=116
For a=17 To 20
    pos=pos+1
    SendBytes(pos)=tempbytes(a-1)
Next
'need to eventually rearrange the record in all apps so that the "data" is the last field and all int fields are together to simplify and keep things clean
 
Upvote 0
Top