mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
Use net_if in 6LoWPAN MAC layer
This commit is contained in:
parent
470d8745e9
commit
108989b65d
@ -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[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] 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 (identical to
|
||||
* give a destination address of 0).
|
||||
* @param[in] mcast send frame as multicast frame (*addr* and *if_id*
|
||||
* will be ignored).
|
||||
*
|
||||
* @return Length of transmitted data in byte
|
||||
*/
|
||||
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_send_ieee802154_frame(int if_id, const void *dest,
|
||||
uint8_t dest_len, const void *payload, uint8_t length, uint8_t mcast);
|
||||
|
||||
/**
|
||||
* @brief Initialise 6LoWPAN MAC interface
|
||||
* @brief Initialise 6LoWPAN MAC layer and register it to interface layer
|
||||
*
|
||||
* @param[in] type Type of transceiver.
|
||||
* @return PID of the MAC receiver thread.
|
||||
*/
|
||||
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 */
|
||||
|
@ -22,15 +22,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "vtimer.h"
|
||||
#include "mutex.h"
|
||||
#include "msg.h"
|
||||
#include "net_if.h"
|
||||
#include "sixlowpan/mac.h"
|
||||
|
||||
#include "ip.h"
|
||||
|
@ -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,
|
||||
|
@ -24,13 +24,10 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user