Indy 10 IdTCPSever Readbytes scrambling data - delphi

I am trying to use Indy10 ReadBytes() in Delphi 2007 to read a large download of a series of data segments formatted as [#bytes]\r\n where #bytes indicates the number of bytes. My algorithm is:
Use ReadBytes() to get the [#]\r\n text, which is normally 10 bytes.
Use ReadBytes() to get the specified # data bytes.
Go to step 1 if more data segments need to be processed, i.e., # is negative.
This works well but frequently I don't get the expected text at step 1. Here's a short example after 330 successful data segments:
Data received from last step 2 ReadBytes(). NOTE embedded Step 1 [-08019]\r\n text.
Line|A033164|B033164|C033164|D033164|E033164|F033164|G033164|H033164|EndL\r|Begin
Line|A033165|B033165|C033165|D033165|E033165|F033165|G033165|H033165|EndL\r|Begin
Line|A033166|B033166|C033166|D033166|E033166|F033166|G033166|H033166|EndL\r[-08019]
\r\n|Begin
Line|A033167|B033167|C033167|D033167|E033167|F033167|G033167|H033167|EndL\r|Begin
Line|A033168|B033168|C033168|D033168|E033168|F033168|G033168|H033168|EndL\r|Begin
Socket data captured by WireShark.
0090 30 33 33 31 36 36 7c 42 30 33 33 31 36 36 7c 43 033166|B033166|C
00a0 30 33 33 31 36 36 7c 44 30 33 33 31 36 36 7c 45 033166|D033166|E
00b0 30 33 33 31 36 36 7c 46 30 33 33 31 36 36 7c 47 033166|F033166|G
00c0 30 33 33 31 36 36 7c 48 30 33 33 31 36 36 7c 45 033166|H033166|E
00d0 6e 64 4c 0d ndL.
No. Time Source Destination Protocol Length Info
2837 4.386336000 000.00.247.121 000.00.172.17 TCP 1514 40887 > 57006 [ACK] Seq=2689776 Ack=93 Win=1460 Len=1460
Frame 2837: 1514 bytes on wire (12112 bits), 1514 bytes captured (12112 bits) on interface 0
Ethernet II, Src: Cisco_60:4d:bf (e4:d3:f1:60:4d:bf), Dst: Dell_2a:78:29 (f0:4d:a2:2a:78:29)
Internet Protocol Version 4, Src: 000.00.247.121 (000.00.247.121), Dst: 000.00.172.17 (000.00.172.17)
Transmission Control Protocol, Src Port: 40887 (40887), Dst Port: 57006 (57006), Seq: 2689776, Ack: 93, Len: 1460
Data (1460 bytes)
0000 5b 2d 30 38 30 31 39 5d 0d 0a 7c 42 65 67 69 6e [-08019]..|Begin
0010 20 4c 69 6e 65 7c 41 30 33 33 31 36 37 7c 42 30 Line|A033167|B0
0020 33 33 31 36 37 7c 43 30 33 33 31 36 37 7c 44 30 33167|C033167|D0
0030 33 33 31 36 37 7c 45 30 33 33 31 36 37 7c 46 30 33167|E033167|F0
Does anyone know why this happens? Thanks
More information. We do socket reading from a single thread and don't call Connected() while reading. Here's relevant code snippet:
AClientDebugSocketContext.Connection.Socket.ReadBytes(inBuffer,byteCount,True);
numBytes := Length(inBuffer);
Logger.WriteToLogFile(BytesToString: '+BytesToString(inBuffer,0,numBytes),0);
Move(inBuffer[0], Pointer(Integer(Buffer))^, numBytes);

Embedded data like you describe, especially at random times, usually happens when you read from the same socket in multiple threads at the same time without adequate synchronization between them. One thread may receive a portion of the incoming data, and another thread may receive another portion of the data, and they end up storing their data in the InputBuffer in the wrong order. Hard to say for sure if that your problem since you did not provide any code. The best option is to make sure you never read from the same socket in multiple threads at all. That includes any calls to Connected(), since it performs a read operation internally. You should do all of your reading within a single thread. If that is not an option, then at least wrap your socket I/O with some kind of inter-thread lock, such as a critical section or mutex.
Update: You are accessing a TIdContext object via your own AClientDebugSocketContext variable. Where is that code being used exactly? If it is not in the context of the server's OnConnect, OnDisconnect, OnExecute, or OnException events, then you are reading from the same socket across multiple threads, because TIdTCPServer internally calls Connected() (which does a read) in between calls to the OnExecute event for that TIdContext object.

Related

MavLink ArduPilot - Can’t parse PARAM_VALUE request

My friend and I are trying to communicate with a drone (APM 2.8 flight controller - ArduCopter V3.2.1 (36b405fb)) with MavLink. After several hours, we managed to handle messages and make ByteBuffers a little more meaningful but we're stuck on parsing one response that seems to didn’t fit with the documentation.
When performing a PARAM_REQUEST_LIST request, the APM sends back (a lot of) PARAM_VALUE (#22) responses, but the format of what we're receiving is really not what we’ve expected
The payload
<Buffer cd cc 4c 3f 32 01 36 00 45 4b 46 5f 43 48 45 43 4b 5f 54 48 52 45 53 48 09>
The expected object (doc)
PARAM_VALUE
{
param_id char[16]
param_value float
param_type uint8_t
param_count uint16_t
param_index uint16_t
}
So param_id = cd cc 4c 3f 32 01 36 00 45 4b 46 5f 43 48 45 43 = ÍÌL?2(soh)6(nul)EKF_CHEC
Although the 8 last characters are OK, it seems that the first 8 characters are absolutely everything but not the beginning of a char[16] - by the way the 8th is always (nul) … And it’s the same for a param_count = 17747 when param_index = 18441 (?!), the different param_count values in every response, or param_type=82 when this value must be 0 < x <= 10 (doc)
We already managed to parse other requests without any problem so we thought we’d understood the way MavLink works but I'm doubting right now … Did we miss something obvious ? Or is there a problem with the drone ?
For those who encountered the same problem, this page is the answer. According to this, my object looks more like that when reordered
PARAM_VALUE
{
param_value float
param_count uint16_t
param_index uint16_t
param_id char[16]
param_type uint8_t
}
So param_id = 45 4b 46 5f 43 48 45 43 4b 5f 54 48 52 45 53 48 = EKF_CHECK_THRESH

Convert log file to PCAP

I have some log file that I want to convert to PCAP file format to be opened in Wireshark. The log file is UDS (Unified Diagnostic Services) log of a car firmware update. What is the best practice to do that?
The log file lines look like this:
***BUSMASTER Ver 3.2.1***
***PROTOCOL CAN***
***NOTE: PLEASE DO NOT EDIT THIS DOCUMENT***
***[START LOGGING SESSION]***
***START DATE AND TIME 4:6:2018 9:2:12:212***
***HEX***
***SYSTEM MODE***
***START CHANNEL BAUD RATE***
***CHANNEL 2 - Kvaser - Kvaser USBcan Pro 5xHS #0 (Channel 1), Serial Number- 0, Firmware- 0x0000013b 0x00030007 - 500000 bps***
***END CHANNEL BAUD RATE***
***START DATABASE FILES***
***END DATABASE FILES***
***<Time><Tx/Rx><Channel><CAN ID><Type><DLC><DataBytes>***
00:00:00:0000 Rx 2 0x064 s 8 20 20 20 20 20 20 20 20
00:00:00:0574 Rx 2 0x7cd s 8 4d 72 2e 20 61 6e 64 20
00:00:00:0952 Rx 2 0x7df s 8 02 01 00 00 00 00 00 00
00:00:00:1457 Rx 2 0x05b s 8 ad dc 0b cc 0a c3 49 40
00:00:00:2069 Rx 2 0x05c s 8 63 d3 4a 21 90 4b c4 bf
00:00:00:2649 Rx 2 0x7cd s 8 4d 72 73 2e 20 44 75 72

ESCPOS Datamatrix command

I am trying to print a Datamatrix barcode using an EPSON m30 Printer.
When the following HEX values are transmitted, no action is taken.
I was able to get this HEX value from the page below.
https://download.epson-biz.com/modules/ref_escpos/index.php?content_id=170
1d 28 6b 0d 00 36 50 30 31 32 33 34 35 36 37 38 39 30
1d 28 6b 03 00 36 54 30 0d 0a
Can you please let me know if something is wrong?
thanks
Maybe the description on the reference page is incorrect.
For example, the printing of the Aztec code is Function 581, which is 35 51 30.
The second byte of other barcodes is 51.
By analogy, there is a possibility of 36 51 30 instead of 36 54 30.
Please try sending the following command.
Q:
1d 28 6b 0d 00 36 50 30 31 32 33 34 35 36 37 38 39 30 1d 28 6b 03 00 36 54 30 0d 0a
A:
1d 28 6b 0d 00 36 50 30 31 32 33 34 35 36 37 38 39 30 1d 28 6b 03 00 36 51 30 0d 0a

Websocket - Chrome complaining about mask bit set

I have implemented a websocket server in my existing server. Handshake is good and then I can even send first message and client browser receives it. But any subsequent messages disconnect websocket. On chrome I get following error.
failed: A server must not mask any frames that it sends to the client.
My frame is created like this
Len = erlang:size(Msg),
if
Len < 126 ->
Message = [<<1:1, 0:3,2:4,0:1,Len:7>>,Msg];
Len < 65536 ->
Message = [<<1:1, 0:3,2:4,0:1,126:7,Len:16>>,Msg];
true ->
Message = [<<1:1, 0:3,2:4,0:1,127:7,Len:64>>,Msg]
end,
Now one sample data to be transmitted looks like this
<<130,46,60,115,110,112,95,105,110,102,111,32,97,118,95,112,111,116,61,34,49,49,34,32,104,97,110,100,115,95,112,101,114,95,104,111,117,114,61,34,48,46,50,48,34,32,47,62>>
As you can see in the code above, my mask bit is always set to 0, but I don't why the same message works for the first time and then I send the same message again, it complains about mask bit set.
Anybody got any idea why?
Thanks
The frame sample data you pasted is sane.
48 bytes
ErlangSampleBytes[48] = 82 2E 3C 73 6E 70 5F 69 6E 66 6F 20 61 76 5F 70
6F 74 3D 22 31 31 22 20 68 61 6E 64 73 5F 70 65
72 5F 68 6F 75 72 3D 22 30 2E 32 30 22 20 2F 3E
It Parses/Translates to:
82 = fin:true
rsv1:false
rsv2:false
rsv3:false
opcode:2
2E = masked:false
payloadLength:46 (decimal)
Payload = UTF8 valid:
<snp_info av_pot="11" hands_per_hour="0.20" />
You don't even have a mismatch on the payload length declaration and what is left in the sample buffer.
At this point, it would be wise to look at the chrome inspection tooling to find out what the frames it thinks it got. And a next step after that would be to try to capture the network traffic with a tool like WireShark in an effort to see what is going on.
Suspect that the # of bytes you are sending on the wire, vs what you are declaring in the payloadLength are differing. (common one i've seen is sending more bytes than you declare)
Such as allocating a buffer of 1024 bytes, filling in the first 48 properly, then sending the entire 1024 bytes. That will mess parsing of the next frame.

Delphi (2009) - Converting AnsiString reading or preserving line breaks?

Using this (test) code to read a tEXt chunk from a PNG:
procedure TForm1.Button1Click(Sender: TObject);
var
PngVar: TPngImage;
n: Integer;
begin
PngVar := TPNGImage.Create;
PngVar.LoadFromFile('C:\test.png');
for n := 0 to pred(PngVar.Chunks.count) do
if PngVar.Chunks.item[n].Name='tEXt' then
with PngVar.Chunks.item[n] as TChunkTEXT do
memo1.lines.add(KeyWord+'='+Text);
end;
The code is from an example by the original author of the TPNGObject and was downloaded from embercardo's website. KeyWord contains the value of what the tEXt chunk is, in this case comment. Text contains the text we need. It is an AnsiString and should have breaks in them but when casting from AnsiString to unicode they are lost and it becomes one string with not even a space between the end and start of a line.
Stepping through the debugger I noticed It had each line in single quotes and between the lines it has #$A which I assume if I check in hex are some form of control character.
comment=PunkBuster Screenshot (ñ) BF3 Levels/MP_017/MP_017'#$A'1135998 31.204.131.11:25530 GoTBF3.nl #4 | 32p | TDM Canals Only | 500 Tickets'#$A'geawtaw46y4w63a46a34643a BorislavFatsolka'#$A'Attempted: w=320 X h=240 at (x=50%,y=50%)'#$A'Resulting: w=320 X h=200 sample=1'
Sample Image
http://www.pbbans.com/pbss_evidence/bf3/31.204.131.11:25530/5d00a95d22fae4a287bd510c076db1bf-2e36c3b4.png
Here is the sample. What I am doing is reading data off punkbuster images to make them searchable in our communities database. But I also display the information next to the image and id like to have the line breaks and or know when the line ends.
When placed into memo or string list directly it comes out all one line like:
comment=PunkBuster Screenshot (ñ) BF3 Levels/MP_017/MP_0171135998 31.204.131.11:25530 GoTBF3.nl #4 | 32p | TDM Canals Only | 500 Tickets*geawtaw46y4w63a46a34643a* BorislavFatsolkaAttempted: w=320 X h=240 at (x=50%,y=50%)Resulting: w=320 X h=200 sample=1
Question
What is the best way to handle this ansistring which is what it is from the original image and or TPNGImage no real choice there. Putting it into a memo, rich edit or string list with the breaks intact.
The first thing that comes to mind is probably inefficient and thats just to throw it into a byte array or the like and read it byte by byte cutting each line at the end of line marks.
More Data from the example
You should be able to see this by downloading the example image but, this is how it looks in a hex editor (First part of the file intact, png header, tEXt chunk header keyword etc.
‰PNG........IHDR...Ž...2.....ûŒÆ$....tEXtcomment.PunkBuster Screenshot (ñ) BF3 Levels/MP_017/MP_017.1135998 31.204.131.11:25530 GoTBF3.nl #4 | 32p | TDM Canals Only | 500 Tickets.*geawtaw46y4w63a46a34643a* BorislavFatsolka.Attempted: w=320 X h=240 at (x=50%,y=50%).Resulting: w=320 X h=200 sample=1.
89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 02 8E 00 00 01 32 08 02 00 00 00 FB 8C C6 24 00 00 01 03 74 45 58 74 63 6F 6D 6D 65 6E 74 00 50 75 6E 6B 42 75 73 74 65 72 20 53 63 72 65 65 6E 73 68 6F 74 20 28 F1 29 20 42 46 33 20 20 4C 65 76 65 6C 73 2F 4D 50 5F 30 31 37 2F 4D 50 5F 30 31 37 0A 31 31 33 35 39 39 38 20 33 31 2E 32 30 34 2E 31 33 31 2E 31 31 3A 32 35 35 33 30 20 47 6F 54 42 46 33 2E 6E 6C 20 23 34 20 7C 20 33 32 70 20 7C 20 54 44 4D 20 43 61 6E 61 6C 73 20 4F 6E 6C 79 20 7C 20 35 30 30 20 54 69 63 6B 65 74 73 0A 2A 67 65 61 77 74 61 77 34 36 79 34 77 36 33 61 34 36 61 33 34 36 34 33 61 2A 20 42 6F 72 69 73 6C 61 76 46 61 74 73 6F 6C 6B 61 0A 41 74 74 65 6D 70 74 65 64 3A 20 77 3D 33 32 30 20 58 20 68 3D 32 34 30 20 61 74 20 28 78 3D 35 30 25 2C 79 3D 35 30 25 29 0A 52 65 73 75 6C 74 69 6E 67 3A 20 77 3D 33 32 30 20 58 20 68 3D 32 30 30 20 73 61 6D 70 6C 65 3D 31 0A
Other Findings
If I dump the Chunk (PngVar.Chunks.item[n].SaveToStream) it gives me basically what we find in the hex editor. The control characters are 0A. I am not sure if the #$A is a before or after conversion effect maybe even being caused by the pngimage code.
Try:
memo1.lines.add(KeyWord+'='+StringReplace(Text,#10,sLineBreak,[rfReplaceAll]));
Another approach would be Jedi CodeLib
sl := TJclStringList.Create;
sl.Split(Text, #10);
sl[0] := 'Keyword=' +sl[0]
memo1.lines.AddStrings(sl);
sl.Free;

Resources