利用TinyOS写一个专门转发数据包的App

由于节点的通信半径非常小(micaz大约15m),因此对于一个大型网络,节点数量可能成百上千个,因此往往数据包需要经过多跳才能到达目的地,这里我们使用ActiveMessageC组件提供的Snoop接口来完成这样的一个功能

具体功能:该节点接受任意包,并且将它发送给目的节点

直接贴代码了,很好懂的。

ForwardAppC.nc

#define NEW_PRINTF_SEMANTICS
#include "printf.h"
configuration ForwardAppC {
}
implementation {
    components ForwardC as App;
    components MainC, LedsC;
    components ActiveMessageC;

    App.Boot -> MainC;
    App.Leds -> LedsC;

    App.AMSend -> ActiveMessageC;
    App.Receive -> ActiveMessageC.Receive;
    App.Snoop -> ActiveMessageC.Snoop;
    App.RadioControl -> ActiveMessageC;
    App.AMPacket -> ActiveMessageC;
    App.Packet -> ActiveMessageC;
    components PrintfC, SerialStartC;
}
#include "printf.h"
#include <string.h>
module ForwardC {
    uses {
        interface Boot;
        interface Leds;
        interface AMSend as AMSend[am_id_t id];
        interface Packet;
        interface AMPacket;
        interface Receive as Receive[am_id_t id];
        interface Receive as Snoop[am_id_t id];
        interface SplitControl as RadioControl;
    }
}

implementation {
    bool radio_busy = FALSE;
    message_t forward_pkg;
    event void Boot.booted()
    {
        call RadioControl.start();
    }
    event void RadioControl.startDone(error_t err)
    {
    }
    event void RadioControl.stopDone(error_t err) { }

    message_t *receive(message_t *msg, void *payload, uint8_t len)
    {
        am_addr_t dest_addr;
        dest_addr = call AMPacket.destination(msg);
        printf("receive a pkg, addr: %d\n", dest_addr);
        printfflush();
            if (!radio_busy) {
                call Leds.led1Toggle();
                memcpy(call AMSend.getPayload[call AMPacket.type(msg)](&forward_pkg, len), payload, len);
                if (call AMSend.send[call AMPacket.type(msg)](dest_addr, &forward_pkg, len) == SUCCESS) { 
                    radio_busy = FALSE;
                } 
            }
        return msg;
    }
    
    
    event void AMSend.sendDone[am_id_t id](message_t *msg, error_t err)
    {
        if (msg == &forward_pkg) {
            radio_busy = FALSE;
        }
    }

    event message_t *Receive.receive[am_id_t id](message_t *msg, void *payload, uint8_t len)
    {
        return receive(msg, payload, len);
    }
    event message_t *Snoop.receive[am_id_t id](message_t *msg, void *payload, uint8_t len)
    {
        return receive(msg, payload, len);
    }
}

Makefile

COMPONENT=ForwardAppC
CFLAGS += -DCC2420_NO_ADDRESS_RECOGNITION
CFLAGS += -I$(TOSROOT)/tos/lib/printf
include $(MAKERULES)

说明:该节点的功能很简单,拿到所有的message,不管是不是自己的,然后拿到payload,再将它放入自己的发送队列转发出去,

注意它不是广播出去的,而是拿到message的目的地址进行发送的。

注意点:1.在Makefile中必须要加一条宏: CFLAGS += -DCC2420_NO_ADDRESS_RECOGNITION用来使节点开启“混杂“模式

            2.这只能完成最基本的功能,因此如果要提高整个网络的性能需要好的路由算法的支持

            3.上文中的PrintfC,SerialStartC组件是用来在PC上打印调试信息用的,具体请参考

            http://docs.tinyos.net/tinywiki/index.php/The_TinyOS_printf_Library

posted on 2012-05-04 17:06  vincent Van Gogh  阅读(2209)  评论(1编辑  收藏  举报

导航