Merge pull request #644 from authmillenon/decouple_network_stack

Decouple network stack from transceiver
dev/timer
Martin Lenders 9 years ago
commit 79a16df7b8

@ -79,6 +79,12 @@ ifneq (,$(filter destiny,$(USEMODULE)))
endif
endif
ifneq (,$(filter sixlowborder,$(USEMODULE)))
ifeq (,$(filter sixlowpan,$(USEMODULE)))
USEMODULE += sixlowpan
endif
endif
ifneq (,$(filter sixlowpan,$(USEMODULE)))
ifeq (,$(filter ieee802154,$(USEMODULE)))
USEMODULE += ieee802154
@ -86,13 +92,13 @@ ifneq (,$(filter sixlowpan,$(USEMODULE)))
ifeq (,$(filter net_help,$(USEMODULE)))
USEMODULE += net_help
endif
ifeq (,$(filter semaphore,$(USEMODULE)))
USEMODULE += semaphore
ifeq (,$(filter net_if,$(USEMODULE)))
USEMODULE += net_if
endif
ifeq (,$(filter transceiver,$(USEMODULE)))
USEMODULE += transceiver
ifeq (,$(filter semaphore, $(USEMODULE)))
USEMODULE += semaphore
endif
ifeq (,$(filter vtimer,$(USEMODULE)))
ifeq (,$(filter vtimer, $(USEMODULE)))
USEMODULE += vtimer
endif
endif

@ -39,15 +39,6 @@ extern uint8_t ipv6_ext_hdr_len;
msg_t msg_q[RCV_BUFFER_SIZE];
/* prints current IPv6 adresses */
void rpl_udp_ip(int argc, char **argv)
{
(void) argc;
(void) argv;
ipv6_iface_print_addrs();
}
void rpl_udp_set_id(int argc, char **argv)
{
if (argc != 2) {
@ -95,7 +86,8 @@ void rpl_udp_monitor(void)
else if (m.type == IPV6_PACKET_RECEIVED) {
ipv6_buf = (ipv6_hdr_t *) m.content.ptr;
printf("IPv6 datagram received (next header: %02X)", ipv6_buf->nextheader);
printf(" from %s ", ipv6_addr_to_str(addr_str, &ipv6_buf->srcaddr));
printf(" from %s ", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
&ipv6_buf->srcaddr));
if (ipv6_buf->nextheader == IPV6_PROTO_NUM_ICMPV6) {
icmpv6_buf = (icmpv6_hdr_t *) &ipv6_buf[(LL_HDR_LEN + IPV6_HDR_LEN) + ipv6_ext_hdr_len];

@ -20,6 +20,7 @@
#include <stdio.h>
#include "net_if.h"
#include "posix_io.h"
#include "shell.h"
#include "shell_commands.h"
@ -37,7 +38,6 @@ const shell_command_t shell_commands[] = {
{"loop", "", rpl_udp_loop},
{"server", "Starts a UDP server", udp_server},
{"send", "Send a UDP datagram", udp_send},
{"ip", "Print all assigned IP addresses", rpl_udp_ip},
{"ign", "ignore node", rpl_udp_ignore},
{NULL, NULL, NULL}
};
@ -48,6 +48,7 @@ int main(void)
/* start shell */
posix_open(uart0_handler_pid, 0);
net_if_set_src_address_mode(0, NET_IF_TRANS_ADDR_M_SHORT);
shell_t shell;
shell_init(&shell, shell_commands, UART0_BUFSIZE, uart0_readc, uart0_putc);

@ -22,6 +22,7 @@
#include <string.h>
#include "vtimer.h"
#include "thread.h"
#include "net_if.h"
#include "sixlowpan.h"
#include "destiny.h"
#include "rpl.h"
@ -64,7 +65,9 @@ void rpl_udp_init(int argc, char **argv)
return;
}
state = rpl_init(TRANSCEIVER, id);
net_if_set_hardware_address(0, id);
state = rpl_init(0);
if (state != SIXLOWERROR_SUCCESS) {
printf("Error initializing RPL\n");
@ -95,11 +98,13 @@ void rpl_udp_init(int argc, char **argv)
ipv6_addr_t prefix, tmp;
ipv6_addr_init(&std_addr, 0xABCD, 0xEF12, 0, 0, 0x1034, 0x00FF, 0xFE00, id);
ipv6_addr_init_prefix(&prefix, &std_addr, 64);
plist_add(&prefix, 64, NDP_OPT_PI_VLIFETIME_INFINITE, 0, 1, ICMPV6_NDP_OPT_PI_FLAG_AUTONOM);
ipv6_init_iface_as_router();
ndp_add_prefix_info(0, &prefix, 64, NDP_OPT_PI_VLIFETIME_INFINITE,
NDP_OPT_PI_PLIFETIME_INFINITE, 1,
ICMPV6_NDP_OPT_PI_FLAG_AUTONOM);
ipv6_init_as_router();
/* add global address */
ipv6_addr_set_by_eui64(&tmp, &std_addr);
ipv6_iface_add_addr(&tmp, IPV6_ADDR_TYPE_GLOBAL, NDP_ADDR_STATE_PREFERRED, 0, 0);
ipv6_addr_set_by_eui64(&tmp, 0, &std_addr);
ipv6_net_if_add_addr(0, &tmp, NDP_ADDR_STATE_PREFERRED, 0, 0, 0);
/* set channel to 10 */
tcmd.transceivers = TRANSCEIVER;
@ -134,7 +139,8 @@ void rpl_udp_loop(int argc, char **argv)
if (!is_root) {
printf("my preferred parent:\n");
printf("%s\n", ipv6_addr_to_str(addr_str, (&mydodag->my_preferred_parent->addr)));
printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
(&mydodag->my_preferred_parent->addr)));
printf("parent lifetime: %d\n", mydodag->my_preferred_parent->lifetime);
}
@ -142,9 +148,11 @@ void rpl_udp_loop(int argc, char **argv)
for (int i = 0; i < RPL_MAX_ROUTING_ENTRIES; i++) {
if (rtable[i].used) {
printf("%s\n", ipv6_addr_to_str(addr_str, (&rtable[i].address)));
printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
(&rtable[i].address)));
puts("next hop");
printf("%s\n", ipv6_addr_to_str(addr_str, (&rtable[i].next_hop)));
printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
(&rtable[i].next_hop)));
printf("entry %d lifetime %d\n", i, rtable[i].lifetime);
if (!rpl_equal_id(&rtable[i].address, &rtable[i].next_hop)) {
@ -171,7 +179,8 @@ void rpl_udp_table(int argc, char **argv)
for (int i = 0; i < RPL_MAX_ROUTING_ENTRIES; i++) {
if (rtable[i].used) {
printf("%s\n", ipv6_addr_to_str(addr_str, (&rtable[i].address)));
printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
(&rtable[i].address)));
printf("entry %d lifetime %d\n", i, rtable[i].lifetime);
if (!rpl_equal_id(&rtable[i].address, &rtable[i].next_hop)) {
@ -200,12 +209,14 @@ void rpl_udp_dodag(int argc, char **argv)
}
printf("Part of Dodag:\n");
printf("%s\n", ipv6_addr_to_str(addr_str, (&mydodag->dodag_id)));
printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
(&mydodag->dodag_id)));
printf("my rank: %d\n", mydodag->my_rank);
if (!is_root) {
printf("my preferred parent:\n");
printf("%s\n", ipv6_addr_to_str(addr_str, (&mydodag->my_preferred_parent->addr)));
printf("%s\n", ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
(&mydodag->my_preferred_parent->addr)));
}
printf("---------------------------\n");

