49 #if CONTIKI_TARGET_COOJA
50 #include "lib/simEnvChange.h"
51 #include "sys/cooja_mt.h"
57 #define PRINTF(...) printf(__VA_ARGS__)
62 #ifdef NULLRDC_CONF_ADDRESS_FILTER
63 #define NULLRDC_ADDRESS_FILTER NULLRDC_CONF_ADDRESS_FILTER
65 #define NULLRDC_ADDRESS_FILTER 1
68 #ifndef NULLRDC_802154_AUTOACK
69 #ifdef NULLRDC_CONF_802154_AUTOACK
70 #define NULLRDC_802154_AUTOACK NULLRDC_CONF_802154_AUTOACK
72 #define NULLRDC_802154_AUTOACK 0
76 #ifndef NULLRDC_802154_AUTOACK_HW
77 #ifdef NULLRDC_CONF_802154_AUTOACK_HW
78 #define NULLRDC_802154_AUTOACK_HW NULLRDC_CONF_802154_AUTOACK_HW
80 #define NULLRDC_802154_AUTOACK_HW 0
84 #if NULLRDC_802154_AUTOACK
86 #include "dev/watchdog.h"
88 #ifdef NULLRDC_CONF_ACK_WAIT_TIME
89 #define ACK_WAIT_TIME NULLRDC_CONF_ACK_WAIT_TIME
91 #define ACK_WAIT_TIME RTIMER_SECOND / 2500
93 #ifdef NULLRDC_CONF_AFTER_ACK_DETECTED_WAIT_TIME
94 #define AFTER_ACK_DETECTED_WAIT_TIME NULLRDC_CONF_AFTER_ACK_DETECTED_WAIT_TIME
96 #define AFTER_ACK_DETECTED_WAIT_TIME RTIMER_SECOND / 1500
100 #ifdef NULLRDC_CONF_SEND_802154_ACK
101 #define NULLRDC_SEND_802154_ACK NULLRDC_CONF_SEND_802154_ACK
103 #define NULLRDC_SEND_802154_ACK 0
106 #if NULLRDC_SEND_802154_ACK
114 send_one_packet(mac_callback_t sent,
void *ptr)
117 int last_sent_ok = 0;
120 #if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW
121 packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
124 if(NETSTACK_FRAMER.create() < 0) {
126 PRINTF(
"nullrdc: send failed, too large header\n");
127 ret = MAC_TX_ERR_FATAL;
129 #if NULLRDC_802154_AUTOACK
138 if(NETSTACK_RADIO.receiving_packet() ||
139 (!is_broadcast && NETSTACK_RADIO.pending_packet())) {
147 RIMESTATS_ADD(reliabletx);
160 while(RTIMER_CLOCK_LT(
RTIMER_NOW(), wt + ACK_WAIT_TIME)) {
161 #if CONTIKI_TARGET_COOJA
162 simProcessRunValue = 1;
168 if(NETSTACK_RADIO.receiving_packet() ||
169 NETSTACK_RADIO.pending_packet() ||
170 NETSTACK_RADIO.channel_clear() == 0) {
172 uint8_t ackbuf[ACK_LEN];
174 if(AFTER_ACK_DETECTED_WAIT_TIME > 0) {
178 wt + AFTER_ACK_DETECTED_WAIT_TIME)) {
179 #if CONTIKI_TARGET_COOJA
180 simProcessRunValue = 1;
186 if(NETSTACK_RADIO.pending_packet()) {
187 len = NETSTACK_RADIO.read(ackbuf, ACK_LEN);
188 if(len == ACK_LEN && ackbuf[2] == dsn) {
190 RIMESTATS_ADD(ackrx);
198 PRINTF(
"nullrdc tx noack\n");
202 case RADIO_TX_COLLISION:
217 case RADIO_TX_COLLISION:
233 mac_call_sent_callback(sent, ptr, ret, 1);
238 send_packet(mac_callback_t sent,
void *ptr)
240 send_one_packet(sent, ptr);
244 send_list(mac_callback_t sent,
void *ptr,
struct rdc_buf_list *buf_list)
246 while(buf_list !=
NULL) {
249 struct rdc_buf_list *next = buf_list->next;
252 queuebuf_to_packetbuf(buf_list->buf);
253 last_sent_ok = send_one_packet(sent, ptr);
268 #if NULLRDC_SEND_802154_ACK
269 int original_datalen;
270 uint8_t *original_dataptr;
276 #if NULLRDC_802154_AUTOACK
279 PRINTF(
"nullrdc: ignored ack\n");
282 if(NETSTACK_FRAMER.parse() < 0) {
284 #if NULLRDC_ADDRESS_FILTER
285 }
else if(!
linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
288 PRINTF(
"nullrdc: not for us\n");
293 #if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW
294 #if RDC_WITH_DUPLICATE_DETECTION
299 PRINTF(
"nullrdc: drop duplicate link layer packet %u\n",
300 packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
307 #if NULLRDC_SEND_802154_ACK
315 uint8_t ackdata[ACK_LEN] = {0, 0, 0};
317 ackdata[0] = FRAME802154_ACKFRAME;
319 ackdata[2] = info154.
seq;
320 NETSTACK_RADIO.send(ackdata, ACK_LEN);
325 NETSTACK_MAC.input();
333 return NETSTACK_RADIO.on();
337 off(
int keep_radio_on)
340 return NETSTACK_RADIO.on();
342 return NETSTACK_RADIO.off();
346 static unsigned short
347 channel_check_interval(
void)
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
void(* send_list)(mac_callback_t sent_callback, void *ptr, struct rdc_buf_list *list)
Send a packet list.
Header file for the real-time timer module.
void mac_sequence_register_seqno(void)
Register the sequence number of the packetbuf.
unsigned short(* channel_check_interval)(void)
Returns the channel check interval, expressed in clock_time_t ticks.
uint8_t dest_addr[8]
Destination address.
The MAC layer deferred the transmission for a later time.
The MAC layer did not get an acknowledgement for the packet.
frame802154_fcf_t fcf
Frame control field.
int(* off)(int keep_radio_on)
Turn the MAC layer off.
#define RTIMER_NOW()
Get the current clock time.
int(* on)(void)
Turn the MAC layer on.
uint8_t seq
Sequence number.
uint16_t packetbuf_totlen(void)
Get the total length of the header and data in the packetbuf.
Header file for MAC sequence numbers management
int packetbuf_holds_broadcast(void)
Checks whether the current packet is a broadcast.
int mac_sequence_is_duplicate(void)
Tell whether the packetbuf is a duplicate packet.
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
Header file for the Rime buffer (packetbuf) management
The MAC layer transmission could not be performed because of a fatal error.
void(* init)(void)
Initialize the RDC driver.
The MAC layer transmission was OK.
#define NULL
The null pointer.
802.15.4 frame creation and parsing functions
void watchdog_periodic(void)
Writes the WDT clear sequence.
int frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
Parses an input frame.
The structure of a RDC (radio duty cycling) driver in Contiki.
uint8_t ack_required
1 bit.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
Header file for Rime statistics
Header file for the Rime queue buffer management
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two Rime addresses.
linkaddr_t linkaddr_node_addr
The Rime address of the node.
A null RDC implementation that uses framer for headers.
Parameters used by the frame802154_create() function.
Include file for the Contiki low-layer network stack (NETSTACK)