nullrdc.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "net/mac/nullrdc.h"
00043 #include "net/packetbuf.h"
00044 #include "net/netstack.h"
00045 #include <string.h>
00046
00047 #define DEBUG 0
00048 #if DEBUG
00049 #include <stdio.h>
00050 #define PRINTF(...) printf(__VA_ARGS__)
00051 #else
00052 #define PRINTF(...)
00053 #endif
00054
00055 #ifndef NULLRDC_802154_AUTOACK
00056 #ifdef NULLRDC_CONF_802154_AUTOACK
00057 #define NULLRDC_802154_AUTOACK NULLRDC_CONF_802154_AUTOACK
00058 #else
00059 #define NULLRDC_802154_AUTOACK 0
00060 #endif
00061 #endif
00062
00063 #ifndef NULLRDC_802154_AUTOACK_HW
00064 #ifdef NULLRDC_CONF_802154_AUTOACK_HW
00065 #define NULLRDC_802154_AUTOACK_HW NULLRDC_CONF_802154_AUTOACK_HW
00066 #else
00067 #define NULLRDC_802154_AUTOACK_HW 0
00068 #endif
00069 #endif
00070
00071 #if NULLRDC_802154_AUTOACK
00072 #include "sys/rtimer.h"
00073 #include "dev/watchdog.h"
00074
00075 #define ACK_WAIT_TIME RTIMER_SECOND / 2500
00076 #define AFTER_ACK_DETECTED_WAIT_TIME RTIMER_SECOND / 1500
00077 #define ACK_LEN 3
00078 #endif
00079
00080 #if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW
00081 struct seqno {
00082 rimeaddr_t sender;
00083 uint8_t seqno;
00084 };
00085
00086 #ifdef NETSTACK_CONF_MAC_SEQNO_HISTORY
00087 #define MAX_SEQNOS NETSTACK_CONF_MAC_SEQNO_HISTORY
00088 #else
00089 #define MAX_SEQNOS 16
00090 #endif
00091
00092 static struct seqno received_seqnos[MAX_SEQNOS];
00093 #endif
00094
00095
00096 static void
00097 send_packet(mac_callback_t sent, void *ptr)
00098 {
00099 int ret;
00100 packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr);
00101 #if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW
00102 packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
00103 #endif
00104
00105 if(NETSTACK_FRAMER.create() == 0) {
00106
00107 PRINTF("nullrdc: send failed, too large header\n");
00108 ret = MAC_TX_ERR_FATAL;
00109 } else {
00110
00111 #if NULLRDC_802154_AUTOACK
00112 int is_broadcast;
00113 uint8_t dsn;
00114 dsn = ((uint8_t *)packetbuf_hdrptr())[2] & 0xff;
00115
00116 NETSTACK_RADIO.prepare(packetbuf_hdrptr(), packetbuf_totlen());
00117
00118 is_broadcast = rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
00119 &rimeaddr_null);
00120
00121 if(NETSTACK_RADIO.receiving_packet() ||
00122 (!is_broadcast && NETSTACK_RADIO.pending_packet())) {
00123
00124
00125
00126
00127 ret = MAC_TX_COLLISION;
00128
00129 } else {
00130 switch(NETSTACK_RADIO.transmit(packetbuf_totlen())) {
00131 case RADIO_TX_OK:
00132 if(is_broadcast) {
00133 ret = MAC_TX_OK;
00134 } else {
00135 rtimer_clock_t wt;
00136
00137
00138 wt = RTIMER_NOW();
00139 watchdog_periodic();
00140 while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + ACK_WAIT_TIME));
00141
00142 ret = MAC_TX_NOACK;
00143 if(NETSTACK_RADIO.receiving_packet() ||
00144 NETSTACK_RADIO.pending_packet() ||
00145 NETSTACK_RADIO.channel_clear() == 0) {
00146 int len;
00147 uint8_t ackbuf[ACK_LEN];
00148
00149 wt = RTIMER_NOW();
00150 watchdog_periodic();
00151 while(RTIMER_CLOCK_LT(RTIMER_NOW(),
00152 wt + AFTER_ACK_DETECTED_WAIT_TIME));
00153
00154 if(NETSTACK_RADIO.pending_packet()) {
00155 len = NETSTACK_RADIO.read(ackbuf, ACK_LEN);
00156 if(len == ACK_LEN && ackbuf[2] == dsn) {
00157
00158 ret = MAC_TX_OK;
00159 } else {
00160
00161 ret = MAC_TX_COLLISION;
00162 }
00163 }
00164 }
00165 }
00166 break;
00167 case RADIO_TX_COLLISION:
00168 ret = MAC_TX_COLLISION;
00169 break;
00170 default:
00171 ret = MAC_TX_ERR;
00172 break;
00173 }
00174 }
00175
00176 #else
00177
00178 switch(NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen())) {
00179 case RADIO_TX_OK:
00180 ret = MAC_TX_OK;
00181 break;
00182 case RADIO_TX_COLLISION:
00183 ret = MAC_TX_COLLISION;
00184 break;
00185 case RADIO_TX_NOACK:
00186 ret = MAC_TX_NOACK;
00187 break;
00188 default:
00189 ret = MAC_TX_ERR;
00190 break;
00191 }
00192
00193 #endif
00194 }
00195 mac_call_sent_callback(sent, ptr, ret, 1);
00196 }
00197
00198 static void
00199 packet_input(void)
00200 {
00201 #if NULLRDC_802154_AUTOACK
00202 if(packetbuf_datalen() == ACK_LEN) {
00203
00204
00205 } else
00206 #endif
00207 if(NETSTACK_FRAMER.parse() == 0) {
00208 PRINTF("nullrdc: failed to parse %u\n", packetbuf_datalen());
00209 } else {
00210 #if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW
00211
00212
00213 int i;
00214 for(i = 0; i < MAX_SEQNOS; ++i) {
00215 if(packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == received_seqnos[i].seqno &&
00216 rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
00217 &received_seqnos[i].sender)) {
00218
00219 PRINTF("nullrdc: drop duplicate link layer packet %u\n",
00220 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID));
00221 return;
00222 }
00223 }
00224 for(i = MAX_SEQNOS - 1; i > 0; --i) {
00225 memcpy(&received_seqnos[i], &received_seqnos[i - 1],
00226 sizeof(struct seqno));
00227 }
00228 received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
00229 rimeaddr_copy(&received_seqnos[0].sender,
00230 packetbuf_addr(PACKETBUF_ADDR_SENDER));
00231 #endif
00232 NETSTACK_MAC.input();
00233 }
00234 }
00235
00236 static int
00237 on(void)
00238 {
00239 return NETSTACK_RADIO.on();
00240 }
00241
00242 static int
00243 off(int keep_radio_on)
00244 {
00245 if(keep_radio_on) {
00246 return NETSTACK_RADIO.on();
00247 } else {
00248 return NETSTACK_RADIO.off();
00249 }
00250 }
00251
00252 static unsigned short
00253 channel_check_interval(void)
00254 {
00255 return 0;
00256 }
00257
00258 static void
00259 init(void)
00260 {
00261 on();
00262 }
00263
00264 const struct rdc_driver nullrdc_driver = {
00265 "nullrdc",
00266 init,
00267 send_packet,
00268 packet_input,
00269 on,
00270 off,
00271 channel_check_interval,
00272 };
00273