@ -128,7 +128,9 @@ void udp_send(int argc, char **argv)
printf("Error sending packet!\n");
}
else {
printf("Successful deliverd %i bytes over UDP to %s to 6LoWPAN\n", bytes_sent, ipv6_addr_to_str(addr_str, &ipaddr));
printf("Successful deliverd %i bytes over UDP to %s to 6LoWPAN\n",
bytes_sent, ipv6_addr_to_str(addr_str, IPV6_MAX_ADDR_STR_LEN,
&ipaddr));
}
destiny_socket_close(sock);

@ -57,6 +57,9 @@ endif
ifneq (,$(filter sixlowpan,$(USEMODULE)))
DIRS += net/network_layer/sixlowpan
endif
ifneq (,$(filter sixlowborder,$(USEMODULE)))
DIRS += net/network_layer/sixlowpan/border
endif
ifneq (,$(filter rpl,$(USEMODULE)))
DIRS += net/routing/rpl
endif

@ -51,6 +51,10 @@
#include "rtc.h"
#endif
#ifdef MODULE_SIXLOWPAN
#include "sixlowpan.h"
#endif
#ifdef MODULE_DESTINY
#include "destiny.h"
#endif
@ -63,6 +67,14 @@
#define ENABLE_DEBUG (0)
#include "debug.h"
#ifndef CONF_RADIO_ADDR
#define CONF_RADIO_ADDR (1)
#endif
#ifndef CONF_PAN_ID
#define CONF_PAN_ID (0xabcd)
#endif
extern int main(void);
void auto_init(void)
@ -103,6 +115,7 @@ void auto_init(void)
MCI_initialize();
#endif
#ifdef MODULE_NET_IF
int iface;
DEBUG("Auto init net_if module.\n");
transceiver_type_t transceivers = 0;
#ifdef MODULE_AT86RF231
@ -128,13 +141,32 @@ void auto_init(void)
if (transceivers != 0) {
transceiver_init(transceivers);
transceiver_start();
int iface = net_if_init_interface(0, transceivers);
iface = net_if_init_interface(0, transceivers);
if (!net_if_get_hardware_address(iface)) {
DEBUG("Auto init radio address on interface %d to 0x%04x\n", iface, CONF_RADIO_ADDR);
DEBUG("Change this value at compile time with macro CONF_RADIO_ADDR\n");
net_if_set_hardware_address(iface, CONF_RADIO_ADDR);
}
if (net_if_get_pan_id(iface) <= 0) {
DEBUG("Auto init PAN ID on interface %d to 0x%04x\n", iface, CONF_PAN_ID);
DEBUG("Change this value at compile time with macro CONF_PAN_ID\n");
net_if_set_pan_id(iface, CONF_PAN_ID);
}
if (iface >= 0) {
DEBUG("Interface %d initialized\n", iface);
DEBUG("Auto init interface %d\n", iface);
}
}
else {
iface = -1;
}
#ifdef MODULE_SIXLOWPAN
DEBUG("Auto init 6LoWPAN module.\n");
sixlowpan_lowpan_init();
#endif
#endif
#ifdef MODULE_PROFILING
extern void profiling_init(void);

