X-Git-Url: https://oss.titaniummirror.com/gitweb/?p=tinyos-2.x.git;a=blobdiff_plain;f=tos%2Fchips%2Fcc2420%2Flowpan%2FCC2420TinyosNetworkP.nc;h=8e8061a9f8612aa70623baf49ec567b37092d66b;hp=e490f37cece3c55e6f3eccbc3ed3a93086037d7e;hb=e9bfab607e051bae6afb47b44892ce37541d1b44;hpb=adf1de6c009d13b7b52e68535c63b28f59c97400 diff --git a/tos/chips/cc2420/lowpan/CC2420TinyosNetworkP.nc b/tos/chips/cc2420/lowpan/CC2420TinyosNetworkP.nc index e490f37c..8e8061a9 100644 --- a/tos/chips/cc2420/lowpan/CC2420TinyosNetworkP.nc +++ b/tos/chips/cc2420/lowpan/CC2420TinyosNetworkP.nc @@ -37,62 +37,190 @@ * * @author David Moss */ - + #include "CC2420.h" +#include "Ieee154.h" module CC2420TinyosNetworkP @safe() { provides { - interface Send; - interface Receive; - - interface Receive as NonTinyosReceive[uint8_t networkId]; + interface Resource[uint8_t client]; + + interface Send as BareSend; + interface Receive as BareReceive; + + interface Send as ActiveSend; + interface Receive as ActiveReceive; } uses { interface Send as SubSend; interface Receive as SubReceive; + interface CC2420Packet; interface CC2420PacketBody; + interface ResourceQueue as Queue; } } implementation { - /***************** Send Commands ****************/ - command error_t Send.send(message_t* msg, uint8_t len) { - (call CC2420PacketBody.getHeader(msg))->network = TINYOS_6LOWPAN_NETWORK_ID; + enum { + OWNER_NONE = 0xff, + TINYOS_N_NETWORKS = uniqueCount(RADIO_SEND_RESOURCE), + } state; + + norace uint8_t resource_owner = OWNER_NONE, next_owner; + + command error_t ActiveSend.send(message_t* msg, uint8_t len) { + call CC2420Packet.setNetwork(msg, TINYOS_6LOWPAN_NETWORK_ID); return call SubSend.send(msg, len); } - command error_t Send.cancel(message_t* msg) { + command error_t ActiveSend.cancel(message_t* msg) { return call SubSend.cancel(msg); } - command uint8_t Send.maxPayloadLength() { + command uint8_t ActiveSend.maxPayloadLength() { return call SubSend.maxPayloadLength(); } - command void* Send.getPayload(message_t* msg, uint8_t len) { - return call SubSend.getPayload(msg, len); + command void* ActiveSend.getPayload(message_t* msg, uint8_t len) { + if (len <= call ActiveSend.maxPayloadLength()) { + return msg->data; + } else { + return NULL; + } + } + + /***************** Send Commands ****************/ + command error_t BareSend.send(message_t* msg, uint8_t len) { + return call SubSend.send(msg, len - AM_OVERHEAD); + } + + command error_t BareSend.cancel(message_t* msg) { + return call SubSend.cancel(msg); + } + + command uint8_t BareSend.maxPayloadLength() { + return call SubSend.maxPayloadLength() + AM_OVERHEAD; + } + + command void* BareSend.getPayload(message_t* msg, uint8_t len) { +#ifndef TFRAMES_ENABLED + cc2420_header_t *hdr = call CC2420PacketBody.getHeader(msg); + return &hdr->network; +#else + // you really can't use BareSend with TFRAMES +#error "BareSend is not supported with TFRAMES: only the ActiveMessage layer is supported" +#endif } /***************** SubSend Events *****************/ event void SubSend.sendDone(message_t* msg, error_t error) { - signal Send.sendDone(msg, error); + if (call CC2420Packet.getNetwork(msg) == TINYOS_6LOWPAN_NETWORK_ID) { + signal ActiveSend.sendDone(msg, error); + } else { + signal BareSend.sendDone(msg, error); + } } - + /***************** SubReceive Events ***************/ event message_t *SubReceive.receive(message_t *msg, void *payload, uint8_t len) { - if((call CC2420PacketBody.getHeader(msg))->network == TINYOS_6LOWPAN_NETWORK_ID) { - return signal Receive.receive(msg, payload, len); - + + if(!(call CC2420PacketBody.getMetadata(msg))->crc) { + return msg; + } +#ifndef TFRAMES_ENABLED + if (call CC2420Packet.getNetwork(msg) == TINYOS_6LOWPAN_NETWORK_ID) { + return signal ActiveReceive.receive(msg, payload, len); } else { - return signal NonTinyosReceive.receive[(call CC2420PacketBody.getHeader(msg))->network](msg, payload, len); + cc2420_header_t *hdr = call CC2420PacketBody.getHeader(msg); + return signal BareReceive.receive(msg, &hdr->network, len + AM_OVERHEAD); } +#else + return signal ActiveReceive.receive(msg, payload, len); +#endif } - + + /***************** Resource ****************/ + // SDH : 8-7-2009 : testing if there's more then one client allows + // the compiler to eliminate most of the logic when there's only one + // client. + task void grantTask() { + + + if (TINYOS_N_NETWORKS > 1) { + if (resource_owner == OWNER_NONE && !(call Queue.isEmpty())) { + resource_owner = call Queue.dequeue(); + + if (resource_owner != OWNER_NONE) { + signal Resource.granted[resource_owner](); + } + } + } else { + if (next_owner != resource_owner) { + resource_owner = next_owner; + signal Resource.granted[resource_owner](); + } + } + } + + async command error_t Resource.request[uint8_t id]() { + + post grantTask(); + + if (TINYOS_N_NETWORKS > 1) { + + return call Queue.enqueue(id); + } else { + if (id == resource_owner) { + return EALREADY; + } else { + next_owner = id; + return SUCCESS; + } + } + } + + async command error_t Resource.immediateRequest[uint8_t id]() { + if (resource_owner == id) return EALREADY; + + if (TINYOS_N_NETWORKS > 1) { + if (resource_owner == OWNER_NONE && call Queue.isEmpty()) { + resource_owner = id; + return SUCCESS; + } + return FAIL; + } else { + resource_owner = id; + return SUCCESS; + } + } + async command error_t Resource.release[uint8_t id]() { + if (TINYOS_N_NETWORKS > 1) { + post grantTask(); + } + resource_owner = OWNER_NONE; + return SUCCESS; + } + async command bool Resource.isOwner[uint8_t id]() { + return (id == resource_owner); + } + /***************** Defaults ****************/ - default event message_t *NonTinyosReceive.receive[uint8_t networkId](message_t *msg, void *payload, uint8_t len) { + default event message_t *BareReceive.receive(message_t *msg, void *payload, uint8_t len) { return msg; } - + default event void BareSend.sendDone(message_t *msg, error_t error) { + + } + default event message_t *ActiveReceive.receive(message_t *msg, void *payload, uint8_t len) { + return msg; + } + default event void ActiveSend.sendDone(message_t *msg, error_t error) { + + } + default event void Resource.granted[uint8_t client]() { + call Resource.release[client](); + } + }