2010-09-01 165 views
1

我遇到了我的nesC代碼問題。在我的代碼中,我使用AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(rd_message))發送第一個數據包。第二次回覆後的Tinyos接收不起作用

之後,當在函數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; 
    } 
    } 

我刪除了所有的邏輯從代碼專注於消息交換電話。我希望有人能幫助我......謝謝。

回答

4

的TinyOS如下幾乎無處不在一個所有權紀律:在任何時間點,每 「內存對象」 - 一塊內存,典型地爲整個可變或單個數組元素 - 應該由單個模塊所擁有。據說像send這樣的命令將其msg參數的所有權從調用者傳遞給被調用者。

代碼的主要問題是,在Receive.receive事件中,你正在使用的packet變量在兩個方面:

  • 作爲輸出數據包通過執行調用call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(rd_message))
  • 作爲緩衝下一呼入分組return bufPtr;

此代碼的結果是不可預知的(因爲接收數據包會損壞傳出數據包)。要解決您的問題,您應該使用Pool<message_t>組件。像你這樣的程序典型的僞像:

  1. 接收(米):
  2. 如果我不需要處理此消息,返回米
  3. 如果我的免費包列表是空的,回報免費包列舉M
  4. 其他
    1. 過程/進m
    2. 回報進入

這是一個粗略的實現模塊的使用Pool<message_t>免費包的列表來管理通信:

module Foo 
{ 
    /* this is our free packet list */ 
    uses interface Pool<message_t>; 
    uses interface Receive; 
    uses interface AMSend; 
} 

implementation 
{ 

event void MilliTimer.fired() 
{ 
    message_t *packet; 
    /* get a free packet */ 
    packet = Pool.get(); 
    if (packet) 
    { 
     /* code to send the packet */ 
    } 
} 

event void AMSend.sendDone(message_t *msg, error_t error) 
{ 
    /* the send function ended, put back the packet in the free packet pool */ 
    /* check here if msg was taken from Pool */ 
    call Pool.put(msg); 
} 

event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len) 
{ 
    if (!haveToProcess(msg)) 
     return msg; // don't have to process this message 
    if (Pool.empty()) 
     return msg; // memory exahusted; 
    /* ... */ 
    /* code that processes the packet */ 
    call AMSend.send(AM_BROADCAST_ADDR, msg, sizeof(rd_message)); 
    /* return a free message_t* as buffer to store the next received packet */ 
    return Pool.get(); 
} 

} 

如果你不喜歡Pool,您可以使用message_t數組作爲循環緩衝區。查看BaseStation代碼,瞭解如何操作。

欲瞭解更多詳情,我建議您閱讀TinyOS programming book,尤其是第3.5.1節。

至於您的評論:

return bufPtr; //FIXME: see if it's correct to return null here 

可以從未在接收事件回報NULL,因爲TinyOS中總是需要一個緩衝存儲傳入數據包。

+0

謝謝你的回覆,現在事情已經很清楚了。當然,我必須詳細研究TinyOS的開發,並理解如何處理這種情況。 Ancora grazie mille !! – Raffo 2010-09-02 17:21:14

相關問題