@ -26,23 +26,44 @@
#include <stdint.h>
/* maximum 802.15.4 header length */
#define IEEE_802154_MAX_HDR_LEN 23
#define IEEE_802154_MAX_HDR_LEN (23)
/* ...and FCS*/
#define IEEE_802154_FCS_LEN 2
#define IEEE_802154_FCS_LEN (2)
#define IEEE_802154_BEACON_FRAME 0
#define IEEE_802154_DATA_FRAME 1
#define IEEE_802154_ACK_FRAME 2
#define IEEE_802154_MAC_CMD_FRAME 3
#define IEEE_802154_BEACON_FRAME (0)
#define IEEE_802154_DATA_FRAME (1)
#define IEEE_802154_ACK_FRAME (2)
#define IEEE_802154_MAC_CMD_FRAME (3)
#define IEEE_802154_SHORT_ADDR_M 2
#define IEEE_802154_LONG_ADDR_M 3
#define IEEE_802154_SHORT_ADDR_M (2)
#define IEEE_802154_LONG_ADDR_M (3)
#define IEEE_802154_SHORT_MCAST_ADDR (0xffff)
#define IEEE_802154_LONG_MCAST_ADDR {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
0xff, 0xff}}
/**
* @brief Transform 16-bit number from network order (big-endian) to
* little-endian byte order (as used by IEEE 802.15.4).
*/
#define NTOLES(a) (((a) >> 8) | (((a) & 0x00ff) << 8))
/**
* @brief Transform 16-bit number from little-endian byte order to network
* order (big-endian).
*/
#define LETONS(a) NTOLES(a)
#define IEEE_802154_PAN_ID 0x1234
/**
* @brief Transform 16-bit number from host byte order to little-endian byte
* order (as used by IEEE 802.15.4).
*/
#define HTOLES(a) a
/**
* @brief Transform 16-bit number from little-endian byte order to host byte
* order.
*/
#define LETOHS(a) HTOLES(a)
typedef struct __attribute__((packed)) {
uint8_t frame_type;
@ -84,6 +105,7 @@ uint8_t ieee802154_frame_init(ieee802154_frame_t *frame, uint8_t *buf);
uint8_t ieee802154_frame_get_hdr_len(ieee802154_frame_t *frame);
uint8_t ieee802154_frame_read(uint8_t *buf, ieee802154_frame_t *frame, uint8_t len);
void ieee802154_frame_print_fcf_frame(ieee802154_frame_t *frame);
uint16_t ieee802154_frame_get_fcs(const uint8_t *frame, uint8_t frame_len);
/** @} */
#endif /* IEEE802154_IEEE802154_FRAME */

@ -150,7 +150,7 @@ void icmpv6_send_parameter_prob(ipv6_addr_t *src, ipv6_addr_t *dest,
* @param[in] data_len Length of data payload.
*/
void icmpv6_send_echo_request(ipv6_addr_t *destaddr, uint16_t id,
uint16_t seq, char *data,
uint16_t seq, uint8_t *data,
size_t data_len);
/**
@ -163,7 +163,7 @@ void icmpv6_send_echo_request(ipv6_addr_t *destaddr, uint16_t id,
* @param[in] data_len Length of data payload.
*/
void icmpv6_send_echo_reply(ipv6_addr_t *destaddr, uint16_t id,
uint16_t seq, char *data, size_t data_len);
uint16_t seq, uint8_t *data, size_t data_len);
/**
* @brief Send ICMPv6 router solicitation.
@ -232,5 +232,16 @@ 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);
/**
* @brief Calculates the checksum for ICMPv6 packets.
*
* @param[in] ipv6_buf The initialized IPv6 header of the packet.
* @param[in] icmpv6_buf The initialized ICMPv6_header of the packet
* (except checksum, payload is expected directly
* after the packet header in memory).
*
* @return The internet checksum of the given ICMPv6 packet.
*/
uint16_t icmpv6_csum(ipv6_hdr_t *ipv6_buf, icmpv6_hdr_t *icmpv6_buf);
/** @} */
#endif /* SIXLOWPAN_ICMP_H */

@ -24,6 +24,9 @@
#include <stdint.h>
#include "inet_ntop.h"
#include "net_help.h"
#include "net_if.h"
#include "sixlowpan/types.h"
/**
@ -32,7 +35,17 @@
#define IPV6_MTU (256)
/**
* @brief Maximum length of a IPv6 address represented as string.
* @brief Length of an IPv6 address in byte.
*/
#define IPV6_ADDR_LEN (16)
/**
* @brief Length of an IPv6 address in bit.
*/
#define IPV6_ADDR_BIT_LEN (128)
/**
* @brief Maximum length of an IPv6 address represented as string.
*/
#define IPV6_MAX_ADDR_STR_LEN (40)
@ -92,7 +105,22 @@ ipv6_hdr_t *ipv6_get_buf(void);
* is going to try to find a route
*/
int ipv6_sendto(const ipv6_addr_t *dest, uint8_t next_header,
const uint8_t *payload, uint16_t payload_length);
const uint8_t *payload, uint16_t payload_length);
/**
* @brief Send an IPv6 packet defined by its header.
*
* @param[in] packet Pointer to an prepared IPv6 packet header.
* The payload is expected directly after the
* packet.
*
* @return length of payload : on success
* -1 : if no route to the given dest could be obtained
* Packet is dropped
* In case of reactive routing: routing is going
* to try to find a route
*/
int ipv6_send_packet(ipv6_hdr_t *packet);
/**
* @brief Determines if node is a router.
@ -101,6 +129,20 @@ int ipv6_sendto(const ipv6_addr_t *dest, uint8_t next_header,
*/
uint8_t ipv6_is_router(void);
/**
* @brief Sets the default hop limit to use with IPv6 packets.
*
* @param[in] hop_limit The hop limit to set the default hop limit to.
*/
void ipv6_set_default_hop_limit(uint8_t hop_limit);
/**
* @brief Gets the default hop limit that is used for IPv6 packets.
*
* @return The current default hop limit for IPv6 packets.
*/
uint8_t ipv6_get_default_hop_limit(void);
/**
* @brief Registers a handler thread for incoming IP packets.
*
@ -131,7 +173,11 @@ void ipv6_register_rpl_handler(int pid);
*
* @param[in,out] ipv6_addr The address to set.
*/
void ipv6_addr_set_link_local_prefix(ipv6_addr_t *ipv6_addr);
static inline void ipv6_addr_set_link_local_prefix(ipv6_addr_t *ipv6_addr)
{
ipv6_addr->uint32[0] = HTONL(0xfe800000);
ipv6_addr->uint32[1] = 0;
}
/**
* @brief Sets IPv6 address *out* according to the remaining
@ -152,16 +198,20 @@ void ipv6_addr_init(ipv6_addr_t *out, uint16_t addr0, uint16_t addr1,
uint16_t addr5, uint16_t addr6, uint16_t addr7);
/**
* @brief Sets IPv6 address *out* using the given *prefix* and this
* nodes EUI-64 (i. e. interface must be initialized).
* @brief Sets IPv6 address *out* using the given *prefix* and an interface's
* EUI-64.
*
*
* @param[out] out Address to be set.
* @param[in] if_id The interface to take the EUI-64 from.
* @param[in] prefix 64-bit network prefix to be used for *out*
* (only the first 64 bit of the ipv6_addr_t type
* are copied to *out*)
*
* @return The Address to be set on success, NULL on error.
*/
void ipv6_addr_set_by_eui64(ipv6_addr_t *out,
const ipv6_addr_t *prefix);
ipv6_addr_t *ipv6_addr_set_by_eui64(ipv6_addr_t *out, int if_id,
const ipv6_addr_t *prefix);
/**
* @brief Sets IPv6 address *out* with the first *bits* bit taken
@ -184,7 +234,13 @@ void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix,
*
* @param[out] ipv6_addr Is set to the loopback address.
*/
void ipv6_addr_set_loopback_addr(ipv6_addr_t *ipv6_addr);
static inline void ipv6_addr_set_loopback_addr(ipv6_addr_t *ipv6_addr)
{
ipv6_addr->uint32[0] = 0;
ipv6_addr->uint32[1] = 0;
ipv6_addr->uint32[2] = 0;
ipv6_addr->uint32[3] = HTONL(1);
}
/**
* @brief Set *ipv6_addr* to a link-local all routers multicast
@ -197,7 +253,13 @@ void ipv6_addr_set_loopback_addr(ipv6_addr_t *ipv6_addr);
* @param[out] ipv6_addr Is set to a link-local all routers multicast
* address.
*/
void ipv6_addr_set_all_routers_addr(ipv6_addr_t *ipv6_addr);
static inline void ipv6_addr_set_all_routers_addr(ipv6_addr_t *ipv6_addr)
{
ipv6_addr->uint32[0] = HTONL(0xff020000);
ipv6_addr->uint32[1] = 0;
ipv6_addr->uint32[2] = 0;
ipv6_addr->uint32[3] = HTONL(2);
}
/**
* @brief Set *ipv6_addr* to a link-local all nodes multicast address
@ -210,7 +272,13 @@ void ipv6_addr_set_all_routers_addr(ipv6_addr_t *ipv6_addr);
* @param[out] ipv6_addr Is set to a link-local all nodes multicast
* address.
*/
void ipv6_addr_set_all_nodes_addr(ipv6_addr_t *ipv6_addr);
static inline void ipv6_addr_set_all_nodes_addr(ipv6_addr_t *ipv6_addr)
{
ipv6_addr->uint32[0] = HTONL(0xff020000);
ipv6_addr->uint32[1] = 0;
ipv6_addr->uint32[2] = 0;
ipv6_addr->uint32[3] = HTONL(1);
}
/**
* @brief Set *ipv6_addr_out* to the solicited-node multicast address
@ -225,22 +293,34 @@ void ipv6_addr_set_all_nodes_addr(ipv6_addr_t *ipv6_addr);
* @param[in] ipv6_addr_in The IPv6 address the solicited-node
* address.
*/
void ipv6_addr_set_solicited_node_addr(ipv6_addr_t *ipv6_addr_out,
const ipv6_addr_t *ipv6_addr_in);
static inline void ipv6_addr_set_solicited_node_addr(ipv6_addr_t *ipv6_addr_out,
const ipv6_addr_t *ipv6_addr_in)
{
/* copy only the last 24-bit of the ip-address that is beeing resolved */
ipv6_addr_out->uint32[0] = HTONL(0xff020000);
ipv6_addr_out->uint32[1] = 0;
ipv6_addr_out->uint32[2] = HTONS(1);
ipv6_addr_out->uint8[12] = 0xff;
ipv6_addr_out->uint8[13] = ipv6_addr_in->uint8[13];
ipv6_addr_out->uint16[7] = ipv6_addr_in->uint16[7];
}
/**
* @brief Converts IPv6 address into string (unabbrivated notation).
* Note that addr_str must allocate at least
* IPV6_MAX_ADDR_STR_LEN byte (40 byte).
* @brief Converts IPv6 address into string.
*
* @param[out] addr_str The IPv6 address as string. Must allocate
* at least IPV6_MAX_ADDR_STR_LEN byte (40
* byte).
* @param[in] str_len The maximum length available to *addr_str*.
* @param[in] ipv6_addr IPv6 address to be converted.
*
* @return Pointer to addr_str.
*/
char *ipv6_addr_to_str(char *addr_str, const ipv6_addr_t *ipv6_addr);
static inline const char *ipv6_addr_to_str(char *addr_str, uint8_t str_len,
const ipv6_addr_t *ipv6_addr)
{
return inet_ntop(AF_INET6, ipv6_addr, addr_str, (size_t)str_len);
}
/**
* @brief Checks if two IPv6 addresses are equal.
@ -250,7 +330,13 @@ char *ipv6_addr_to_str(char *addr_str, const ipv6_addr_t *ipv6_addr);
*
* @return 1 if *a* and *b* are equal, 0 otherwise.
*/
int ipv6_addr_is_equal(const ipv6_addr_t *a, const ipv6_addr_t *b);
static inline int ipv6_addr_is_equal(const ipv6_addr_t *a, const ipv6_addr_t *b)
{
return (a->uint32[0] == b->uint32[0]) &&
(a->uint32[1] == b->uint32[1]) &&
(a->uint32[2] == b->uint32[2]) &&
(a->uint32[3] == b->uint32[3]);
}
/**
* @brief Checks if *ipv6_addr* is unspecified (all zero).
@ -263,10 +349,16 @@ int ipv6_addr_is_equal(const ipv6_addr_t *a, const ipv6_addr_t *b);
*
* @return 1 if *ipv6_addr* is unspecified address, 0 otherwise.
*/
int ipv6_addr_is_unspecified(const ipv6_addr_t *ipv6_addr);
static inline int ipv6_addr_is_unspecified(const ipv6_addr_t *ipv6_addr)
{
return (ipv6_addr->uint32[0] == 0) &&
(ipv6_addr->uint32[1] == 0) &&
(ipv6_addr->uint32[2] == 0) &&
(ipv6_addr->uint32[3] == 0);
}
/**
* @brief Check if *ipv6_addr* is a link-local address.
* @brief Check if *ipv6_addr* is a multicast address.
*
* @see <a href="http://tools.ietf.org/html/rfc4291">
* RFC 4291
@ -274,26 +366,34 @@ int ipv6_addr_is_unspecified(const ipv6_addr_t *ipv6_addr);
*
* @param[in] ipv6_addr An IPv6 address.
*
* @return 1 if *ipv6_addr* is link-local address, 0 otherwise.
* @return 1 if *ipv6_addr* is multicast address, 0 otherwise.
*/
int ipv6_addr_is_link_local(const ipv6_addr_t *ipv6_addr);
static inline int ipv6_addr_is_multicast(const ipv6_addr_t *ipv6_addr)
{
return (ipv6_addr->uint8[0] == 0xff);
}
/**
* @brief Check if *ipv6_addr* is unique local unicast address.
* @brief Checks if *ipv6_addr* is a loopback address.
*
* @see <a href="http://tools.ietf.org/html/rfc4193">
* RFC 4193
* @see <a href="http://tools.ietf.org/html/rfc4291">
* RFC 4291
* </a>
*
* @param[in] ipv6_addr An IPv6 address.
* @param[in] ipv6_addr An IPv6 address.
*
* @return 1 if *ipv6_addr* is unique local unicast address,
* 0 otherwise.
* @return 1 if *ipv6_addr* is loopback address, 0 otherwise.
*/
int ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *addr);
static inline int ipv6_addr_is_loopback(const ipv6_addr_t *ipv6_addr)
{
return ipv6_addr->uint32[0] == 0 &&
ipv6_addr->uint32[1] == 0 &&
ipv6_addr->uint32[2] == 0 &&
NTOHL(ipv6_addr->uint32[3]) == 1;
}
/**
* @brief Check if *ipv6_addr* is a multicast address.
* @brief Check if *ipv6_addr* is a link-local address.
*
* @see <a href="http://tools.ietf.org/html/rfc4291">
* RFC 4291
@ -301,9 +401,32 @@ int ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *addr);
*
* @param[in] ipv6_addr An IPv6 address.
*
* @return 1 if *ipv6_addr* is multicast address, 0 otherwise.
* @return 1 if *ipv6_addr* is link-local address, 0 otherwise.
*/
static inline int ipv6_addr_is_link_local(const ipv6_addr_t *ipv6_addr)
{
return ((ipv6_addr->uint32[0] == HTONL(0xfe800000)) &&
(ipv6_addr->uint32[1] == 0)) ||
(ipv6_addr_is_multicast(ipv6_addr) &&
(ipv6_addr->uint8[1] & 0x0f) == 2);
}
/**
* @brief Check if *ipv6_addr* is unique local unicast address.
*
* @see <a href="http://tools.ietf.org/html/rfc4193">
* RFC 4193
* </a>
*
* @param[in] ipv6_addr An IPv6 address.
*
* @return 1 if *ipv6_addr* is unique local unicast address,
* 0 otherwise.
*/
int ipv6_addr_is_multicast(const ipv6_addr_t *ipv6_addr);
static inline int ipv6_addr_is_unique_local_unicast(const ipv6_addr_t *ipv6_addr)
{
return ((ipv6_addr->uint8[0] == 0xfc) || (ipv6_addr->uint8[0] == 0xfd));
}
/**
* @brief Check if *ipv6_addr* is solicited-node multicast address.
@ -317,7 +440,28 @@ int ipv6_addr_is_multicast(const ipv6_addr_t *ipv6_addr);
* @return 1 if *ipv6_addr* is solicited-node multicast address,
* 0 otherwise.
*/
int ipv6_addr_is_solicited_node(const ipv6_addr_t *ipv6_addr);
static inline int ipv6_addr_is_solicited_node(const ipv6_addr_t *ipv6_addr)
{
return (ipv6_addr->uint32[0] == HTONL(0xff020000)) &&
(ipv6_addr->uint32[1] == 0) &&
(ipv6_addr->uint32[2] == HTONL(1)) &&
(ipv6_addr->uint8[12] == 0xff);
}
/**
* @brief Get pointer to potential EUI-64 bit of the IPv6 address.
*
* @param[in] ipv6_addr An IPv6 address of this node.
* @param[in] prefix_len Length of the prefix. Only multiples of 8 are
* possible.
*
* @return The IID (as EUI-64) of this node.
*/
static inline net_if_eui64_t *ipv6_addr_get_iid(const ipv6_addr_t *ipv6_addr,
uint8_t prefix_len)
{
return ((net_if_eui64_t *) &ipv6_addr->uint8[prefix_len / 8]);
}
/*
* TODO to wrap sixlowpan initialisations
@ -325,26 +469,35 @@ int ipv6_addr_is_solicited_node(const ipv6_addr_t *ipv6_addr);
*/
/**
* @brief Add an IPv6 address to this nodes interface.
* @brief Add an IPv6 address to one of this nodes interfaces.
*
* @see <a href="http://tools.ietf.org/html/rfc4862">
* RFC 4862
* </a>
*
* @param[in] if_id The interface's ID.
* @param[in] addr Address to be added to the interface.
* @param[in] type Type of this address.
* @param[in] state Initial state of the address.
* @param[in] val_ltime Valid lifetime of this address in seconds.
* @param[in] val_ltime Valid lifetime of this address in seconds. Set 0
* for unspecified.
* @param[in] pref_ltime Preferred lifetime of this address in
* seconds.
* seconds. Set 0 for unspecified.
* @param[in] is_anycast Determines if an address is anycast. Anycast
* addresses are syntactically undistinguishable
* from unicast addresses and can only be identified
* with this flag. If *addr* is no unicast address
* and *is_anycast* is set, this function will fail.
*
* @return 1 on success, 0 on failure.
*/
void ipv6_iface_add_addr(const ipv6_addr_t *addr, ipv6_addr_type_t type,
int ipv6_net_if_add_addr(int if_id, const ipv6_addr_t *addr,
ndp_addr_state_t state, uint32_t val_ltime,
uint32_t pref_ltime);
uint32_t pref_ltime, uint8_t is_anycast);
/**
* @brief Tries to determine best suitable source address attached to
* the interface of this node based on the given destination
* an interface of this node based on the given destination
* address. The use-case for this function is to find a
* suitable address for the source address field of an IPv6
* address upon sending. *src* may be empty (all zero) if there
@ -352,16 +505,11 @@ void ipv6_iface_add_addr(const ipv6_addr_t *addr, ipv6_addr_type_t type,
*
* @param[out] src The best source address for this node (may be
* all zero if ther is none).
* @param[in] if_id The interface's ID.
* @param[in] dest The destination address for a packet we search
* the source address for.
*/
void ipv6_iface_get_best_src_addr(ipv6_addr_t *src,
const ipv6_addr_t *dest);
/**
* @brief Print all addresses attached to the interface to stdout.
*/
void ipv6_iface_print_addrs(void);
void ipv6_net_if_get_best_src_addr(ipv6_addr_t *src, const ipv6_addr_t *dest);
/**
* @brief Registers a function that decides how to route incomming
@ -375,7 +523,7 @@ void ipv6_iface_print_addrs(void);
*
* @param next_hop function that returns the next hop to reach dest
*/
void ipv6_iface_set_routing_provider(ipv6_addr_t *(*next_hop)(ipv6_addr_t* dest));
void ipv6_iface_set_routing_provider(ipv6_addr_t *(*next_hop)(ipv6_addr_t *dest));
/**
* @brief Calculates the IPv6 upper-layer checksum.

@ -25,6 +25,8 @@
#include <stdint.h>
#include "transceiver.h"
#include "net_help.h"
#include "net_if.h"
#include "sixlowpan/types.h"
/**
@ -178,26 +180,44 @@ typedef struct __attribute__((packed)) {
/**
* @brief Initializes 6LoWPAN.
* @brief Initializes all addresses on an interface needed for 6LoWPAN.
*
* @param[in] trans Transceiver to use with 6LoWPAN.
* @param[in] r_addr PHY layer address.
* @param[in] as_border 1 if node should act as border router,
* 0 otherwise.
* @param[in] if_id The interface to use with 6LoWPAN.
*
* @return 1 on success, 0 on failure.
*/
void sixlowpan_lowpan_init(transceiver_type_t trans, uint8_t r_addr,
int as_border);
int sixlowpan_lowpan_init_interface(int if_id);
/**
* @brief Checks if an EUI-64 was set from a short address. If so
* it returns this address, else 0
*
* @param[in] iid An EUI-64.
*
* @return The short address on success, 0 on failure.
*/
static inline uint16_t sixlowpan_lowpan_eui64_to_short_addr(const net_if_eui64_t *iid)
{
if (iid->uint32[0] == HTONL(0x000000ff) &&
iid->uint16[2] == HTONS(0xfe00)) {
return NTOHS(iid->uint16[3]);
}
return 0;
}
/**
* @brief Initializes a 6LoWPAN router with address prefix
* @brief Initializes all addresses and prefixes on an interface needed
* for 6LoWPAN. Calling this function together with
* sixlowpan_lowpan_init_interface() is not necessary.
*
* @param[in] trans transceiver to use with 6LoWPAN.
* @param[in] if_id The interface to use with 6LoWPAN.
* @param[in] prefix the address prefix to advertise.
* @param[in] r_addr PHY layer address.
*
* @return 1 on success, 0 on failure.
*/
void sixlowpan_lowpan_adhoc_init(transceiver_type_t trans,
const ipv6_addr_t *prefix,
uint8_t r_addr);
int sixlowpan_lowpan_init_adhoc_interface(int if_id,
const ipv6_addr_t *prefix);
/**
* @brief Initializes a 6LoWPAN border router with an address
@ -205,26 +225,26 @@ void sixlowpan_lowpan_adhoc_init(transceiver_type_t trans,
* @note Currently only working with addresses generated from
* IEEE 802.15.4 16-bit short addresses.
*
* @param[in] trans transceiver to use with 6LoWPAN.
* @param[in] border_router_addr Address of this border router.
* @param[in] if_id The interface to use with 6LoWPAN.
*
* @return SIXLOWERROR_SUCCESS on success, otherwise SIXLOWERROR_ADDRESS if
* address was not generated from IEEE 802.15.4 16-bit short
* address.
* @return 1 on success, 0 on failure.
*/
uint8_t sixlowpan_lowpan_border_init(transceiver_type_t trans,
const ipv6_addr_t *border_router_addr);
int sixlowpan_lowpan_border_init(int if_id);
/**
* @brief Send data via 6LoWPAN to destination node dest.
* @brief Send data via 6LoWPAN to destination node or next hop dest.
*
* @param[in] dest EUI-64 of destination node.
* @param[in] if_id The interface to send the data over.
* @param[in] dest Hardware address of the next hop or destination node.
* @param[in] dest_len Length of the destination address in byte.
* @param[in] data Data to send to destination node (may be
* manipulated).
* @param[in] data_len Length of data.
*
* @return length of transmitted data on success, -1 on failure.
*/
void sixlowpan_lowpan_sendto(const ieee_802154_long_t *dest,
uint8_t *data, uint16_t data_len);
int sixlowpan_lowpan_sendto(int if_id, const void *dest, int dest_len,
uint8_t *data, uint16_t data_len);
/**
* @brief Set header compression status for 6LoWPAN.
@ -272,5 +292,12 @@ void sixlowpan_lowpan_print_fifo_buffers(void);
void sixlowpan_lowpan_print_reassembly_buffers(void);
#endif
/**
* @brief Initializes 6LoWPAN module.
*
* @return 1 on success, 0 on failure.
*/
int sixlowpan_lowpan_init(void);
/** @} */
#endif /* SIXLOWPAN_LOWPAN_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.
*/
uint8_t sixlowpan_mac_get_radio_address(void);
/**
* @brief Sets radio transmitter address.
*
* @param[in] addr 8-bit radio address.
*/
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[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).
*
* @param[out] laddr The EUI-64 address of this node.
* @return Length of transmitted data in byte
*/
void sixlowpan_mac_init_802154_long_addr(ieee_802154_long_t *laddr);
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 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.
* @brief Initialise 6LoWPAN MAC layer and register it to interface layer
*
* @return Pointer to addr_str.
* @return PID of the MAC receiver thread.
*/
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 */

