From 108989b65d047eeff71ed5575512e8042f6fb633 Mon Sep 17 00:00:00 2001 From: Martin Lenders Date: Thu, 13 Feb 2014 15:18:16 +0100 Subject: [PATCH] Use net_if in 6LoWPAN MAC layer --- sys/net/include/sixlowpan/mac.h | 83 ++--- sys/net/network_layer/sixlowpan/icmp.c | 24 +- sys/net/network_layer/sixlowpan/ip.c | 1 + sys/net/network_layer/sixlowpan/lowpan.c | 32 +- sys/net/network_layer/sixlowpan/mac.c | 368 +++++++++++++---------- sys/net/routing/rpl/etx_beaconing.c | 15 +- 6 files changed, 272 insertions(+), 251 deletions(-) diff --git a/sys/net/include/sixlowpan/mac.h b/sys/net/include/sixlowpan/mac.h index a09960d788..84dbaef90e 100644 --- a/sys/net/include/sixlowpan/mac.h +++ b/sys/net/include/sixlowpan/mac.h @@ -34,78 +34,29 @@ #define IEEE_802154_MAX_ADDR_STR_LEN (12) /** - * @brief Gets current radio transmitter address. + * @brief Send an IEEE 802.15.4 frame to a long address. * - * @return Current radio address as 8-bit value. + * @param[in] if_id The interface to send over (will be ignored if + * *mcast* is 1). + * @param[in] dest The destination address of the frame (will be + * ignored if *mcast* is 1). + * @param[in] dest_len The lengts of the destination address in byte. + * @param[in] payload The payload of the frame. + * @param[in] length The length of the payload. + * @param[in] mcast send frame as multicast frame (*addr* and *if_id* + * will be ignored). + * + * @return Length of transmitted data in byte */ -uint8_t sixlowpan_mac_get_radio_address(void); +int sixlowpan_mac_send_ieee802154_frame(int if_id, const void *dest, + uint8_t dest_len, const void *payload, uint8_t length, uint8_t mcast); /** - * @brief Sets radio transmitter address. + * @brief Initialise 6LoWPAN MAC layer and register it to interface layer * - * @param[in] addr 8-bit radio address. + * @return PID of the MAC receiver thread. */ -void sixlowpan_mac_set_radio_address(uint8_t addr); - -/** - * @brief Generates EUI-64 from IEEE 802.15.4 PAN ID and - * radio transceiver address. - * - * @param[out] laddr The EUI-64 address of this node. - */ -void sixlowpan_mac_init_802154_long_addr(ieee_802154_long_t *laddr); - -/** - * @brief Generates IEEE 802.15.4 16-bit short address from radio - * transceiver address. - * - * @param[out] saddr The IEEE 802.15.4 16-bit short address of this - * node. - */ -void sixlowpan_mac_init_802154_short_addr(ieee_802154_short_t *saddr); - -/** - * @brief Get pointer to potential EUI-64 bit of the IPv6 address. - * - * @param[in] ipaddr An IPv6 address of this node. - * - * @return The EUI-64 address of this node. - */ -ieee_802154_long_t *sixlowpan_mac_get_eui64(const ipv6_addr_t *ipaddr); - -/** - * @brief Send an IEEE 802.15.4 frame. - * - * @param[in] addr The destination address of the frame. - * @param[in] payload The payload of the frame. - * @param[in] length The length of the payload. - * @param[in] mcast send frame as multicast frame (identical to - * give a destination address of 0). - */ -void sixlowpan_mac_send_ieee802154_frame(const ieee_802154_long_t *addr, - const uint8_t *payload, - uint8_t length, uint8_t mcast); - -/** - * @brief Initialise 6LoWPAN MAC interface - * - * @param[in] type Type of transceiver. - */ -void sixlowpan_mac_init(transceiver_type_t type); - -/** - * @brief Converts IEEE 802.15.4 long address into string. - * Note that addr_str must allocate at least - * IEEE_802154_MAX_ADDR_STR_LEN byte (12 byte). - * - * @param[out] addr_str The IEEE 802.15.4 long address as string. Must - * allocate at least IEEE_802154_ADDR_STR_LEN byte (12 - * byte). - * @param[in] laddr IEEE 802.15.4 address to be converted. - * - * @return Pointer to addr_str. - */ -char *sixlowpan_mac_802154_long_addr_to_str(char *addr_str, const ieee_802154_long_t *laddr); +int sixlowpan_mac_init(void); /** @} */ #endif /* SIXLOWPAN_MAC_H */ diff --git a/sys/net/network_layer/sixlowpan/icmp.c b/sys/net/network_layer/sixlowpan/icmp.c index af3881bf9f..5d93f56bbd 100644 --- a/sys/net/network_layer/sixlowpan/icmp.c +++ b/sys/net/network_layer/sixlowpan/icmp.c @@ -22,15 +22,13 @@ #include #include -#include "malloc.h" #include "vtimer.h" #include "mutex.h" +#include "net_if.h" #include "sixlowpan/error.h" -#include "sixlowpan/mac.h" #include "ip.h" #include "icmp.h" -#include "lowpan.h" #include "serialnumber.h" #include "net_help.h" @@ -857,6 +855,7 @@ void icmpv6_send_neighbor_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t * uint8_t sllao, uint8_t aro) { uint16_t packet_length; + int if_id = 0; // TODO: get this somehow ipv6_buf = ipv6_get_buf(); ipv6_buf->version_trafficclass = IPV6_VER; @@ -910,7 +909,14 @@ void icmpv6_send_neighbor_sol(ipv6_addr_t *src, ipv6_addr_t *dest, ipv6_addr_t * opt_aro_buf->status = 0; opt_aro_buf->reserved1 = 0; opt_aro_buf->reserved2 = 0; - memcpy(&(opt_aro_buf->eui64), sixlowpan_mac_get_eui64(src), 8); + + if (net_if_get_src_address_mode(if_id) == NET_IF_TRANS_ADDR_M_SHORT) { + net_if_get_eui64((net_if_eui64_t *) &opt_aro_buf->eui64, if_id, 1); + } + else if (net_if_get_src_address_mode(if_id) == NET_IF_TRANS_ADDR_M_LONG) { + net_if_get_eui64((net_if_eui64_t *) &opt_aro_buf->eui64, if_id, 0); + } + icmpv6_opt_hdr_len += OPT_ARO_HDR_LEN; packet_length += OPT_ARO_HDR_LEN; @@ -1114,6 +1120,7 @@ void recv_nbr_sol(void) void icmpv6_send_neighbor_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *tgt, uint8_t rso, uint8_t sllao, uint8_t aro) { + int if_id = 0; // TODO: get this somehow uint16_t packet_length; ipv6_buf = ipv6_get_buf(); @@ -1156,7 +1163,14 @@ void icmpv6_send_neighbor_adv(ipv6_addr_t *src, ipv6_addr_t *dst, ipv6_addr_t *t opt_aro_buf->status = 0; /* TODO */ opt_aro_buf->reserved1 = 0; opt_aro_buf->reserved2 = 0; - memcpy(&(opt_aro_buf->eui64), sixlowpan_mac_get_eui64(dst), 8); + + if (net_if_get_src_address_mode(if_id) == NET_IF_TRANS_ADDR_M_SHORT) { + net_if_get_eui64((net_if_eui64_t *) &opt_aro_buf->eui64, if_id, 1); + } + else if (net_if_get_src_address_mode(if_id) == NET_IF_TRANS_ADDR_M_LONG) { + net_if_get_eui64((net_if_eui64_t *) &opt_aro_buf->eui64, if_id, 0); + } + icmpv6_opt_hdr_len += OPT_ARO_HDR_LEN; packet_length += OPT_ARO_HDR_LEN; diff --git a/sys/net/network_layer/sixlowpan/ip.c b/sys/net/network_layer/sixlowpan/ip.c index 73a7566d18..7616e69787 100644 --- a/sys/net/network_layer/sixlowpan/ip.c +++ b/sys/net/network_layer/sixlowpan/ip.c @@ -25,6 +25,7 @@ #include "vtimer.h" #include "mutex.h" #include "msg.h" +#include "net_if.h" #include "sixlowpan/mac.h" #include "ip.h" diff --git a/sys/net/network_layer/sixlowpan/lowpan.c b/sys/net/network_layer/sixlowpan/lowpan.c index e0b6b95b59..00a20fff94 100644 --- a/sys/net/network_layer/sixlowpan/lowpan.c +++ b/sys/net/network_layer/sixlowpan/lowpan.c @@ -159,6 +159,7 @@ void lowpan_ipv6_set_dispatch(uint8_t *data); void sixlowpan_lowpan_sendto(const ieee_802154_long_t *dest, uint8_t *data, uint16_t data_len) { + int if_id = 0; uint8_t mcast = 0; ipv6_buf = (ipv6_hdr_t *) data; @@ -200,10 +201,11 @@ void sixlowpan_lowpan_sendto(const ieee_802154_long_t *dest, fragbuf[2] = tag >> 8; fragbuf[3] = tag; - sixlowpan_mac_send_ieee802154_frame(&laddr, - (uint8_t *)&fragbuf, + sixlowpan_mac_send_ieee802154_frame(if_id, dest, dest_len, + &fragbuf, max_frag_initial + header_size + 4, mcast); + /* subsequent fragments */ position = max_frag_initial; max_frag = ((max_frame - 5) / 8) * 8; @@ -220,9 +222,9 @@ void sixlowpan_lowpan_sendto(const ieee_802154_long_t *dest, fragbuf[3] = tag; fragbuf[4] = position / 8; - sixlowpan_mac_send_ieee802154_frame(&laddr, - (uint8_t *)&fragbuf, - max_frag + 5, mcast); + sixlowpan_mac_send_ieee802154_frame(if_id, dest, dest_len, + &fragbuf, + max_frame + 5, mcast); data += max_frag; position += max_frag; @@ -240,13 +242,15 @@ void sixlowpan_lowpan_sendto(const ieee_802154_long_t *dest, fragbuf[3] = tag; fragbuf[4] = position / 8; - sixlowpan_mac_send_ieee802154_frame(&laddr, - (uint8_t *)&fragbuf, - remaining + 5, mcast); + if (sixlowpan_mac_send_ieee802154_frame(if_id, dest, dest_len, + &fragbuf, remaining + 5, mcast) < 0) { + return -1; + } } else { - sixlowpan_mac_send_ieee802154_frame(&laddr, data, - send_packet_length, mcast); + return sixlowpan_mac_send_ieee802154_frame(if_id, dest, dest_len, + data, send_packet_length, + mcast); } tag++; @@ -1649,17 +1653,13 @@ void sixlowpan_lowpan_adhoc_init(transceiver_type_t trans, void lowpan_init(transceiver_type_t trans, uint8_t r_addr, const ipv6_addr_t *prefix, int as_border) { + int if_id = 0; ipv6_addr_t tmp; short i; - /* init mac-layer and radio transceiver */ - sixlowpan_mac_init(trans); /* init interface addresses */ memset(&iface, 0, sizeof(iface_t)); - sixlowpan_mac_set_radio_address(r_addr); - sixlowpan_mac_init_802154_short_addr(&(iface.saddr)); - sixlowpan_mac_init_802154_long_addr(&(iface.laddr)); /* init lowpan context mutex */ mutex_init(&lowpan_context_mutex); @@ -1705,6 +1705,8 @@ void lowpan_init(transceiver_type_t trans, uint8_t r_addr, ipv6_iface_add_addr(&tmp, IPV6_ADDR_TYPE_LOOPBACK, NDP_ADDR_STATE_PREFERRED, 0, 0); + /* init mac-layer and radio transceiver */ + sixlowpan_mac_init(); if (as_border) { ip_process_pid = thread_create(ip_process_buf, IP_PROCESS_STACKSIZE, PRIORITY_MAIN - 1, CREATE_STACKTEST, diff --git a/sys/net/network_layer/sixlowpan/mac.c b/sys/net/network_layer/sixlowpan/mac.c index 34c71cba6b..ab27207b31 100644 --- a/sys/net/network_layer/sixlowpan/mac.c +++ b/sys/net/network_layer/sixlowpan/mac.c @@ -24,13 +24,10 @@ #include #include -#include "ltc4150.h" -#include "hwtimer.h" #include "thread.h" #include "msg.h" #include "radio/radio.h" -#include "transceiver.h" -#include "vtimer.h" +#include "net_if.h" #include "sixlowpan/mac.h" #include "ip.h" @@ -49,110 +46,37 @@ #define RADIO_RCV_BUF_SIZE (64) #define RADIO_SENDING_DELAY (1000) +#define DEFAULT_IEEE_802154_PAN_ID (0x1234) +#define IEEE802154_TRANSCEIVER (TRANSCEIVER_AT86RF231 | TRANSCEIVER_CC2420 | TRANSCEIVER_MC1322X) + char radio_stack_buffer[RADIO_STACK_SIZE]; msg_t msg_q[RADIO_RCV_BUF_SIZE]; -static uint8_t r_src_addr; -uint8_t buf[PAYLOAD_SIZE]; +uint8_t lowpan_mac_buf[PAYLOAD_SIZE]; static uint8_t macdsn; -static radio_packet_t p; -static msg_t mesg; -int transceiver_type; -static transceiver_command_t tcmd; - -uint8_t sixlowpan_mac_get_radio_address(void) +static inline void mac_short_to_eui64(net_if_eui64_t *eui64, + uint16_t short_addr) { - int16_t address; - DEBUG("sixlowpan_mac_get_radio_address()\n"); - - tcmd.transceivers = transceiver_type; - tcmd.data = &address; - mesg.content.ptr = (char *)&tcmd; - mesg.type = GET_ADDRESS; - msg_send_receive(&mesg, &mesg, transceiver_pid); - - return (uint8_t)address; -} - -void sixlowpan_mac_set_radio_address(uint8_t addr) -{ - int16_t address = (int16_t)addr; - - tcmd.transceivers = transceiver_type; - tcmd.data = &address; - mesg.content.ptr = (char *)&tcmd; - mesg.type = SET_ADDRESS; - msg_send_receive(&mesg, &mesg, transceiver_pid); -} - -void set_radio_channel(uint8_t channel) -{ - int16_t chan = (int16_t)channel; - - tcmd.transceivers = transceiver_type; - tcmd.data = &chan; - mesg.content.ptr = (char *)&tcmd; - mesg.type = SET_CHANNEL; - msg_send_receive(&mesg, &mesg, transceiver_pid); -} - -void switch_to_rx(void) -{ - mesg.type = SWITCH_RX; - mesg.content.ptr = (char *) &tcmd; - tcmd.transceivers = TRANSCEIVER_CC1100; - msg_send(&mesg, transceiver_pid, 1); -} - -void sixlowpan_mac_init_802154_short_addr(ieee_802154_short_t *saddr) -{ - DEBUG("sixlowpan_mac_init_802154_short_addr(saddr=%02X)\n", *saddr); - saddr->uint8[0] = 0; - saddr->uint8[1] = sixlowpan_mac_get_radio_address(); -} - -ieee_802154_long_t *sixlowpan_mac_get_eui64(const ipv6_addr_t *ipaddr) -{ - return ((ieee_802154_long_t *) &ipaddr->uint8[8]); -} - -void sixlowpan_mac_init_802154_long_addr(ieee_802154_long_t *laddr) -{ -#ifdef DEBUG_ENABLED - char addr_str[IEEE_802154_MAX_ADDR_STR_LEN]; - sixlowpan_mac_802154_long_addr_to_str(addr_str, laddr); - DEBUG("sixlowpan_mac_init_802154_long_addr(laddr=%s)\n", addr_str); -#endif - - // 16bit Pan-ID:16-zero-bits:16-bit-short-addr = 48bit - laddr->uint16[0] = IEEE_802154_PAN_ID; - - /* RFC 4944 Section 6 / RFC 2464 Section 4 */ - laddr->uint8[0] ^= 0x02; - laddr->uint8[2] = 0; - laddr->uint8[3] = 0xFF; - laddr->uint8[4] = 0xFE; - laddr->uint8[5] = 0; - laddr->uint8[6] = 0; - laddr->uint8[7] = sixlowpan_mac_get_radio_address(); -} - -char *sixlowpan_mac_802154_long_addr_to_str(char *addr_str, const ieee_802154_long_t *laddr) -{ - sprintf(addr_str, - "%02x:%02x:%02x:%02x", - laddr->uint16[0], laddr->uint16[1], - laddr->uint16[2], laddr->uint16[3]); - return addr_str; + eui64->uint32[0] = HTONL(0x000000ff); + eui64->uint16[2] = HTONS(0xfe00); + eui64->uint16[3] = LETONS(short_addr); } void recv_ieee802154_frame(void) { msg_t m; +#if (defined(MODULE_AT86RF231) | \ + defined(MODULE_CC2420) | \ + defined(MODULE_MC1322X)) + ieee802154_packet_t *p; +#else radio_packet_t *p; - uint8_t hdrlen, length; + uint8_t hdrlen; +#endif + uint8_t length; ieee802154_frame_t frame; + net_if_eui64_t src, dst; msg_init_queue(msg_q, RADIO_RCV_BUF_SIZE); @@ -160,22 +84,84 @@ void recv_ieee802154_frame(void) msg_receive(&m); if (m.type == PKT_PENDING) { - +#if (defined(MODULE_AT86RF231) | \ + defined(MODULE_CC2420) | \ + defined(MODULE_MC1322X)) + p = (ieee802154_packet_t *) m.content.ptr; + memcpy(&frame, &p->frame, sizeof(ieee802154_frame_t)); + length = p->frame.payload_len; +#else p = (radio_packet_t *) m.content.ptr; hdrlen = ieee802154_frame_read(p->data, &frame, p->length); length = p->length - hdrlen - IEEE_802154_FCS_LEN; +#endif + +#ifdef DEBUG_ENABLED + DEBUG("INFO: Received IEEE 802.15.4. packet (length = %d):\n", length); + DEBUG("INFO: FCF:\n"); + ieee802154_frame_print_fcf_frame(&frame); + + DEBUG("Sender:"); + + for (uint8_t i = 0; i < 8; i++) { + printf("%02x ", frame.src_addr[i]); + } + + DEBUG("\n"); + + DEBUG("Receiver:"); + + for (size_t i = 0; i < 8; i++) { + printf("%02x ", frame.dest_addr[i]); + } + + DEBUG("\n"); + + DEBUG("Payload:\n"); + + for (uint8_t i = 0; i < frame.payload_len; i++) { + printf("%02x ", frame.payload[i]); + + if (!((i + 1) % 16) || i == frame.payload_len - 1) { + printf("\n"); + } + } + +#endif + + if (frame.fcf.src_addr_m == IEEE_802154_SHORT_ADDR_M) { + mac_short_to_eui64(&src, *((uint16_t *)frame.src_addr)); + } + else if (frame.fcf.src_addr_m == IEEE_802154_LONG_ADDR_M) { + memcpy(&src, frame.src_addr, 8); + } + else { + DEBUG("Unknown IEEE 802.15.4 source address mode.\n"); + continue; + } + + if (frame.fcf.dest_addr_m == IEEE_802154_SHORT_ADDR_M) { + mac_short_to_eui64(&dst, *((uint16_t *)frame.dest_addr)); + } + else if (frame.fcf.dest_addr_m == IEEE_802154_LONG_ADDR_M) { + memcpy(&dst, frame.dest_addr, 8); + } + else { + DEBUG("Unknown IEEE 802.15.4 destination address mode.\n"); + continue; + } /* deliver packet to network(6lowpan)-layer */ - lowpan_read(frame.payload, length, (ieee_802154_long_t *)&frame.src_addr, - (ieee_802154_long_t *)&frame.dest_addr); + lowpan_read(frame.payload, length, &src, &dst); + /* TODO: get interface ID somehow */ p->processing--; } else if (m.type == ENOBUFFER) { - puts("Transceiver buffer full"); + DEBUG("Transceiver buffer full"); } else { - puts("Unknown packet received"); + DEBUG("Unknown packet received"); } } } @@ -187,86 +173,158 @@ void set_ieee802154_fcf_values(ieee802154_frame_t *frame, uint8_t dest_mode, frame->fcf.sec_enb = 0; frame->fcf.frame_pend = 0; frame->fcf.ack_req = 0; - frame->fcf.panid_comp = 0; + frame->fcf.panid_comp = (frame->dest_pan_id == frame->src_pan_id); frame->fcf.frame_ver = 0; frame->fcf.src_addr_m = src_mode; frame->fcf.dest_addr_m = dest_mode; -#if ENABLE_DEBUG +#ifdef DEBUG_ENABLED ieee802154_frame_print_fcf_frame(frame); #endif } -void set_ieee802154_frame_values(ieee802154_frame_t *frame) +void set_ieee802154_frame_values(int if_id, uint16_t dest_pan, + ieee802154_frame_t *frame) { + int32_t pan_id = net_if_get_pan_id(if_id); // TODO: addresse aus ip paket auslesen und in frame einfuegen - frame->dest_pan_id = IEEE_802154_PAN_ID; - frame->src_pan_id = IEEE_802154_PAN_ID; + + if (pan_id < 0) { + frame->dest_pan_id = NTOLES(dest_pan); + frame->src_pan_id = HTOLES(DEFAULT_IEEE_802154_PAN_ID); + } + else { + frame->dest_pan_id = NTOLES(dest_pan); + frame->src_pan_id = HTOLES((uint16_t)pan_id); + } + frame->seq_nr = macdsn; macdsn++; } -void sixlowpan_mac_send_ieee802154_frame(const ieee_802154_long_t *addr, - const uint8_t *payload, - uint8_t length, uint8_t mcast) +int sixlowpan_mac_prepare_ieee802144_frame( + ieee802154_frame_t *frame, int if_id, uint16_t dest_pan, const void *dest, + uint8_t dest_len, const void *payload, uint8_t length, uint8_t mcast) { - uint16_t daddr; - /* TODO: check if dedicated response struct is necessary */ - msg_t transceiver_rsp; - r_src_addr = local_address; - mesg.type = SND_PKT; - mesg.content.ptr = (char *) &tcmd; + uint8_t src_mode = net_if_get_src_address_mode(if_id); + uint8_t dest_mode; + uint16_t *fcs; + set_ieee802154_frame_values(if_id, dest_pan, frame); - tcmd.transceivers = transceiver_type; - tcmd.data = &p; - - ieee802154_frame_t frame; - - memset(&frame, 0, sizeof(frame)); - set_ieee802154_fcf_values(&frame, IEEE_802154_LONG_ADDR_M, - IEEE_802154_LONG_ADDR_M); - set_ieee802154_frame_values(&frame); - - memcpy(&(frame.dest_addr[0]), &(addr->uint8[0]), 8); - memcpy(&(frame.src_addr[0]), &(iface.laddr.uint8[0]), 8); - - daddr = HTONS(addr->uint16[3]); - frame.payload = (uint8_t *)payload; // payload won't be changed so cast is legal. - frame.payload_len = length; - uint8_t hdrlen = ieee802154_frame_get_hdr_len(&frame); - - memset(&buf, 0, PAYLOAD_SIZE); - ieee802154_frame_init(&frame, (uint8_t *)&buf); - memcpy(&buf[hdrlen], frame.payload, frame.payload_len); - /* set FCS */ - /* RSSI = 0 */ - buf[frame.payload_len + hdrlen] = 0; - /* FCS Valid = 1 / LQI Correlation Value = 0 */ - buf[frame.payload_len + hdrlen + 1] = 0x80; - DEBUG("IEEE802.15.4 frame - FCF: %02X %02X DPID: %02X SPID: %02X DSN: %02X\n", buf[0], buf[1], frame.dest_pan_id, frame.src_pan_id, frame.seq_nr); - - p.length = hdrlen + frame.payload_len + IEEE_802154_FCS_LEN; - - if (mcast == 0) { - p.dst = daddr; + if (dest_len == 8) { + dest_mode = IEEE_802154_LONG_ADDR_M; + } + else if (dest_len == 2) { + dest_mode = IEEE_802154_SHORT_ADDR_M; } else { - p.dst = 0; + DEBUG("Illegal IEEE 802.15.4 address for address length %d\n", dest_len); + return -1; } - p.data = buf; - msg_send_receive(&mesg, &transceiver_rsp, transceiver_pid); + set_ieee802154_fcf_values(frame, dest_mode, src_mode); - hwtimer_wait(5000); + + if (src_mode == IEEE_802154_LONG_ADDR_M) { + net_if_get_eui64((net_if_eui64_t *)&frame->src_addr[0], if_id, 0); + } + else if (src_mode == IEEE_802154_SHORT_ADDR_M) { + uint16_t src = HTONS(net_if_get_hardware_address(if_id)); + memcpy(&frame->src_addr[0], &src, 2); + } + else { + DEBUG("Illegal IEEE 802.15.4 address mode: %d\n", src_mode); + return -1; + } + + if (mcast) { + memset(&frame->dest_addr[0], 0xff, dest_len); + } + else { + memcpy(&frame->dest_addr[0], dest, dest_len); + } + + frame->payload = (uint8_t *)payload; // payload won't be changed so cast is legal. + frame->payload_len = length; + uint8_t hdrlen = ieee802154_frame_get_hdr_len(frame); + + memset(&lowpan_mac_buf, 0, PAYLOAD_SIZE); + ieee802154_frame_init(frame, (uint8_t *)&lowpan_mac_buf); + memcpy(&lowpan_mac_buf[hdrlen], frame->payload, frame->payload_len); + /* set FCS */ + fcs = (uint16_t *)&lowpan_mac_buf[frame->payload_len + hdrlen]; + *fcs = ieee802154_frame_get_fcs(lowpan_mac_buf, frame->payload_len + hdrlen); + DEBUG("IEEE802.15.4 frame - FCF: %02X %02X DPID: %02X SPID: %02X DSN: %02X\n", + lowpan_mac_buf[0], lowpan_mac_buf[1], frame->dest_pan_id, + frame->src_pan_id, frame->seq_nr); + + return hdrlen; } -void sixlowpan_mac_init(transceiver_type_t type) +int sixlowpan_mac_send_data(int if_id, + const void *dest, uint8_t dest_len, + const void *payload, + uint8_t payload_len, uint8_t mcast) +{ + if (mcast) { + return net_if_send_packet_broadcast(IEEE_802154_SHORT_ADDR_M, + payload, + payload_len); + } + else { + if (dest_len == 8) { + return net_if_send_packet_long(if_id, (net_if_eui64_t *) dest, + payload, (size_t)payload_len); + } + else if (dest_len == 2) { + return net_if_send_packet(if_id, NTOHS(*((uint16_t *)dest)), + payload, (size_t)payload_len); + } + } + + return -1; +} + +int sixlowpan_mac_send_ieee802154_frame(int if_id, + const void *dest, uint8_t dest_len, + const void *payload, + uint8_t payload_len, uint8_t mcast) +{ + if (net_if_get_interface(if_id) && + net_if_get_interface(if_id)->transceivers & IEEE802154_TRANSCEIVER) { + return sixlowpan_mac_send_data(if_id, dest, dest_len, payload, + payload_len, mcast); + } + else { + ieee802154_frame_t frame; + uint16_t dest_pan = HTONS(0xabcd); + uint8_t length; + int hdrlen = sixlowpan_mac_prepare_ieee802144_frame(&frame, if_id, + dest_pan, dest, + dest_len, payload, + payload_len, mcast); + + if (hdrlen < 0) { + return -1; + } + + length = hdrlen + frame.payload_len + IEEE_802154_FCS_LEN; + + return sixlowpan_mac_send_data(if_id, dest, dest_len, lowpan_mac_buf, + length, mcast); + } +} + +int sixlowpan_mac_init(void) { int recv_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE, PRIORITY_MAIN - 2, CREATE_STACKTEST, recv_ieee802154_frame , "radio"); - transceiver_type = type; - transceiver_init(transceiver_type); - transceiver_start(); - transceiver_register(type, recv_pid); + int if_id = -1; + + while ((if_id = net_if_iter_interfaces(if_id)) >= 0) { + net_if_register(if_id, recv_pid); + } macdsn = rand() % 256; + + return recv_pid; } diff --git a/sys/net/routing/rpl/etx_beaconing.c b/sys/net/routing/rpl/etx_beaconing.c index cc16ddfb5d..e60f86a1da 100644 --- a/sys/net/routing/rpl/etx_beaconing.c +++ b/sys/net/routing/rpl/etx_beaconing.c @@ -169,14 +169,6 @@ void etx_beacon(void) etx_probe_t *packet = etx_get_send_buf(); uint8_t p_length = 0; - /* - * xxx If you get a -Wmissing-braces warning here: - * A -Wmissing-braces warning at this point is a gcc-bug! - * Please delete this information once it's fixed - * See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119 - */ - ieee_802154_long_t empty_addr = { {0} }; - while (true) { thread_sleep(); mutex_lock(&etx_mutex); @@ -194,7 +186,10 @@ void etx_beacon(void) } packet->length = p_length; - sixlowpan_mac_send_ieee802154_frame(&empty_addr, &etx_send_buf[0], + /* will be send broadcast, so if_id and destination address will be + * ignored (see documentation) + */ + sixlowpan_mac_send_ieee802154_frame(0, NULL, 8, &etx_send_buf[0], ETX_DATA_MAXLEN + ETX_PKT_HDR_LEN, 1); DEBUG("sent beacon!\n"); etx_set_packets_received(); @@ -394,7 +389,7 @@ void etx_radio(void) ipv6_addr_t candidate_addr; ipv6_addr_set_link_local_prefix(&ll_address); - ipv6_iface_get_best_src_addr(&candidate_addr, &ll_address); + ipv6_net_if_get_best_src_addr(&candidate_addr, &ll_address); while (1) { msg_receive(&m);