I want to write a mote-mote radio communication program, and want the receiver acknowledges back to the sender. I know the PacketAcknowledgements is recommended, but there are some questions I'm not sure about this interface.
1. If I use it in the sender mote,should i also uses interface Receive in the module of the sender mote
2. Should I write extra code in the receiver mote? Should I use interface PacketAcknowledgements too?
3. command error_t requestAck(message_t *msg) and command bool wasAcked(message_t *msg) should be used when and where
No.
No.
You need to call requestAck on a packet you're about to send just before calling send from interface AMSend or Send. Be sure to check an error code returned by requestAck, because FAIL indicates that the communication layer doesn't support synchronous acknowledgements (it depends on the radio chip and driver you use). Once the packet is sent, i.e., inside event sendDone (or later), call wasAcked, which returns true if the packet was acknowledged by the receiver.
More info in:
https://github.com/tinyos/tinyos-main/blob/master/tos/interfaces/PacketAcknowledgements.nc
Related
I am using CANalyzer.
I am transmitting CAN message using Interactive Generator block. I use IG to modify signals in transmitted message by hand.
I need to automaticaly calculate checksum (the last byte in the message) every time the message is sent. Checksum is calculated from all previous data bytes in the message (message is always 8 bytes long). There is no option in IG to do that.
I need:
Set signals by hand using IG.
Automatically calculate value of the last data byte according to values of preceding data bytes.
I tried to write simple code in CAPL but without success.
I put CAPL Program node after the IG node in the Configuration window and wrote on message event in CAPL script:
on message FooMsg
{
message FooMsg msg1; // FooMsg is name of message in database
msg1 = this; // copy message from IG to temporary variable
// this.byte(7) = 0x11; // not posibble, compiler warning
msg1.byte(7) = 0x11; // constant value just for test
output(msg1); // send message
}
The message is transmitting but the Tx period set in IG is not respected (message is transmitted as fast as possible).
I thought I catch the message generated from IG, modify it and send to CAN bus.
Finally, I redesigned the whole stuff as VioletVynil recommended.
I created panels, add system variables and hooked them to controls on panels, wrote some code in CAPL for calculating checksum and periodic transmit of the message and it runs! Without any problems! And yes additional CRC on the payload is used for additional safety (railway application). I didn't designed communication protocol, I just got it.
I have a configuration setup with two CAN nodes and an attached database. I have added a CANOEILNLVECTOR.dll to both the nodes. By adding this Dll file all my messages are sent cyclic as I see in trace window.
Now I set some value for a signal in a message, For Eg:
variables
{
message Battery_Traction Batt_msg;
}
on start
{
Batt_msg.Isolation_Signal = 0x02; //0x02:On
output(Batt_msg);
}
What I see on trace is: The message is cyclic but only for the first instance the value set by me above appears in trace. For all of the rest times the signal value in the message in set to default.
As seen in the image value 0x02 is sent only once.
I am not sure what could be the problem, as seen in image attached value set by me is only sent once.
When using output you are putting the message directly onto the CAN bus, but you are not changing the value inside of your (simulated) node, so the interaction layer is still sending the old value.
You can change the signal value in the interaction layer by just putting a $ in front of the signal name and set the value.
In your case most likely $Isolation_Signal = 0x02
Outputting the message on the CAN bus at the right time, with the right cycle time and so on will be handled by the interaction layer.
You have two ways to influence dynamically the value of your message: IL DLLs and custom message sending.
Custom message sending is the basic way, where
you define the message ex.: message Battery_Traction Batt_msg;
you trigger its sending(output function)
you set up cyclic sending on timer Cycletimemsg1 {output(msg1);}
and so on.
IL DLLs are doing this all for you, without much coding effort from your side, but they rely heavily on the dbc settings and attributes you have linked as database to your CAN Channel.
Unfortunately, they don't play well together, meaning you need advanced CANoe know-how of them to use both in the same environment. You basically bypassed your CANOEILNLVECTOR.dlls working by sending explicit message.
So your code if you are accessing your signal through IL, should look like this:
variables
{
/*no need to define custom message object, they are already "known" to IL by dbc*/
}
on start
{
$Batt_msg::Isolation_Signal = 0x02; //0x02:On
/*NO need for output either (IF YOUR MESSAGE IS defined Cyclic in dbc), */
}
If your signal is not identified at $Batt_msg::Isolation_Signal, just dragndrop the signal from the CAPL browsers Symbols panel, and add the $ sign before it.
Through dollar($) sign, you access the dbsignal class objects signal value attribute.
I have an application that can send a message to another application. Under pre-Win8 systems, that works fine. You give it the class or title, it uses enumwindows and finds the target window. With Win8, you can only enumerate top level windows, which means the TApplication class. The sending side is happy with that, but the receiver isn't.
To catch the message I'm using this code within my target form ...
function Tmain.AppMsgHookFunc(var wmsg : TMessage) : Boolean;
begin
Result := False;
if wmsg.Msg = WM_COPYDATA then begin
// Post the caught message back to this form.
postmessage (handle,wmsg.Msg,wmsg.WParam,wmsg.LParam);
end;
end;
... and then activate this with application.hookmainwindow etc.
This never fires. I see that if I use sendmessage to send myself the message then it does fire, but if I use postmessage that doesn't work, even on XP. Any suggestions?
WM_COPYDATA is a sent message. The system marshals data cross-process. In order to do so, the system must know that the message has been processed in order to be able to tidy up the resources used to make the cross-process marshalling happen. And the way that the system knows that the message has been processed is by forcing you to send it synchronously. That means you must use SendMessage rather than PostMessage.
The documentation also contains this information, although you do need to know how to interpret it.
An application sends the WM_COPYDATA message to pass data to another application.
Note the use of the word "sends". That is code for the message being synchronous.
Raymond Chen discusses this issue here: Why can't I PostMessage the WM_COPYDATA message, but I can SendMessageTimeout it with a tiny timeout?
The important difference from the standpoint of messages like
WM_COPYDATA is that with sent messages, the window manager knows when
message processing is complete: When the window procedure returns. At
that time, it can free the temporary buffers used to marshal the
message from the sender to the recipient. If the message were posted,
the window manager would never be sure.
Suppose the message is placed in a MSG structure as the result of a
call to GetMessage. Now the window manager knows that the receiving
thread has the potential for taking action on the message and the
buffers need to be valid. But how would it know when the buffers can
be freed? "Well you can wait until the exact same parameters get
passed in a MSG structure to the DispatchMessage function." But what
if the message loop discards the message? Or what if it decides to
dispatch it twice? Or what if it decides to smuggle it inside another
message?
Posted messages have no guarantee of delivery nor do they provide any
information as to when the message has been definitely processed, or
even if it has been processed at all. If the window manager let you
post a WM_COPYDATA message, it would have to use its psychic powers
to know when the memory can be freed.
I have a device that sends data to my server via gprs . The problem is that it sends raw data and i don't know where i can stop the reading
Currently i am using something TIdHttpServer and something like this to read the strings :
var
s : string;
repeat
s:=s+acontext.Connection.Socket.ReadChar;
until acontext.Connection.Socket.InputBufferIsEmpty;
Is there a better solution to my problem ?
TCP is stream oriented. If the protocol is unknown, the server only can try to read into a byte array (if memory is not a problem) or a file stream. If the client disconnects normally, the data is 'complete'. Unfortunately, if the protocol is unknown, the server can not tell wether the client died or disconnected normally.
InputBufferIsEmpty does not help, as it only says if there is data in the (TCP) buffer - and depending on latency this can happen frequently, but it does not mean that there are no more in-flight bytes.
You could try to 'reverse engineer' the protocol, by sending known strings over the client devices. But if the sender is a black box, there can be many special cases - think of encoding or 'escape' characters etc.
You could make up you own protocol.
Some ideas are:
use a special character or characters combo to define the end of the
message.
append at the start of the message some fixed size field with the size of the message
I have come to the point of thinking that the onWrite Event of a ClientSocket is redundant when I directly write bytes into the socket connection via SendBuf().
Is my point of thinking somewhere in the desert?
The Delphi Documentation is also somewhat bad because it just sais: "Write a routine for the onWrite event to write into the socket connection."
OnWrite is used when you're using asynchronous IO (when you have ClientType = ctNonBlocking, in other words). It's called when the socket's ready for you to send data.
Thus, your thinking's only half in the desert: if you're using ctBlocking, then don't bother with OnWrite at all. If you need that thread to send data and get on with other stuff at the same time, then use ctNonBlocking and write to the socket in OnWrite.
When you use async sockets, Windows will send your socket a CM_SOCKETMESSAGE, handled by TCustomWinSocket.CMSocketMessage. When that message has its SelectEvent property set to FD_WRITE, the OnWrite's (ultimately) invoked.
The magic ingredient here is the call to WSAAsyncSelect in TCustomWinSocket.DoSetAsyncStyles.