第二次回复后 Tinyos 接收不起作用
我的 nesC 代码遇到了麻烦。在我的代码中,我使用 AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(rd_message))
发送第一个数据包。
之后,当在函数 event message_t* Receive.receive(message_t* bufPtr, void* Payload, uint8_t len){
中收到消息时,会生成回复并成功发送,但其他节点没有收到回复能够收到回复。特别是,我必须遵循 DSR 协议的基础知识来处理 RREP 回复。 这是我的代码:
implementation{
/**********************Variables used*****************************/
short phase = 0;
message_t packet;
bool locked;
event void Boot.booted(){
dbg("Boot", "Node %hhu booted\n", TOS_NODE_ID);
call AMControl.start();
}
[cut]
event void MilliTimer.fired(){
/*This contains the discovery message*/
rd_message *rreq = NULL;
if (phase == 0){
//Route discovery phase
rreq = (rd_message *) call Packet.getPayload(&packet, (int) NULL);
if(call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(rd_message)) == SUCCESS){
//locked = TRUE;
}
return;
}
}
event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len){
rd_message *received_mex = NULL;
rd_message *reply_mex = NULL;
int i,j;
received_mex = (rd_message*) payload; //cast to rd_message
if (received_mex->type == RREQ){
reply_mex = (rd_message*) call Packet.getPayload(&packet, (int) NULL); //reply packet is created.
if (received_mex->sender_id == TOS_NODE_ID){
//The original sender received its RREQ. Stopping the forward procedure
return bufPtr; //FIXME: see if it's correct to return null here
}
//RREQ message case 1: I am not the receiver_id
if (received_mex->receiver_id != TOS_NODE_ID){
}
else if (received_mex->receiver_id == TOS_NODE_ID){
//I am the receiver of the RREQ message. I can now reply with a RREP
}
if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(rd_message)) == SUCCESS) {
dbg("dsr", "packet sent\n");
//locked = TRUE;
}
else{
dbg("dsr", "failed to send reply packet.\n");
}
}
else if (received_mex->type == RREP){
//DO SOMETHING WITH CHE NEW RECEIVED MESSAGE HERE
}
return bufPtr;
}
event void AMSend.sendDone(message_t* bufPtr, error_t error) {
if (&packet == bufPtr) {
//locked = FALSE;
}
}
我从代码中删除了所有逻辑,以专注于消息交换调用。我希望有人可以帮助我...谢谢。
I'm in trouble with my nesC code. In my code I send a first packet using AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(rd_message))
.
After that, when a message is received in function event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len){
a reply is generated and sent successfully, but the other nodes are not able to receive the reply. In particular I have to process a RREP reply, following the basics of DSR protocol.
This is my code:
implementation{
/**********************Variables used*****************************/
short phase = 0;
message_t packet;
bool locked;
event void Boot.booted(){
dbg("Boot", "Node %hhu booted\n", TOS_NODE_ID);
call AMControl.start();
}
[cut]
event void MilliTimer.fired(){
/*This contains the discovery message*/
rd_message *rreq = NULL;
if (phase == 0){
//Route discovery phase
rreq = (rd_message *) call Packet.getPayload(&packet, (int) NULL);
if(call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(rd_message)) == SUCCESS){
//locked = TRUE;
}
return;
}
}
event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len){
rd_message *received_mex = NULL;
rd_message *reply_mex = NULL;
int i,j;
received_mex = (rd_message*) payload; //cast to rd_message
if (received_mex->type == RREQ){
reply_mex = (rd_message*) call Packet.getPayload(&packet, (int) NULL); //reply packet is created.
if (received_mex->sender_id == TOS_NODE_ID){
//The original sender received its RREQ. Stopping the forward procedure
return bufPtr; //FIXME: see if it's correct to return null here
}
//RREQ message case 1: I am not the receiver_id
if (received_mex->receiver_id != TOS_NODE_ID){
}
else if (received_mex->receiver_id == TOS_NODE_ID){
//I am the receiver of the RREQ message. I can now reply with a RREP
}
if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(rd_message)) == SUCCESS) {
dbg("dsr", "packet sent\n");
//locked = TRUE;
}
else{
dbg("dsr", "failed to send reply packet.\n");
}
}
else if (received_mex->type == RREP){
//DO SOMETHING WITH CHE NEW RECEIVED MESSAGE HERE
}
return bufPtr;
}
event void AMSend.sendDone(message_t* bufPtr, error_t error) {
if (&packet == bufPtr) {
//locked = FALSE;
}
}
I removed all the logic from the code to focus on the message exchange calls. I hope that someone can help me... thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
TinyOS 几乎在任何地方都遵循所有权规则:在任何时间点,每个
“内存对象” - 一块内存,通常是整个变量或单个数组元素 - 应该由单个模块拥有。像
send
这样的命令据说会将其 msg 参数的所有权从调用者传递给被调用者。代码的主要问题是,在 Receive.receive 事件中,您以两种方式使用 packet 变量:
return bufPtr;
作为下一个传入数据包的缓冲区;此代码的结果是不可预测的(因为接收数据包会破坏传出数据包)。要解决您的问题,您应该使用
Pool
组件。像您这样的程序的典型伪代码如下:这是一个模块的粗略实现,该模块使用
Pool
作为空闲数据包列表来管理通信:如果您不喜欢
Pool
,您可以使用message_t
数组作为循环缓冲区。查看基站 代码以获取有关如何执行此操作的提示。有关更多详细信息,我建议您阅读 TinyOS 编程书籍,特别是第 3.5.1 节。
至于您的评论:
您永远不能在接收事件中返回
NULL
,因为TinyOS始终需要一个缓冲区来存储传入的数据包。TinyOS follows almost everywhere a ownership discipline: at any point in time, every
"memory object" - a piece of memory, typically a whole variable or a single array element - should be owned by a single module. A command like
send
is said to pass ownership of its msg argument from caller to callee.The main problem of your code is that in the
Receive.receive
event you are using thepacket
variable in two ways:call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(rd_message))
return bufPtr;
the result of this code is unpredictable (since receiving a packet will corrupt the outgoing packet). To solve your problem, you should use a
Pool<message_t>
component. The typical pseudocode for a program like yours is like:This is a rough implementation of a module that uses
Pool<message_t>
as list of free packets to manage communication:If you don't like
Pool
, you can use amessage_t
array as circular buffer. Take a look at the BaseStation code for a hint on how to do so.For more details, I suggest you to read the TinyOS programming book, especially section 3.5.1.
As for your comment:
you can never return
NULL
in a receive event, since TinyOS needs always a buffer to store incoming packets.