@ -24,6 +24,7 @@
#include <stdint.h>
#include "net_if.h"
#include "timex.h"
#include "sixlowpan/types.h"
@ -32,6 +33,7 @@
#define NDP_OPT_SLLAO_TYPE (1)
#define NDP_OPT_TLLAO_TYPE (2)
#define NDP_OPT_PI_VLIFETIME_INFINITE (0xffffffff)
#define NDP_OPT_PI_PLIFETIME_INFINITE (0xffffffff)
#define NDP_OPT_ARO_STATE_SUCCESS (0)
#define NDP_OPT_ARO_STATE_DUP_ADDR (1)
#define NDP_OPT_ARO_STATE_NBR_CACHE_FULL (2)
@ -64,18 +66,37 @@ typedef enum __attribute__((packed)) {
/**
* @brief Prefix list type to store information spread by prefix
* information option.
* information option on the interface.
*
* @see net_if_addr_t
*/
typedef struct __attribute__((packed)) {
uint8_t inuse; ///< Prefix is in in use.
uint8_t adv;
ipv6_addr_t addr; ///< The Prefix.
uint8_t length; ///< Length of the prefix.
uint8_t l_a_reserved1; ///< L and A flag of prefix information option
uint32_t val_ltime; ///< valid lifetime
uint32_t pref_ltime; ///< preferred lifetime
uint8_t infinite; ///< flag to set to infinite lifetime
} ndp_prefix_list_t;
typedef struct __attribute__((packed)) ndp_prefix_info_t {
/**
* @brief The next on the interface. Intialise with NULL
*/
struct ndp_prefix_info_t *addr_next;
/**
* @brief The prev address on the interface. Initialise with NULL
*/
struct ndp_prefix_info_t *addr_prev;
/**
* @brief Flags to define upper layer protocols this address applies to.
* For this layer NET_IF_L3P_IPV6_PREFIX must be set.
*/
net_if_l3p_t prefix_protocol;
ipv6_addr_t *prefix_data; ///< The Prefix.
uint8_t prefix_len; ///< Length of the prefix.
uint8_t inuse; ///< Prefix is in in use.
/**
* Use this information in Prefix Information Options of Router
* Advertisements.
*/
uint8_t advertisable;
uint8_t flags; ///< flags of the prefix information option
uint32_t valid_lifetime; ///< valid lifetime
uint32_t preferred_lifetime; ///< preferred lifetime
uint8_t infinite; ///< flag to set to infinite lifetime
} ndp_prefix_info_t;
/**
* @brief Default router list to store information spread by
@ -84,7 +105,7 @@ typedef struct __attribute__((packed)) {
typedef struct __attribute__((packed)) {
ipv6_addr_t addr; ///< Address of router.
timex_t inval_time; ///< remaining time until this entry is
///< invalid.
///< invalid.
} ndp_default_router_list_t;
/**
@ -94,14 +115,16 @@ typedef struct __attribute__((packed)) {
* </a>.
*/
typedef struct __attribute__((packed)) {
int if_id; ///< Interface the IPv6 address is reachable
///< over
ndp_nce_type_t type; ///< Type of neighbor cache entry.
ndp_nce_state_t state; ///< State of neighbor cache entry.
uint8_t isrouter; ///< Flag to signify that this neighbor
///< is a router.
///< is a router.
ipv6_addr_t addr; ///< IPv6 address of the neighbor.
ieee_802154_long_t laddr; ///< EUI-64 of neighbor
ieee_802154_short_t saddr; ///< IEEE 802.15.4 16-bit short address
///< of neighbor.
uint8_t lladdr[8]; ///< Link-layer address of the neighbor
uint8_t lladdr_len; ///< Length of link-layer address of the
///< neighbor
timex_t ltime; ///< lifetime of entry.
} ndp_neighbor_cache_t;
@ -118,9 +141,76 @@ typedef struct __attribute__((packed)) {
} ndp_a6br_cache_t;
ndp_default_router_list_t *ndp_default_router_list_search(ipv6_addr_t *ipaddr);
uint8_t ndp_neighbor_cache_add(int if_id, const ipv6_addr_t *ipaddr,
const void *lladdr, uint8_t lladdr_len,
uint8_t isrouter, ndp_nce_state_t state,
ndp_nce_type_t type, uint16_t ltime);
ndp_neighbor_cache_t *ndp_neighbor_cache_search(ipv6_addr_t *ipaddr);
/*TODO: to implement*/
uint8_t ndp_prefix_list_search(ipv6_addr_t *addr);
ndp_neighbor_cache_t *ndp_get_ll_address(ipv6_addr_t *ipaddr);
int ndp_addr_is_on_link(ipv6_addr_t *dest_addr);
/**
* @brief Adds a prefix information to an interface. If it already exists,
* the values *valid_lifetime*, *preferred_lifetime*, *advertisable*,
* and flags will be updated accordingly and the prefix will be marked
* as *in_use*.
*
* @see <a href="http://tools.ietf.org/html/rfc4861#section-4.6.2">
* RFC 4861, section 4.6.2
* </a>.
*
* @param[in] if_id The interface's ID.
* @param[in] prefix The prefix.
* @param[in] prefix_len The length of the prefix in bit.
* @param[in] valid_lifetime The time in seconds this prefix is valid
* for on-link determination.
* NDP_OPT_PI_VLIFETIME_INFINITE for infinite
* lifetime.
* @param[in] preferred_lifetime The time in seconds addresses generated with
* this prefix remain preferred.
* NDP_OPT_PI_PLIFETIME_INFINITE for infinite
* lifetime.
* @param[in] advertisable Set this to a value != 0 to advertise this
* prefix information with the Prefix
* Information Option, set it to 0 if not.
* @param[in] flags Flags for the Prefix Information Option.
* Valid values are
* ICMPV6_NDP_OPT_PI_FLAG_ON_LINK and
* ICMPV6_NDP_OPT_PI_FLAG_AUTONOM
*/
int ndp_add_prefix_info(int if_id, const ipv6_addr_t *prefix,
uint8_t prefix_len, uint32_t valid_lifetime,
uint32_t preferred_lifetime, uint8_t advertisable,
uint8_t flags);
/**
* @brief Searches the information for the longest prefix up to *up_to* bits
* on an interface fitting to an address *addr*.
*
* @param[in] if_id The interface's ID.
* @param[in] addr The address to search the prefix for.
* @param[in] up_to The number of bits up to which point the search should
* go. Set to IPV6_ADDR_BIT_LEN for the whole address.
* Values greater then IPV6_ADDR_BIT_LEN are set to
* IPV6_ADDR_BIT_LEN.
*
* @return The found prefix information, NULL when none is found.
*/
ndp_prefix_info_t *ndp_prefix_info_search(int if_id, const ipv6_addr_t *addr,
uint8_t up_to);
/**
* @brief Searches the information for the prefix that matches *prefix* with
* length *prefix_len*.
*
* @param[in] if_id The interface's ID.
* @param[in] prefix The prefix to search for.
* @param[in] prefix_len The length of the prefix in bit.
*
* @return The found prefix information, NULL when none is found.
*/
ndp_prefix_info_t *ndp_prefix_info_match(int if_id, const ipv6_addr_t *prefix,
uint8_t prefix_len);
ndp_a6br_cache_t *ndp_a6br_cache_get_most_current(void);
ndp_a6br_cache_t *ndp_a6br_cache_get_oldest(void);

@ -49,25 +49,6 @@ typedef union __attribute__((packed)) {
uint32_t uint32[4]; ///< devided by 4 32-bit words.
} ipv6_addr_t;
/**
* @brief Data type to represent IPv6 address types.
*
* @see <a href="http://tools.ietf.org/html/rfc4291">
* RFC 4291
* </a>
*/
typedef enum __attribute__((packed)) {
IPV6_ADDR_TYPE_NONE, ///< address has no type/is invalid.
IPV6_ADDR_TYPE_UNICAST, ///< address is an unicast address.
IPV6_ADDR_TYPE_MULTICAST, ///< address is a multicast address.
IPV6_ADDR_TYPE_ANYCAST, ///< address is an anycast address.
IPV6_ADDR_TYPE_SOLICITED_NODE, ///< address is a solicitated node
///< multicast address.
IPV6_ADDR_TYPE_LOOPBACK, ///< address is a loopback address.
IPV6_ADDR_TYPE_LINK_LOCAL, ///< address is a link-local address.
IPV6_ADDR_TYPE_GLOBAL ///< address is a global address.
} ipv6_addr_type_t;
/**
* @brief Data type to represent an IPv6 packet header
*
@ -78,7 +59,7 @@ typedef enum __attribute__((packed)) {
typedef struct __attribute__((packed)) {
uint8_t version_trafficclass; ///< Version field + first 4 bit of Traffic Class.
uint8_t trafficclass_flowlabel; ///< last 4 bit of Traffic Class
///< and first 4 bit of Flow Label.
///< and first 4 bit of Flow Label.
uint16_t flowlabel; ///< last 16 bit of Flow Label.
uint16_t length; ///< payload length of this packet.
uint8_t nextheader; ///< type of next header in this packet.

@ -18,6 +18,13 @@
#include "ieee802154_frame.h"
#define ENABLE_DEBUG (0)
#if ENABLE_DEBUG
#define DEBUG_ENABLED
#endif
#include "debug.h"
#define IEEE_802154_FCS_POLY (0x8408) /* x^16 + x^12 + x^5 + 1 for LSB first */
uint8_t ieee802154_hdr_ptr;
uint8_t ieee802154_payload_ptr;
@ -28,16 +35,16 @@ uint8_t ieee802154_frame_init(ieee802154_frame_t *frame, uint8_t *buf)
/* Frame Control Field - 802.15.4 - 2006 - 7.2.1.1 */
uint8_t index = 0;
buf[index] = ((frame->fcf.frame_type) |
(frame->fcf.sec_enb << 3) |
(frame->fcf.frame_pend << 4) |
(frame->fcf.ack_req << 5) |
(frame->fcf.panid_comp << 6));
buf[index] = (((frame->fcf.frame_type) & 0x07) |
((frame->fcf.sec_enb << 3) & 0x08) |
((frame->fcf.frame_pend << 4) & 0x10) |
((frame->fcf.ack_req << 5) & 0x20) |
((frame->fcf.panid_comp << 6) & 0x40));
index++;
buf[index] = ((frame->fcf.dest_addr_m << 2) |
(frame->fcf.frame_ver << 4) |
(frame->fcf.src_addr_m << 6));
buf[index] = (((frame->fcf.dest_addr_m << 2) & 0x0c) |
((frame->fcf.frame_ver << 4) & 0x30) |
((frame->fcf.src_addr_m << 6) & 0xc0));
index++;
@ -55,49 +62,62 @@ uint8_t ieee802154_frame_init(ieee802154_frame_t *frame, uint8_t *buf)
/* Destination Address - 802.15.4 - 2006 - 7.2.1.4 */
if (frame->fcf.dest_addr_m == 0x02) {
buf[index] = frame->dest_addr[0];
buf[index + 1] = frame->dest_addr[1];
buf[index] = frame->dest_addr[1];
buf[index + 1] = frame->dest_addr[0];
index += 2;
}
else if (frame->fcf.dest_addr_m == 0x03) {
buf[index] = frame->dest_addr[0];
buf[index + 1] = frame->dest_addr[1];
buf[index + 2] = frame->dest_addr[2];
buf[index + 3] = frame->dest_addr[3];
buf[index + 4] = frame->dest_addr[4];
buf[index + 5] = frame->dest_addr[5];
buf[index + 6] = frame->dest_addr[6];
buf[index + 7] = frame->dest_addr[7];
buf[index] = frame->dest_addr[7];
buf[index + 1] = frame->dest_addr[6];
buf[index + 2] = frame->dest_addr[5];
buf[index + 3] = frame->dest_addr[4];