• Welcome to Forum.Deepsoftware.Com. Please login or sign up.
 
March 29, 2024, 09:18:16 am

News:

SMF - Just Installed!


TnrComm.OnAfterReceive

Started by Arne, September 22, 2008, 06:22:47 am

Previous topic - Next topic

Arne

Hello,

I got a question about the OnAfterReceive message. Let's say that my OnAfterReceive procedure is called with parameter Received = 50, but right now I only need 40 bytes because my data-structure I was waiting for on the serial line is only 40 bytes in size, i.e. that the other 10 bytes belong to the beginning of the next datagram. Am I allowed to only get the first 40 bytes and leave the other 10 bytes for the next call into OnAfterReceive or am I forced to 'swallow' all 50 bytes?

thanx, Arne

Roman Novgorodov

September 22, 2008, 12:22:39 pm #1 Last Edit: September 22, 2008, 12:33:23 pm by Roman Novgorodov
Hello

Thank you for your interest to our product and thank you for your detail question.

Your question is not  original :-).

Please read this topic:
"The some notes about OnAfterReceive event ..."
http://deepsoftware.com/groups_dsr/index.php?topic=8.0

Please note that this situation is ordinary. And your software should foresee it for reliable work.

Good luck!

Roman
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.

Arne

Thank you for your reply.

data processing looks interesting. Unfortunately I have 5 different datagrams - all with different header byte (1. byte). Four do have fixed length, but one does not. The length of the whole datagram is always stored in the 3. byte. And no datagram does have a finish marker. All have a CRC 16 in two consecutive bytes at the end.

Do you see any possibility to use TnrDataProcessor with this variable length datagram?

bye, Arne

Roman Novgorodov

Hello

Yes it is possible.
By the way, we implemented the Kermit file transfer protocol by using TnrDataProcessor base class.

So You can add the needed 4 packets with fixed length into DataPackets property.
And add one packet with start byte and handled event OnPacketLength.
In this event handler you can detect expected packet length.

You can see how we did this in our Kermit protocol implementation:


procedure TnrKermit.HandlePacketLength(Packet: TnrDataPacket; chData: byte;
  var IsHandled: Boolean);
begin
  // detect variable datapacket length and set it into needed property ...
  Packet.PacketLength := byte(chData) - 32 + Packet.DataLength;
  IsHandled := True;
end;


It works!

Also you can disable or reset further packets detection if needed packet is received.

Roman Novgorodov
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.

Arne

Hello,

I'm afraid I don't understand fully what you mean. I found the OnPacketLength handler, but I don't know what you are doing in the code example you provided. Is the handler called with every byte received? What is the Packet.DataLength item for? Is it the number of bytes already received for the current packet?

All my datagrams look the same in the first 3 bytes:
1. byte: header byte - different for all 5 datagrams
2. byte: receiver/sender - 4bit for each
3. byte: number of parameters
....
n byte and n+1 byte: CRC16

that means that for the single variable datagram I need to investigate byte no. 3 and set the Packet.PacketLength item accordingly while the packet is received by nrComm. Am I right?

thanx, Arne

Roman Novgorodov

September 23, 2008, 09:12:20 am #5 Last Edit: September 23, 2008, 09:17:14 am by Roman Novgorodov
Hello

I added five packets into DataPackets property of TDataProcessor component.
They contain needed values in PacketBegin properties and 0 (zero) in PacketLength.
All packets have same handler for OnPacketLength event.
The handler of this event waits third byte and fills expected packet length.
Please see sample of code:


procedure TForm1.nrDataProcessor1DataPackets0PacketLength(Packet: TnrDataPacket;
  chData: Byte; var IsHandled: Boolean);
begin
  if Packet.DataLength = 3 then begin
    // now calculate and set the total packet legth ( 3 bytes are already received !!!):
    Packet.PacketLength := Packet.DataLength + Byte(chData);
    IsHandled := True;  // mark that length of packet now is wellknow
  end;
end;

procedure TForm1.nrDataProcessor1DataPacket(Sender: TObject;
  Packet: TnrDataPacket);
begin
  // you can process packets here  - check CRC and etc.
  Memo1.Lines.Add('PACKET is detected!:' + Packet.Caption + ':' + Packet.Data );
end;


Roman Novgorodov
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.

Roman Novgorodov

You asked:
Quote
Just one last question about your code snippet: is chData the byte that was received last? So I just need to evaluate this byte to get to know the length of the packet I will receive?


Yes it is. The chData is last (current received) byte. For example if your packet contains:

ABC..

... the OnPacketLength will be called 3 times (of course if IsHandled is still false):

1st call:
chData = 'A'
Packet.DataLength = 1

2st call:
chData = 'B'
Packet.DataLength = 2

3st call:
chData = 'C'
Packet.DataLength = 3

... and so on.

Roman Novgorodov
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.

Arne

Thank you, Roman.
That's exactly what I need. Just waiting for two 5V(TTL) to RS-232 converters and then I will start testing my program.

bye, Arne