sicslowmac.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
00043
00044
00045
00046
00047 #include <string.h>
00048 #include "net/mac/sicslowmac.h"
00049 #include "net/mac/frame802154.h"
00050 #include "net/packetbuf.h"
00051 #include "net/netstack.h"
00052 #include "lib/random.h"
00053
00054 #define DEBUG 0
00055
00056 #if DEBUG
00057 #include <stdio.h>
00058 #define PRINTF(...) printf(__VA_ARGS__)
00059 #define PRINTADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7])
00060 #else
00061 #define PRINTF(...)
00062 #define PRINTADDR(addr)
00063 #endif
00064
00065
00066
00067
00068
00069 static uint8_t mac_dsn;
00070
00071
00072
00073
00074
00075 static uint16_t mac_dst_pan_id = IEEE802154_PANID;
00076
00077
00078
00079
00080
00081 static uint16_t mac_src_pan_id = IEEE802154_PANID;
00082
00083
00084 static int
00085 is_broadcast_addr(uint8_t mode, uint8_t *addr)
00086 {
00087 int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8;
00088 while(i-- > 0) {
00089 if(addr[i] != 0xff) {
00090 return 0;
00091 }
00092 }
00093 return 1;
00094 }
00095
00096 static void
00097 send_packet(mac_callback_t sent, void *ptr)
00098 {
00099 frame802154_t params;
00100 uint8_t len;
00101
00102
00103 memset(¶ms, 0, sizeof(params));
00104
00105
00106 params.fcf.frame_type = FRAME802154_DATAFRAME;
00107 params.fcf.security_enabled = 0;
00108 params.fcf.frame_pending = 0;
00109 params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_RELIABLE);
00110 params.fcf.panid_compression = 0;
00111
00112
00113 params.fcf.frame_version = FRAME802154_IEEE802154_2003;
00114
00115
00116 params.seq = mac_dsn++;
00117
00118
00119
00120
00121
00122
00123 params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
00124 params.dest_pid = mac_dst_pan_id;
00125
00126
00127
00128
00129
00130 if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
00131
00132 params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
00133 params.dest_addr[0] = 0xFF;
00134 params.dest_addr[1] = 0xFF;
00135
00136 } else {
00137 rimeaddr_copy((rimeaddr_t *)¶ms.dest_addr,
00138 packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
00139 params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
00140 }
00141
00142
00143 params.src_pid = mac_src_pan_id;
00144
00145
00146
00147
00148
00149 rimeaddr_copy((rimeaddr_t *)¶ms.src_addr, &rimeaddr_node_addr);
00150
00151 params.payload = packetbuf_dataptr();
00152 params.payload_len = packetbuf_datalen();
00153 len = frame802154_hdrlen(¶ms);
00154 if(packetbuf_hdralloc(len)) {
00155 int ret;
00156 frame802154_create(¶ms, packetbuf_hdrptr(), len);
00157
00158 PRINTF("6MAC-UT: %2X", params.fcf.frame_type);
00159 PRINTADDR(params.dest_addr.u8);
00160 PRINTF("%u %u (%u)\n", len, packetbuf_datalen(), packetbuf_totlen());
00161
00162 ret = NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen());
00163 if(sent) {
00164 switch(ret) {
00165 case RADIO_TX_OK:
00166 sent(ptr, MAC_TX_OK, 1);
00167 break;
00168 case RADIO_TX_ERR:
00169 sent(ptr, MAC_TX_ERR, 1);
00170 break;
00171 }
00172 }
00173 } else {
00174 PRINTF("6MAC-UT: too large header: %u\n", len);
00175 }
00176 }
00177
00178 static void
00179 input_packet(void)
00180 {
00181 frame802154_t frame;
00182 int len;
00183
00184 len = packetbuf_datalen();
00185
00186 if(frame802154_parse(packetbuf_dataptr(), len, &frame) &&
00187 packetbuf_hdrreduce(len - frame.payload_len)) {
00188 if(frame.fcf.dest_addr_mode) {
00189 if(frame.dest_pid != mac_src_pan_id &&
00190 frame.dest_pid != FRAME802154_BROADCASTPANDID) {
00191
00192 PRINTF("6MAC: for another pan %u\n", frame.dest_pid);
00193 return;
00194 }
00195 if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) {
00196 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (rimeaddr_t *)&frame.dest_addr);
00197 if(!rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
00198 &rimeaddr_node_addr)) {
00199
00200 PRINTF("6MAC: not for us\n");
00201 return;
00202 }
00203 }
00204 }
00205 packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (rimeaddr_t *)&frame.src_addr);
00206
00207 PRINTF("6MAC-IN: %2X", frame.fcf.frame_type);
00208 PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
00209 PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
00210 PRINTF("%u\n", packetbuf_datalen());
00211 NETSTACK_MAC.input();
00212 } else {
00213 PRINTF("6MAC: failed to parse hdr\n");
00214 }
00215 }
00216
00217 static int
00218 on(void)
00219 {
00220 return NETSTACK_RADIO.on();
00221 }
00222
00223 static int
00224 off(int keep_radio_on)
00225 {
00226 if(keep_radio_on) {
00227 return NETSTACK_RADIO.on();
00228 } else {
00229 return NETSTACK_RADIO.off();
00230 }
00231 }
00232
00233 static void
00234 init(void)
00235 {
00236 mac_dsn = random_rand() % 256;
00237
00238 NETSTACK_RADIO.on();
00239 }
00240
00241 static unsigned short
00242 channel_check_interval(void)
00243 {
00244 return 0;
00245 }
00246
00247 const struct rdc_driver sicslowmac_driver = {
00248 "sicslowmac",
00249 init,
00250 send_packet,
00251 input_packet,
00252 on,
00253 off,
00254 channel_check_interval
00255 };
00256