49 #if CONTIKI_TARGET_COOJA
50 #include "lib/simEnvChange.h"
56 #define PRINTF(...) printf(__VA_ARGS__)
61 #ifdef NULLRDC_CONF_ADDRESS_FILTER
62 #define NULLRDC_ADDRESS_FILTER NULLRDC_CONF_ADDRESS_FILTER
64 #define NULLRDC_ADDRESS_FILTER 1
67 #ifndef NULLRDC_802154_AUTOACK
68 #ifdef NULLRDC_CONF_802154_AUTOACK
69 #define NULLRDC_802154_AUTOACK NULLRDC_CONF_802154_AUTOACK
71 #define NULLRDC_802154_AUTOACK 0
75 #ifndef NULLRDC_802154_AUTOACK_HW
76 #ifdef NULLRDC_CONF_802154_AUTOACK_HW
77 #define NULLRDC_802154_AUTOACK_HW NULLRDC_CONF_802154_AUTOACK_HW
79 #define NULLRDC_802154_AUTOACK_HW 0
83 #if NULLRDC_802154_AUTOACK
85 #include "dev/watchdog.h"
87 #ifdef NULLRDC_CONF_ACK_WAIT_TIME
88 #define ACK_WAIT_TIME NULLRDC_CONF_ACK_WAIT_TIME
90 #define ACK_WAIT_TIME RTIMER_SECOND / 2500
92 #ifdef NULLRDC_CONF_AFTER_ACK_DETECTED_WAIT_TIME
93 #define AFTER_ACK_DETECTED_WAIT_TIME NULLRDC_CONF_AFTER_ACK_DETECTED_WAIT_TIME
95 #define AFTER_ACK_DETECTED_WAIT_TIME RTIMER_SECOND / 1500
99 #ifdef NULLRDC_CONF_SEND_802154_ACK
100 #define NULLRDC_SEND_802154_ACK NULLRDC_CONF_SEND_802154_ACK
102 #define NULLRDC_SEND_802154_ACK 0
105 #if NULLRDC_SEND_802154_ACK
113 send_one_packet(mac_callback_t sent,
void *ptr)
116 int last_sent_ok = 0;
119 #if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW
120 packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
123 if(NETSTACK_FRAMER.create_and_secure() < 0) {
125 PRINTF(
"nullrdc: send failed, too large header\n");
126 ret = MAC_TX_ERR_FATAL;
128 #if NULLRDC_802154_AUTOACK
135 is_broadcast =
linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
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 int original_datalen;
269 uint8_t *original_dataptr;
274 #if NULLRDC_802154_AUTOACK
277 PRINTF(
"nullrdc: ignored ack\n");
280 if(NETSTACK_FRAMER.parse() < 0) {
282 #if NULLRDC_ADDRESS_FILTER
283 }
else if(!
linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
287 PRINTF(
"nullrdc: not for us\n");
292 #if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW
293 #if RDC_WITH_DUPLICATE_DETECTION
298 PRINTF(
"nullrdc: drop duplicate link layer packet %u\n",
299 packetbuf_attr(PACKETBUF_ATTR_PACKET_ID));
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)
int mac_sequence_is_duplicate(void)
Tell whether the packetbuf is a duplicate packet.
linkaddr_t linkaddr_node_addr
The Rime address of the node.
802.15.4 frame creation and parsing functions
uint8_t ack_required
1 bit.
const linkaddr_t linkaddr_null
The null Rime address.
The MAC layer deferred the transmission for a later time.
Header file for the Rime buffer (packetbuf) management
#define NULL
The null pointer.
The MAC layer transmission could not be performed because of a fatal error.
Header file for MAC sequence numbers management
uint16_t packetbuf_totlen(void)
Get the total length of the header and data in the packetbuf.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
Parameters used by the frame802154_create() function.
uint8_t seq
Sequence number.
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
void watchdog_periodic(void)
Writes the WDT clear sequence.
Header file for the real-time timer module.
void mac_sequence_register_seqno(void)
Register the sequence number of the packetbuf.
int(* off)(int keep_radio_on)
Turn the MAC layer off.
Header file for the Rime queue buffer management
uint8_t dest_addr[8]
Destination address.
unsigned short(* channel_check_interval)(void)
Returns the channel check interval, expressed in clock_time_t ticks.
The structure of a RDC (radio duty cycling) driver in Contiki.
void(* init)(void)
Initialize the RDC driver.
The MAC layer transmission was OK.
#define RTIMER_NOW()
Get the current clock time.
int frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
Parses an input frame.
A null RDC implementation that uses framer for headers.
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two Rime addresses.
int(* on)(void)
Turn the MAC layer on.
The MAC layer did not get an acknowledgement for the packet.
Header file for Rime statistics
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
frame802154_fcf_t fcf
Frame control field.
void(* send_list)(mac_callback_t sent_callback, void *ptr, struct rdc_buf_list *list)
Send a packet list.
Include file for the Contiki low-layer network stack (NETSTACK)