1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

Merge pull request #460 from authmillenon/define_ll_ifs

Link layer interfaces
This commit is contained in:
Martin Lenders 2014-03-01 15:44:58 +01:00
commit eaa86600b6
18 changed files with 2703 additions and 116 deletions

View File

@ -102,3 +102,15 @@ ifneq (,$(filter vtimer,$(USEMODULE)))
USEMODULE += timex
endif
endif
ifneq (,$(filter net_if,$(USEMODULE)))
ifeq (,$(filter transceiver,$(USEMODULE)))
USEMODULE += transceiver
endif
endif
ifneq (,$(filter shell_commands,$(USEMODULE)))
ifneq (,$(filter net_if,$(USEMODULE)))
USEMODULE += net_help
endif
endif

View File

@ -42,6 +42,9 @@ endif
ifneq (,$(filter vtimer,$(USEMODULE)))
DIRS += vtimer
endif
ifneq (,$(filter net_if,$(USEMODULE)))
DIRS += net/link_layer/net_if
endif
ifneq (,$(filter destiny,$(USEMODULE)))
DIRS += net/transport_layer/destiny
endif

View File

@ -1,3 +1,7 @@
MODULE = auto_init
ifneq (,$(filter net_if,$(USEMODULE)))
INCLUDES += -I$(RIOTBASE)/sys/net/include/
endif
include $(RIOTBASE)/Makefile.base

View File

@ -55,6 +55,11 @@
#include "destiny.h"
#endif
#ifdef MODULE_NET_IF
#include "net_if.h"
#include "transceiver.h"
#endif
#define ENABLE_DEBUG (0)
#include "debug.h"
@ -97,6 +102,40 @@ void auto_init(void)
DEBUG("Auto init mci module.\n");
MCI_initialize();
#endif
#ifdef MODULE_NET_IF
DEBUG("Auto init net_if module.\n");
transceiver_type_t transceivers = 0;
#ifdef MODULE_AT86RF231
transceivers |= TRANSCEIVER_AT86RF231;
#endif
#ifdef MODULE_CC1020
transceivers |= TRANSCEIVER_CC1020;
#endif
#if MODULE_CC110X || MODULE_CC110X_NG
transceivers |= TRANSCEIVER_CC1100;
#endif
#ifdef MODULE_CC2420
transceivers |= TRANSCEIVER_CC2420;
#endif
#ifdef MODULE_MC1322X
transceivers |= TRANSCEIVER_MC1322X;
#endif
#ifdef MODULE_NATIVENET
transceivers |= TRANSCEIVER_NATIVE;
#endif
net_if_init();
if (transceivers != 0) {
transceiver_init(transceivers);
transceiver_start();
int iface = net_if_init_interface(0, transceivers);
if (iface >= 0) {
DEBUG("Interface %d initialized\n", iface);
}
}
#endif
#ifdef MODULE_PROFILING
extern void profiling_init(void);
profiling_init();

View File

@ -107,6 +107,11 @@
*/
typedef uint16_t transceiver_type_t;
/**
* @brief Data type to represent the transceiver's EUI-64.
*/
typedef uint64_t transceiver_eui64_t;
/**
* @brief Message types for transceiver interface
*/
@ -129,6 +134,8 @@ enum transceiver_msg_type_t {
SET_CHANNEL, ///< Set a new channel
GET_ADDRESS, ///< Get the radio address
SET_ADDRESS, ///< Set the radio address
GET_LONG_ADDR, ///< Get the long radio address, if existing
SET_LONG_ADDR, ///< Set the long radio address, if supported by hardware
SET_MONITOR, ///< Set transceiver to monitor mode (disable address checking)
GET_PAN, ///< Get current pan
SET_PAN, ///< Set a new pan

View File

@ -38,6 +38,10 @@
#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}}
#define IEEE_802154_PAN_ID 0x1234
typedef struct __attribute__((packed)) {
@ -62,6 +66,20 @@ typedef struct __attribute__((packed)) {
uint8_t payload_len;
} ieee802154_frame_t;
/**
* Structure to represent an IEEE 802.15.4 packet for the transceiver.
*/
typedef struct __attribute__(( packed )) {
/* @{ */
uint8_t processing; /** < internal processing state */
uint8_t length; /** < the length of the frame of the frame including fcs*/
ieee802154_frame_t frame; /** < the ieee802154 frame */
int8_t rssi; /** < the rssi value */
uint8_t crc; /** < 1 if crc was successfull, 0 otherwise */
uint8_t lqi; /** < the link quality indicator */
/* @} */
} ieee802154_packet_t;
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);

View File

@ -21,8 +21,17 @@
(((uint32_t) (a) & 0x00ff0000) >> 8) | \
(((uint32_t) (a) & 0x0000ff00) << 8) | \
(((uint32_t) (a) & 0x000000ff) << 24))
#define HTONLL(a) ((((uint64_t) (a) & 0xff00000000000000) >> 56) | \
(((uint64_t) (a) & 0x00ff000000000000) >> 40) | \
(((uint64_t) (a) & 0x0000ff0000000000) >> 24) | \
(((uint64_t) (a) & 0x000000ff00000000) >> 8) | \
(((uint64_t) (a) & 0x00000000ff000000) << 8) | \
(((uint64_t) (a) & 0x0000000000ff0000) << 24) | \
(((uint64_t) (a) & 0x000000000000ff00) << 40) | \
(((uint64_t) (a) & 0x00000000000000ff) << 56))
#define NTOHS HTONS
#define NTOHL HTONL
#define NTOHLL HTONLL
#define CMP_IPV6_ADDR(a, b) (memcmp(a, b, 16))

504
sys/net/include/net_if.h Normal file
View File

@ -0,0 +1,504 @@
/*
* Copyright (C) 2013 Freie Universität Berlin.
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @defgroup net_if Network interfaces
* @brief Abstraction layer between transceiver module and L3 protocol
* implementations.
* @ingroup net
*
* @{
*
* @file net_if.h
* @brief Types and functions for network interfaces
* @author Freie Universität Berlin
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef _NET_IF_H
#define _NET_IF_H
#include <stdint.h>
#include <stdlib.h>
#include "mutex.h"
#include "transceiver.h"
/**
* @brief type to specify types of upper layer addresses
*/
typedef uint8_t net_if_l3p_t;
/**
* @brief Interface protocols (for net_if_t.protocols): Use raw packets with
* static addresses in upper layer.
*/
#define NET_IF_L3P_RAW (0x00)
/**
* @brief Interface protocols (for net_if_t.protocols): Use unicast IPv6
* address in upper layer, addr_len must be 128.
*/
#define NET_IF_L3P_IPV6_UNICAST (0x01)
/**
* @brief Interface protocols (for net_if_t.protocols): Use multicast IPv6
* address in upper layer, addr_len must be 128.
*/
#define NET_IF_L3P_IPV6_MULTICAST (0x02)
/**
* @brief Interface protocols (for net_if_t.protocols): Use anycast IPv6
* address in upper layer, addr_len must be 128.
*/
#define NET_IF_L3P_IPV6_ANYCAST (0x04)
/**
* @brief Interface protocols (for net_if_t.protocols): Use IPv6 prefix in
* upper layer, addr_len <= 128 becomes prefix length.
*/
#define NET_IF_L3P_IPV6_PREFIX (0x08)
/**
* @brief Interface protocols (for net_if_t.protocols): Convenience macro
* combining NET_IF_L3P_IPV6_UNICAST, NET_IF_L3P_IPV6_ANYCAST, and
* NET_IF_L3P_IPV6_MULTICAST for comparisons
*/
#define NET_IF_L3P_IPV6_ADDR (NET_IF_L3P_IPV6_UNICAST | NET_IF_L3P_IPV6_ANYCAST \
| NET_IF_L3P_IPV6_MULTICAST)
/**
* @brief Interface protocols (for net_if_t.protocols): Convenience macro
* combining NET_IF_L3P_IPV6_UNICAST, NET_IF_L3P_IPV6_ANYCAST,
* NET_IF_L3P_IPV6_MULTICAST, and NET_IF_L3P_IPV6_PREFIX for
* comparisons
*/
#define NET_IF_L3P_IPV6 (NET_IF_L3P_IPV6_UNICAST | NET_IF_L3P_IPV6_ANYCAST \
| NET_IF_L3P_IPV6_MULTICAST | NET_IF_L3P_IPV6_PREFIX)
/**
* @brief Interface protocols: Return value of net_if_get_l3p_types() on
* error.
*/
#define NET_IF_L3P_FAILURE (0x80)
#ifndef NET_IF_MAX
/**
* @brief Maximum number of interfaces. Redefinable via compiler flag.
*/
#define NET_IF_MAX (1)
#endif
/**
* @brief Data type to represent an EUI-64.
*/
typedef union __attribute__((packed)) {
uint8_t uint8[8]; ///< split into 8 8-bit words.
uint16_t uint16[4]; ///< split into 4 16-bit words.
uint32_t uint32[2]; ///< split into 2 32-bit words.
uint64_t uint64; ///< as one 64-bit word.
} net_if_eui64_t;
/**
* @brief list type for upper layer address of an interface.
*
* @details The interpretation of the address data is left to the upper layer
* implementations.
*/
typedef struct __attribute__((packed)) net_if_addr_t {
/**
* @brief The next address on the interface. Initialise with NULL
*/
struct net_if_addr_t *addr_next;
/**
* @brief The next address on the interface. Initialise with NULL
*/
struct net_if_addr_t *addr_prev;
/**
* @brief Flags to define upper layer protocols this address applies to
*/
net_if_l3p_t addr_protocol;
void *addr_data; ///< The actual upper layer address
uint8_t addr_len; ///< Length of the upper layer address in bit.
} net_if_addr_t;
typedef uint8_t net_if_trans_addr_m_t;
/**
* @brief Interface type.
*/
typedef struct __attribute__((packed)) {
uint8_t initialized; ///< Detemines if interface is initialized
uint8_t protocols; ///< Interface L3 protocols
transceiver_type_t transceivers; ///< Transceivers to use with this interface
net_if_trans_addr_m_t trans_src_addr_m; ///< Transceiver address mode
mutex_t address_buffer_mutex; ///< Mutex for address buffer operations
net_if_addr_t *addresses; ///< Adresses
uint8_t l3p_data[9]; ///< generic L3 data
} net_if_t;
#define NET_IF_TRANS_ADDR_M_SHORT 2 ///< Transceiver address mode for short addresses
#define NET_IF_TRANS_ADDR_M_LONG 3 ///< Transceiver address mode for long addresses
/**
* All registered interfaces.
*/
extern net_if_t interfaces[NET_IF_MAX];
/**
* @brief Initializes the module.
*/
void net_if_init(void);
/**
* @brief Inititializes a new interface
*
* @pre *transceivers* may not be zero.
*
* @param[in] protocols The upper layer protocols to use on this interface.
* @param[in] transceivers The transceivers this interface uses.
*
* @return The new interface's ID on success, -1 on failure.
*/
int net_if_init_interface(net_if_l3p_t protocols,
transceiver_type_t transceivers);
/**
* @brief Get interface.
*
* @param[in] if_id The interface's ID
*
* @return The interface identified by *if_id* or NULL on failure.
*/
static inline net_if_t *net_if_get_interface(int if_id)
{
if (if_id < NET_IF_MAX && interfaces[if_id].initialized) {
return &interfaces[if_id];
}
else {
return NULL;
}
}
/**
* @brief Iterates over all intitialized interfaces
*
* @param[in] start Return value of last iteration step. -1 to start iteration.
*
* @return ID of an initialized interface. -1 if end of interface list is
* reached.
*/
int net_if_iter_interfaces(int start);
/**
* @brief Sets the source address mode for the interface
*
* @param[in] if_id Interface to set source address mode for.
* @param[in] mode The mode to set to.
*
* @return 1 on success, 0 on error
*/
static inline int net_if_set_src_address_mode(int if_id,
net_if_trans_addr_m_t mode)
{
if (!interfaces[if_id].initialized) {
return 0;
}
interfaces[if_id].trans_src_addr_m = mode;
return 1;
}
/**
* @brief Gets the source address mode for the interface
*
* @param[in] if_id Interface to get source address mode from.
*
* @return The interfaces address mode, 0 on error
*/
static inline net_if_trans_addr_m_t net_if_get_src_address_mode(int if_id)
{
if (!interfaces[if_id].initialized) {
return 0;
}
return interfaces[if_id].trans_src_addr_m;
}
/**
* @brief Adds new address to interface
*
* @pre *addr* is not NULL, *addr->addr_data* is not NULL
*
* @param[in] if_id The interface's ID
* @param[in] addr The address to add
*
* @return 1 on success, 0 on failure.
*/
int net_if_add_address(int if_id, net_if_addr_t *addr);
/**
* @brief Removes first occurance of address from interface
*
* @pre *addr* is not NULL, *addr->addr_data* is not NULL
*
* @param[in] if_id The interface's ID
* @param[in] addr The address to remove
*
* @return 1 on success (and if given address is not registered to this
* interface), 0 on failure
*/
int net_if_del_address(int if_id, net_if_addr_t *addr);
/**
* @brief Iterates over registered addresses of an interface.
*
* @param[in] if_id The interface's ID
* @param[in,out] addr The previous address as in or the next address as out.
* If *addr* points to NULL it will be set to the
* first address assigned to *if_id*, if *addr* points to
* NULL as out, the last address assigned to *if_id* was
* given as *addr* previously (and the address list was
* completely iterated).
*
* @return The pointer *addr* refers to after call of this function or NULL on
* error
*/
net_if_addr_t *net_if_iter_addresses(int if_id, net_if_addr_t **addr);
/**
* @brief Get the upper layer protocol types assigned to the interface *if_id*
*
* @param[in] if_id The interface's ID
* @return The upper layer protocol types assigned to the interface *if_id* on
* success, NET_IF_L3P_FAILURE on failure.
*/
net_if_l3p_t net_if_get_l3p_types(int if_id);
/**
* @brief Add an upper layer protocol types to the interface *if_id*
*
* @param[in] if_id The interface's ID
* @param[in] protocols The upper layer protocol types to assign to the
* interface *if_id*
* @return 1 on success, 0 on failure.
*/
int net_if_add_l3p_types(int if_id, net_if_l3p_t protocols);
/**
* @brief Remove upper layer protocol types and all addresses of this scope
* from the interface *if_id*
*
* @param[in] if_id The interface's ID
* @param[in] protocols The upper layer protocol types to be removed from the
* interface *if_id*
* @return 1 on success, 0 on failure.
*/
int net_if_del_l3p_types(int if_id, net_if_l3p_t protocols);
/**
* @brief Sends a packet to a short address over the interface.
*
* @pre Transceivers has to be initialized and transceiver thread has
* to be started.
*
* @param[in] if_id The interface's ID.
* @param[in] target The target's short transceiver address.
* @param[in] packet_data The packet to send
* @param[in] packet_len The length of the packet's data in byte, negative
* number on error.
*
* @return The number of bytes send on success, negative value on failure
*/
int net_if_send_packet(int if_id, uint16_t target, const void *packet_data,
size_t packet_len);
/**
* @brief Sends a packet to a long address over the interface. If transceiver
* only supports smaller addresses the least significant bit of the
* address will be taken.
*
* @pre Transceivers has to be initialized and transceiver thread has
* to be started.
*
* @param[in] if_id The interface's ID.
* @param[in] target The target's long transceiver address.
* @param[in] packet_data The packet to send
* @param[in] packet_len The length of the packet's data in byte, negative
* number on error.
*
* @return The number of bytes send on success, negative value on failure
*/
int net_if_send_packet_long(int if_id, net_if_eui64_t *target,
const void *packet_data, size_t packet_len);
/**
* @brief Sends a packet over all initialized interfaces.
*
* @pre Transceivers has to be initialized and transceiver thread has
* to be started.
*
* @param[in] preferred_dest_mode The preferred transceiver address mode for
* the destination broadcast address. Choose
* NET_IF_TRANS_ADDR_M_SHORT if you are not
* sure
* @param[in] packet_data The packet to send
* @param[in] packet_len The length of the packet's data in byte,
* negative number on error.
*
* @return The number of bytes send on success, negative value on failure
*/
int net_if_send_packet_broadcast(net_if_trans_addr_m_t preferred_dest_mode,
const void *payload, size_t payload_len);
/**
* @brief register a thread for events an interface's transceiver
* @details This function just wraps transceiver_register().
*
* @pre Transceivers has to be initialized and transceiver thread has
* to be started.
*
* @param[in] if_id The transceiver's interface to register for
* @param[in] pid The pid of the thread to register
*
* @return 1 on success, 0 otherwise
*/
int net_if_register(int if_id, int pid);
/**
* Returns the EUI-64 of the transeivers attached to this interface. This can
* be get by the actual EUI-64 if the transceiver has one or a generated one
* based of the hardware address
*
* @pre Transceivers of this interface has to be initialized and
* transceiver thread has to be started.
*
* @see <a href="http://tools.ietf.org/html/rfc4944#section-6">
* RFC 4944, section 5
* </a>
* @see <a href="http://tools.ietf.org/search/rfc6282#section-3.2.2">
* RFC 6282, section 3.2.2
* </a>
*
* @param[out] eui64 The EUI-64 to fill
* @param[in] if_id The interface's ID
* @param[in] force_generation Force generation from a short address if the
* hardware supports it, even if the hardware
* supplies an EUI-64
*
* @return 1 on success, 0 on failure
*/
int net_if_get_eui64(net_if_eui64_t *eui64, int if_id, int force_generation);
/**
* @brief Parses a string to an EUI-64.
* @detail The parsing will be back to front, every non-hexadecimal character
* and every hexadecimal character beyond the count of 8 will be
* ignored
*
* @param[out] eui64 The generated binary EUI-64.
* @param[in] eui64_str A hexadecimal number in string representation.
*/
void net_if_hex_to_eui64(net_if_eui64_t *eui64, const char *eui64_str);
/**
* Returns the address of the transceiver associated with the given interface.
*
* @pre Transceivers of this interface has to be initialized and
* transceiver thread has to be started.
*
* @param[in] if_id The interface's ID
*
* @return The transceiver's hardware address on success, 0 on failure
*/
uint16_t net_if_get_hardware_address(int if_id);
/**
* Returns the EUI-64 of the transeivers attached to this interface. This can
* be get by the actual EUI-64 if the transceiver has one or a generated one
* based of the hardware address
*
* @pre Transceivers of this interface has to be initialized and
* transceiver thread has to be started.
*
* @param[in] if_id The interface's ID
* @param[in] eui64 The new EUI-64
*
* @return 1 on success, 0 on failure
*/
int net_if_set_eui64(int if_id, net_if_eui64_t *eui64);
/**
* Sets the address of the transceiver associated with the given interface.
*
* @pre Transceivers of this interface has to be initialized and
* transceiver thread has to be started.
*
* @param[in] if_id The interface's ID
* @param[in] addr The new hardware address
*
* @return the new hardware address on success, 0 on failure.
*/
uint16_t net_if_set_hardware_address(int if_id, uint16_t addr);
/**
* Returns the channel of the transceiver associated with the given interface.
*
* @pre Transceivers of this interface has to be initialized and
* transceiver thread has to be started.
*
* @param[in] if_id The interface's ID
*
* @return The transceiver's frequency channel on success, -1 on failure.
*/
int32_t net_if_get_channel(int if_id);
/**
* Sets the channel of the transceiver associated with the given interface.
*
* @pre Transceivers of this interface has to be initialized and
* transceiver thread has to be started.
*
* @param[in] if_id The interface's ID
* @param[in] channel The new frequency channel
*
* @return the new channel on success, -1 on failure.
*/
int32_t net_if_set_channel(int if_id, uint16_t channel);
/**
* Returns the PAN ID of the transceiver associated with the given interface.
*
* @pre Transceivers of this interface has to be initialized and
* transceiver thread has to be started.
*
* @param[in] if_id The interface's ID
*
* @return The transceiver's PAN ID on success, -1 on failure
*/
int32_t net_if_get_pan_id(int if_id);
/**
* Sets the PAN ID of the transceiver associated with the given interface.
*
* @pre Transceivers of this interface has to be initialized and
* transceiver thread has to be started.
*
* @param[in] if_id The interface's ID
* @param[in] pan_id The new frequency channel
*
* @return the PAN ID on success, -1 on failure.
*/
int32_t net_if_set_pan_id(int if_id, uint16_t pan_id);
/**
* @}
*/
#endif /* _NET_IF_H */

View File

@ -0,0 +1,5 @@
MODULE:=$(shell basename $(CURDIR))
INCLUDES += -I$(RIOTBASE)/drivers/include \
-I$(RIOTBASE)/drivers/cc110x_ng/include \
-I$(RIOTBASE)/sys/net/include
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,552 @@
/*
* Copyright (C) 2013 Freie Universität Berlin.
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup net_if
* @{
* @file net_if.c
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
*/
#include <string.h>
#include "clist.h"
#include "ieee802154_frame.h"
#include "msg.h"
#include "mutex.h"
#include "net_help.h"
#include "transceiver.h"
#include "net_if.h"
#define ENABLE_DEBUG (0)
#if ENABLE_DEBUG
#define DEBUG_ENABLED
#endif
#include "debug.h"
net_if_t interfaces[NET_IF_MAX];
#ifdef DEBUG_ENABLED
void print_addr_hex(net_if_addr_t *addr)
{
int i;
DEBUG("0x");
for (i = 0; i < addr->addr_len; i++) {
DEBUG("%02x", ((char *)addr->addr_data)[i]);
}
DEBUG("\n");
}
#endif
uint8_t net_if_hex_to_dec(char c)
{
if (c >= '0' && c <= '9') {
return (uint8_t)(c - '0');
}
else if (c >= 'A' && c <= 'F') {
return (uint8_t)(c - 55);
}
else if (c >= 'a' && c <= 'f') {
return (uint8_t)(c - 87);
}
else {
return 0xff;
}
}
void net_if_hex_to_eui64(net_if_eui64_t *eui64, const char *eui64_str)
{
int i;
const char *eui64_rev = &eui64_str[strlen(eui64_str) - 1];
eui64->uint64 = 0;
for (i = 7; i >= 0 || eui64_rev >= eui64_str; i--) {
uint8_t digit;
while ((digit = net_if_hex_to_dec(*eui64_rev)) == 0xFF) {
if (--eui64_rev < eui64_str) {
return;
}
}
eui64->uint8[i] = digit;
eui64_rev--;
while ((digit = net_if_hex_to_dec(*eui64_rev)) == 0xFF) {
if (--eui64_rev < eui64_str) {
return;
}
}
eui64->uint8[i] |= digit << 4;
eui64_rev--;
}
}
void net_if_init(void)
{
memset(&interfaces, 0, sizeof(net_if_t) * NET_IF_MAX);
}
int net_if_init_interface(uint8_t protocols, transceiver_type_t transceivers)
{
int i;
if (transceivers == 0) {
DEBUG("Interface initialization: Precondition not met.\n");
return -1;
}
for (i = 0; i < NET_IF_MAX; i++) {
if (!interfaces[i].initialized) {
interfaces[i].initialized = 1;
interfaces[i].protocols = protocols;
mutex_init(&interfaces[i].address_buffer_mutex);
interfaces[i].transceivers = transceivers;
DEBUG("Initialized interface %d for protocols %d on transceivers 0x%x\n",
i, protocols, transceivers);
return i;
}
}
DEBUG("Interface buffer full.\n");
return -1;
}
int net_if_iter_interfaces(int start)
{
if (start == NET_IF_MAX - 1) {
return -1;
}
start++;
while (start < NET_IF_MAX && !interfaces[start].initialized) {
start++;
}
return start;
}
int net_if_add_address(int if_id, net_if_addr_t *addr)
{
if (!addr || !addr->addr_data) {
DEBUG("Address addition: Precondition not met.\n");
return 0;
}
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Address addition: No interface initialized with ID %d.\n", if_id);
return 0;
}
mutex_lock(&interfaces[if_id].address_buffer_mutex);
interfaces[if_id].protocols |= addr->addr_protocol;
clist_add((clist_node_t **)&interfaces[if_id].addresses,
(clist_node_t *)addr);
mutex_unlock(&interfaces[if_id].address_buffer_mutex);
return 1;
}
int net_if_del_address(int if_id, net_if_addr_t *addr)
{
if (!addr || !addr->addr_data) {
DEBUG("Address deletion: Precondition not met.\n");
return 0;
}
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Address deletion: No interface initialized with ID %d.\n", if_id);
return 0;
}
mutex_lock(&interfaces[if_id].address_buffer_mutex);
clist_remove((clist_node_t **)&interfaces[if_id].addresses,
(clist_node_t *)addr);
mutex_unlock(&interfaces[if_id].address_buffer_mutex);
return 1;
}
net_if_addr_t *net_if_iter_addresses(int if_id, net_if_addr_t **addr)
{
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Address iteration: No interface initialized with ID %d.\n", if_id);
return NULL;
}
if (*addr == NULL) {
*addr = interfaces[if_id].addresses;
return *addr;
}
clist_advance((clist_node_t **)addr);
if (*addr == interfaces[if_id].addresses) {
*addr = NULL;
}
return *addr;
}
net_if_l3p_t net_if_get_l3p_types(int if_id)
{
net_if_l3p_t protocols;
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Get L3 protocols: No interface initialized with ID %d.\n", if_id);
return NET_IF_L3P_FAILURE;
}
mutex_lock(&interfaces[if_id].address_buffer_mutex);
protocols = interfaces[if_id].protocols;
mutex_unlock(&interfaces[if_id].address_buffer_mutex);
return protocols;
}
int net_if_add_l3p_types(int if_id, net_if_l3p_t protocols)
{
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Add L3 protocols: No interface initialized with ID %d.\n", if_id);
return 0;
}
interfaces[if_id].protocols |= protocols;
return 1;
}
int net_if_del_l3p_types(int if_id, net_if_l3p_t protocols)
{
net_if_addr_t *addr_ptr = NULL;
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Remove L3 protocols: No interface initialized with ID %d.\n", if_id);
return 0;
}
while (net_if_iter_addresses(if_id, &addr_ptr)) {
if (addr_ptr->addr_protocol & protocols) {
net_if_del_address(if_id, addr_ptr);
addr_ptr = NULL;
}
}
interfaces[if_id].protocols &= ~protocols;
return 1;
}
uint32_t net_if_transceiver_get_set_handler(int if_id, uint16_t op_type,
void *data)
{
DEBUG("net_if_transceiver_get_set_handler: if_id = %d, op_type = %d, data = %p\n",
if_id, op_type, data);
msg_t msg;
transceiver_command_t tcmd;
tcmd.transceivers = interfaces[if_id].transceivers;
tcmd.data = (char *)data;
msg.content.ptr = (char *)&tcmd;
msg.type = op_type;
msg_send_receive(&msg, &msg, transceiver_pid);
return msg.content.value;
}
int net_if_send_packet_broadcast(net_if_trans_addr_m_t preferred_dest_mode,
const void *payload, size_t payload_len)
{
int if_id = -1;
int res = 0, res_prev = 0;
while ((if_id = net_if_iter_interfaces(if_id)) >= 0) {
if (interfaces[if_id].transceivers & (TRANSCEIVER_CC1100 | TRANSCEIVER_NATIVE)) {
res = net_if_send_packet(if_id, 0,
payload, payload_len);
}
else if (preferred_dest_mode == NET_IF_TRANS_ADDR_M_SHORT) {
res = net_if_send_packet(if_id, IEEE_802154_SHORT_MCAST_ADDR,
payload, payload_len);
}
else {
net_if_eui64_t mcast_addr = IEEE_802154_LONG_MCAST_ADDR;
res = net_if_send_packet_long(if_id, &mcast_addr, payload,
payload_len);
}
if (res_prev != 0) {
if (res != res_prev) {
return -1;
}
}
else {
if (res == 0) {
break;
}
}
res_prev = res;
}
return res;
}
int net_if_send_packet(int if_id, uint16_t target, const void *payload,
size_t payload_len)
{
DEBUG("net_if_send_packet: if_id = %d, target = %d, payload = %p, "
"payload_len = %d\n", if_id, target, payload, payload_len);
uint32_t response;
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Send packet: No interface initialized with ID %d.\n", if_id);
return -1;
}
if (interfaces[if_id].transceivers & (TRANSCEIVER_CC2420 | TRANSCEIVER_AT86RF231 | TRANSCEIVER_MC1322X)) {
ieee802154_packet_t p;
memset(&p, 0, sizeof(ieee802154_packet_t));
p.frame.payload = (uint8_t *)payload;
p.frame.payload_len = (uint8_t)payload_len;
p.frame.fcf.src_addr_m = (uint8_t)interfaces[if_id].trans_src_addr_m;
p.frame.fcf.dest_addr_m = IEEE_802154_SHORT_ADDR_M;
p.frame.fcf.ack_req = 0;
p.frame.fcf.sec_enb = 0;
p.frame.fcf.frame_type = 1;
p.frame.fcf.frame_pend = 0;
p.frame.dest_pan_id = net_if_get_pan_id(if_id);
memcpy(p.frame.dest_addr, &target, 2);
response = net_if_transceiver_get_set_handler(if_id, SND_PKT, (void *)&p);
}
else {
radio_packet_t p;
memset(&p, 0, sizeof(radio_packet_t));
p.data = (uint8_t *) payload;
p.length = payload_len;
p.dst = target;
response = net_if_transceiver_get_set_handler(if_id, SND_PKT, (void *)&p);
}
return (response > payload_len) ? (int)payload_len : (int)response;
}
int net_if_send_packet_long(int if_id, net_if_eui64_t *target,
const void *payload, size_t payload_len)
{
DEBUG("net_if_send_packet: if_id = %d, target = %016" PRIx64 ", "
"payload = %p, payload_len = %d\n", if_id, NTOHLL(target->uint64), payload,
payload_len);
uint32_t response;
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Send packet: No interface initialized with ID %d.\n", if_id);
return -1;
}
if (interfaces[if_id].transceivers & (TRANSCEIVER_CC2420 |
TRANSCEIVER_AT86RF231 |
TRANSCEIVER_MC1322X)) {
ieee802154_packet_t p;
memset(&p, 0, sizeof(ieee802154_packet_t));
p.frame.payload = (uint8_t *)payload;
p.frame.payload_len = (uint8_t)payload_len;
p.frame.fcf.src_addr_m = (uint8_t)interfaces[if_id].trans_src_addr_m;
p.frame.fcf.dest_addr_m = IEEE_802154_LONG_ADDR_M;
p.frame.fcf.ack_req = 0;
p.frame.fcf.sec_enb = 0;
p.frame.fcf.frame_type = 1;
p.frame.fcf.frame_pend = 0;
p.frame.dest_pan_id = net_if_get_pan_id(if_id);
memcpy(p.frame.dest_addr, target, 8);
response = net_if_transceiver_get_set_handler(if_id, SND_PKT, (void *)&p);
}
else {
radio_packet_t p;
memset(&p, 0, sizeof(radio_packet_t));
p.data = (uint8_t *) payload;
p.length = payload_len;
p.dst = NTOHS(target->uint16[3]);
response = net_if_transceiver_get_set_handler(if_id, SND_PKT, (void *)&p);
}
return (response > payload_len) ? (int)payload_len : (int)response;
}
int net_if_register(int if_id, int pid)
{
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Register thread: No interface initialized with ID %d.\n", if_id);
return 0;
}
return (int)transceiver_register(interfaces[if_id].transceivers, pid);
}
int net_if_get_eui64(net_if_eui64_t *eui64, int if_id, int force_generation)
{
uint64_t tmp;
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Get EUI-64: No interface initialized with ID %d.\n", if_id);
return 0;
}
if (eui64 == NULL) {
DEBUG("Get EUI-64: parameter eui64 is a NULL pointer.\n");
return 0;
}
net_if_transceiver_get_set_handler(if_id, GET_LONG_ADDR, &tmp);
eui64->uint64 = HTONLL(tmp);
if (eui64->uint64 == 0 || force_generation) {
uint16_t hwaddr = net_if_get_hardware_address(if_id);
if (hwaddr == 0) {
return 0;
}
/* RFC 6282 Section 3.2.2 / RFC 2464 Section 4 */
eui64->uint32[0] = HTONL(0x000000ff);
eui64->uint16[2] = HTONS(0xfe00);
if (sizeof(hwaddr) == 2) {
eui64->uint16[3] = HTONS(hwaddr);
}
else if (sizeof(hwaddr) == 1) {
eui64->uint8[6] = 0;
eui64->uint8[7] = (uint8_t)hwaddr;
}
else {
DEBUG("Error on EUI-64 generation: do not know what to do with "
"hardware address of length %d\n", sizeof(hwaddr));
return 0;
}
}
return 1;
}
int net_if_set_eui64(int if_id, net_if_eui64_t *eui64)
{
if (eui64 == NULL) {
return 0;
}
uint64_t tmp = NTOHLL(eui64->uint64);
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Set EUI-64: No interface initialized with ID %d.\n", if_id);
return 0;
}
net_if_transceiver_get_set_handler(if_id, SET_LONG_ADDR, (void *) &tmp);
return eui64->uint64 != 0;
}
uint16_t net_if_get_hardware_address(int if_id)
{
uint16_t addr;
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Get hardware address: No interface initialized with ID %d.\n", if_id);
return 0;
}
net_if_transceiver_get_set_handler(if_id, GET_ADDRESS, &addr);
return addr;
}
uint16_t net_if_set_hardware_address(int if_id, uint16_t addr)
{
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Set hardware address: No interface initialized with ID %d.\n", if_id);
return 0;
}
net_if_transceiver_get_set_handler(if_id, SET_ADDRESS, &addr);
return addr;
}
int32_t net_if_get_channel(int if_id)
{
int32_t channel;
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Get channel: No interface initialized with ID %d.\n", if_id);
return -1;
}
net_if_transceiver_get_set_handler(if_id, GET_CHANNEL, &channel);
return channel;
}
int32_t net_if_set_channel(int if_id, uint16_t channel)
{
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Set channel: No interface initialized with ID %d.\n", if_id);
return -1;
}
net_if_transceiver_get_set_handler(if_id, SET_CHANNEL, &channel);
return channel;
}
int32_t net_if_get_pan_id(int if_id)
{
int32_t pan_id;
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Get PAN ID: No interface initialized with ID %d.\n", if_id);
return -1;
}
net_if_transceiver_get_set_handler(if_id, GET_PAN, &pan_id);
if (pan_id < 0) {
return 0;
}
else {
return pan_id;
}
}
int32_t net_if_set_pan_id(int if_id, uint16_t pan_id)
{
if (if_id < 0 || if_id > NET_IF_MAX || !interfaces[if_id].initialized) {
DEBUG("Set PAN ID: No interface initialized with ID %d.\n", if_id);
return -1;
}
net_if_transceiver_get_set_handler(if_id, SET_PAN, &pan_id);
return pan_id;
}
/**
* @}
*/

View File

@ -11,6 +11,10 @@ ifneq (,$(filter cc110x,$(USEMODULE)))
SRC += sc_cc1100.c
endif
endif
ifneq (,$(filter net_if,$(USEMODULE)))
INCLUDES += -I$(RIOTBASE)/sys/net/include
SRC += sc_net_if.c
endif
ifneq (,$(filter mci,$(USEMODULE)))
SRC += sc_disk.c
endif

View File

@ -0,0 +1,613 @@
/*
* Shell commands for network interfaces
*
* Copyright (C) 2013 Martin Lenders
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup shell_commands
* @{
* @file sc_net_if.c
* @brief provides shell commands to configure network interfaces
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
* @}
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "destiny/socket.h" /* for AF_INET6 */
#include "inet_pton.h"
#include "inet_ntop.h"
#include "net_help.h"
#include "net_if.h"
#include "transceiver.h"
#define ADDR_REGISTERED_MAX (6)
#define ADDRS_LEN_MAX (16)
static uint8_t addr_registered = 0;
static uint8_t addrs[ADDR_REGISTERED_MAX][ADDRS_LEN_MAX];
void _net_if_ifconfig_add(int if_id, int argc, char **argv);
void _net_if_ifconfig_add_ipv6(int if_id, int argc, char **argv);
void _net_if_ifconfig_set(int if_id, char *key, char *value);
void _net_if_ifconfig_set_srcaddrmode(int if_id, char *mode);
void _net_if_ifconfig_set_eui64(int if_id, char *addr);
void _net_if_ifconfig_set_hwaddr(int if_id, char *addr);
void _net_if_ifconfig_set_pan_id(int if_id, char *pan_id);
void _net_if_ifconfig_set_channel(int if_id, char *channel);
void _net_if_ifconfig_create(char *transceivers_str);
int _net_if_ifconfig_ipv6_addr_convert(net_if_addr_t *addr, char *type,
char *addr_data_str, char *addr_data_len);
void _net_if_ifconfig_list(int if_id);
int isnumber(char *str)
{
for (; *str; str++) {
if (!isdigit((int)*str)) {
return 0;
}
}
return 1;
}
static inline void _eui64_to_str(char *eui64_str, net_if_eui64_t *eui64)
{
sprintf(eui64_str, "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
eui64->uint8[0], eui64->uint8[1], eui64->uint8[2], eui64->uint8[3],
eui64->uint8[4], eui64->uint8[5], eui64->uint8[6], eui64->uint8[7]);
}
char *addr_data_to_str(char *addr_str, const uint8_t *addr, uint8_t addr_len)
{
int i;
for (i = 0; i < addr_len / 8; i++) {
sprintf(addr_str, "%02x", addr[i]);
}
uint8_t r = addr_len % 8;
if (r) {
uint8_t mask = 0x00;
while (r) {
mask |= 0x1 << (8 - (r--));
}
sprintf(addr_str, "%02x", addr[addr_len / 8] & mask);
}
return addr_str;
}
void add_usage(void)
{
puts("Usage: ifconfig <if_id> add ipv6 [multicast|anycast] <addr>");
}
void set_usage(void)
{
printf("Usage: ifconfig <if_id> set <key> <value>\n"
" Sets an transceiver specific value\n"
" <key> may be one of the following\n"
" * \"srcaddrmode\" - sets the source address mode for IEEE\n"
" 802.15.4 transeivers (valid values: \"short\" or \"long\"),\n"
" * \"sam\" - alias for \"srcaddrmode\"\n"
" * \"eui64\" - sets the EUI-64 if supported by transceivers,\n"
" * \"hwaddr\" - sets the 16-bit address (or just the address\n"
" for e.g cc1100) of the transceivers\n"
" * \"pan_id\" - sets the PAN ID of the transceiver\n"
" * \"pan\" - alias for \"pan_id\"\n"
" * \"channel\" - sets the frequency channel of the transceiver\n"
" * \"chan\" - alias for \"channel\"\n");
}
void create_usage(void)
{
puts("Usage: ifconfig create <transceiver_1>[,<transceiver_2>,...]\n"
" <transceiver_n> may be one of the following values:\n"
#ifdef MODULE_AT86RF231
" * at86rv231\n"
#endif
#ifdef MODULE_CC1020
" * cc1020\n"
#endif
#if MODULE_CC110X || MODULE_CC110X_NG
" * cc1100\n"
#endif
#ifdef MODULE_CC2420
" * cc2420\n"
#endif
#ifdef MODULE_MC1322X
" * mc1322x\n"
#endif
#ifdef MODULE_NATIVENET
" * native\n"
#endif
);
}
void _net_if_ifconfig(int argc, char **argv)
{
if (argc < 2) {
int if_id = -1;
while ((if_id = net_if_iter_interfaces(if_id)) >= 0) {
_net_if_ifconfig_list(if_id);
}
return;
}
else if (strcmp(argv[1], "create") == 0) {
_net_if_ifconfig_create(argv[2]);
return;
}
else if (isnumber(argv[1])) {
int if_id = atoi(argv[1]);
if (argc < 3) {
_net_if_ifconfig_list(if_id);
return;
}
else if (strcmp(argv[2], "add") == 0) {
if (argc < 5) {
add_usage();
return;
}
_net_if_ifconfig_add(if_id, argc, argv);
return;
}
else if (strcmp(argv[2], "set") == 0) {
if (argc < 5) {
set_usage();
return;
}
_net_if_ifconfig_set(if_id, argv[3], argv[4]);
return;
}
}
create_usage();
printf("or: ifconfig [<if_id> [add <protocol> <addr>|set <key> <value>]]\n");
}
void _net_if_ifconfig_set_srcaddrmode(int if_id, char *mode)
{
if (mode == NULL) {
set_usage();
return;
}
else if (strcmp(mode, "short") == 0) {
net_if_set_src_address_mode(if_id, NET_IF_TRANS_ADDR_M_SHORT);
}
else if (strcmp(mode, "long") == 0) {
net_if_set_src_address_mode(if_id, NET_IF_TRANS_ADDR_M_LONG);
}
else {
set_usage();
return;
}
}
void _net_if_ifconfig_set_eui64(int if_id, char *eui64_str)
{
net_if_eui64_t eui64;
if (eui64_str == NULL) {
set_usage();
return;
}
net_if_hex_to_eui64(&eui64, eui64_str);
net_if_set_eui64(if_id, &eui64);
}
void _net_if_ifconfig_set_hwaddr(int if_id, char *addr_str)
{
int addr;
if (addr_str == NULL) {
set_usage();
return;
}
if (isnumber(addr_str)) {
if ((addr = atoi(addr_str)) > 0xffff) {
set_usage();
return;
}
}
else {
if ((addr = strtoul(addr_str, NULL, 16)) > 0xffff) {
set_usage();
return;
}
}
net_if_set_hardware_address(if_id, (uint16_t)addr);
}
void _net_if_ifconfig_set_pan_id(int if_id, char *pan_str)
{
int pan_id;
if (pan_str == NULL) {
set_usage();
return;
}
if (isnumber(pan_str)) {
if ((pan_id = atoi(pan_str)) > 0xffff) {
set_usage();
return;
}
}
else {
if ((pan_id = strtoul(pan_str, NULL, 16)) > 0xffff) {
set_usage();
return;
}
}
net_if_set_pan_id(if_id, (uint16_t) pan_id);
}
void _net_if_ifconfig_set_channel(int if_id, char *chan_str)
{
int channel;
if (chan_str == NULL) {
set_usage();
return;
}
if (isnumber(chan_str)) {
if ((channel = atoi(chan_str)) > 0xffff) {
set_usage();
return;
}
}
else {
if ((channel = strtoul(chan_str, NULL, 16)) > 0xffff) {
set_usage();
return;
}
}
net_if_set_channel(if_id, (uint16_t) channel);
}
void _net_if_ifconfig_set(int if_id, char *key, char *value)
{
if (strcmp(key, "sam") == 0 || strcmp(key, "srcaddrmode") == 0) {
_net_if_ifconfig_set_srcaddrmode(if_id, value);
}
else if (strcmp(key, "eui64") == 0) {
_net_if_ifconfig_set_eui64(if_id, value);
}
else if (strcmp(key, "hwaddr") == 0) {
_net_if_ifconfig_set_hwaddr(if_id, value);
}
else if (strcmp(key, "pan") == 0 || strcmp(key, "pan_id") == 0) {
_net_if_ifconfig_set_pan_id(if_id, value);
}
else if (strcmp(key, "chan") == 0 || strcmp(key, "channel") == 0) {
_net_if_ifconfig_set_channel(if_id, value);
}
else {
set_usage();
return;
}
}
void _net_if_ifconfig_add_ipv6(int if_id, int argc, char **argv)
{
char *type;
char *addr_str;
char *addr_data_str;
char *addr_data_len;
net_if_addr_t addr;
if (argc > 5) {
if (strcmp(argv[4], "multicast") == 0 || strcmp(argv[4], "anycast") == 0 || strcmp(argv[4], "unicast") == 0) {
type = argv[4];
addr_str = argv[5];
}
else {
add_usage();
return;
}
}
else {
addr_str = argv[4];
type = NULL;
}
addr_data_str = strtok(addr_str, "/");
addr_data_len = strtok(NULL, "/");
if (!_net_if_ifconfig_ipv6_addr_convert(&addr, type, addr_data_str, addr_data_len)) {
add_usage();
return;
}
if (net_if_add_address(if_id, &addr) < 0) {
add_usage();
return;
}
addr_registered++;
}
void _net_if_ifconfig_add(int if_id, int argc, char **argv)
{
if (strcmp(argv[3], "ipv6") == 0) {
_net_if_ifconfig_add_ipv6(if_id, argc, argv);
}
else {
add_usage();
}
}
void _net_if_ifconfig_create(char *transceivers_str)
{
char *transceiver_str;
transceiver_type_t transceivers = TRANSCEIVER_NONE;
int iface;
transceiver_str = strtok(transceivers_str, ",");
while (transceiver_str) {
if (strcasecmp(transceiver_str, "at86rv231") == 0) {
transceivers |= TRANSCEIVER_AT86RF231;
}
else if (strcasecmp(transceiver_str, "cc1020") == 0) {
transceivers |= TRANSCEIVER_CC1020;
}
else if (strcasecmp(transceiver_str, "cc1100") == 0) {
transceivers |= TRANSCEIVER_CC1100;
}
else if (strcasecmp(transceiver_str, "cc2420") == 0) {
transceivers |= TRANSCEIVER_CC2420;
}
else if (strcasecmp(transceiver_str, "mc1322x") == 0) {
transceivers |= TRANSCEIVER_MC1322X;
}
else if (strcasecmp(transceiver_str, "native") == 0) {
transceivers |= TRANSCEIVER_NATIVE;
}
else {
create_usage();
return;
}
transceiver_str = strtok(NULL, ",");
}
if (!transceivers) {
create_usage();
return;
}
iface = net_if_init_interface(NET_IF_L3P_RAW, transceivers);
if (iface < 0) {
puts("Maximum number of allowed interfaces reached.\n");
}
else {
printf("Initialized interface %d\n", iface);
}
}
static inline int _is_multicast(uint8_t *addr)
{
return *addr == 0xff;
}
static inline int _is_link_local(uint8_t *addr)
{
return (addr[0] == 0xfe && addr[1] == 0x80) ||
(_is_multicast(addr) && (addr[1] & 0x0f) == 2);
}
int _set_protocol_from_type(char *type, net_if_addr_t *addr)
{
if (type != NULL) {
if ((strcmp(type, "multicast") == 0) &&
_is_multicast((uint8_t *)addr->addr_data)) {
addr->addr_protocol |= NET_IF_L3P_IPV6_MULTICAST;
return 1;
}
else if ((strcmp(type, "anycast") == 0) &&
addr->addr_protocol & NET_IF_L3P_IPV6_PREFIX) {
addr->addr_protocol |= NET_IF_L3P_IPV6_ANYCAST;
return 1;
}
return 0;
}
else if (_is_multicast((uint8_t *)addr->addr_data)) {
addr->addr_protocol |= NET_IF_L3P_IPV6_MULTICAST;
return 1;
}
else {
addr->addr_protocol |= NET_IF_L3P_IPV6_UNICAST;
return 1;
}
}
int _net_if_ifconfig_ipv6_addr_convert(net_if_addr_t *addr, char *type,
char *addr_data_str, char *addr_data_len)
{
if (addr_data_len && !isnumber(addr_data_len)) {
return 0;
}
addr->addr_data = (void *)&addrs[addr_registered][0];
if (!inet_pton(AF_INET6, addr_data_str, addr->addr_data)) {
return 0;
}
else if (addr_data_len == NULL) {
addr->addr_len = 128;
addr->addr_protocol = 0;
if (!_set_protocol_from_type(type, addr)) {
return 0;
}
}
else {
addr->addr_len = atoi(addr_data_len);
addr->addr_protocol = NET_IF_L3P_IPV6_PREFIX;
if (addr->addr_len > 128 || !_set_protocol_from_type(type, addr)) {
return 0;
}
}
return 1;
}
void _net_if_ifconfig_list(int if_id)
{
net_if_t *iface = net_if_get_interface(if_id);
transceiver_type_t transceivers;
uint16_t hw_address;
int32_t channel;
int32_t pan_id;
net_if_eui64_t eui64;
char eui64_str[24];
net_if_addr_t *addr_ptr = NULL;
if (!iface) {
return;
}
transceivers = iface->transceivers;
hw_address = net_if_get_hardware_address(if_id);
channel = net_if_get_channel(if_id);
pan_id = net_if_get_pan_id(if_id);
net_if_get_eui64(&eui64, if_id, 0);
_eui64_to_str(eui64_str, &eui64);
printf("Iface %3d HWaddr: 0x%04x", if_id,
hw_address);
if (channel < 0) {
printf(" Channel: not set");
}
else {
printf(" Channel: %d", (uint16_t) channel);
}
if (pan_id < 0) {
printf(" PAN ID: not set");
}
else {
printf(" PAN ID: 0x%04x", (uint16_t)pan_id);
}
printf("\n");
printf(" EUI-64: %s\n", eui64_str);
switch (net_if_get_src_address_mode(if_id)) {
case NET_IF_TRANS_ADDR_M_SHORT:
puts(" Source address mode: short");
break;
case NET_IF_TRANS_ADDR_M_LONG:
puts(" Source address mode: long");
break;
default:
puts(" Source address mode: unknown");
break;
}
puts(" Transceivers:");
if (transceivers & TRANSCEIVER_AT86RF231) {
puts(" * at86rf231");
}
if (transceivers & TRANSCEIVER_CC1020) {
puts(" * cc1020");
}
if (transceivers & TRANSCEIVER_CC1100) {
puts(" * cc1100");
}
if (transceivers & TRANSCEIVER_CC2420) {
puts(" * cc2420");
}
if (transceivers & TRANSCEIVER_MC1322X) {
puts(" * mc1322x");
}
if (transceivers & TRANSCEIVER_NATIVE) {
puts(" * native");
}
while (net_if_iter_addresses(if_id, &addr_ptr)) {
if (addr_ptr->addr_protocol == NET_IF_L3P_RAW) {
char addr_str[addr_ptr->addr_len / 4 + 3];
printf(" Raw L3 addr: 0x");
printf("%s", addr_data_to_str(addr_str, addr_ptr->addr_data,
addr_ptr->addr_len));
puts("\n");
}
if (addr_ptr->addr_protocol & NET_IF_L3P_IPV6) {
char addr_str[50];
printf(" inet6 addr: ");
if (inet_ntop(AF_INET6, addr_ptr->addr_data, addr_str,
addr_ptr->addr_len / 8 + 1)) {
printf("%s/%d", addr_str, addr_ptr->addr_len);
printf(" scope: ");
if (addr_ptr->addr_len > 2 && _is_link_local((uint8_t *)addr_ptr->addr_data)) {
printf("local");
}
else {
printf("local");
}
if (!(addr_ptr->addr_protocol & NET_IF_L3P_IPV6_UNICAST)) {
printf(" ");
if (addr_ptr->addr_protocol & NET_IF_L3P_IPV6_MULTICAST) {
printf("[multicast]");
}
else if (addr_ptr->addr_protocol & NET_IF_L3P_IPV6_ANYCAST) {
printf("[anycast]");
}
}
printf("\n");
}
else {
printf("error in conversion\n");
}
}
}
puts("");
}

View File

@ -21,6 +21,9 @@
#include <string.h>
#include <inttypes.h>
#ifdef MODULE_NET_IF
#include "net_if.h"
#endif
#include "transceiver.h"
#include "msg.h"
@ -80,6 +83,92 @@ void _transceiver_get_set_address_handler(int argc, char **argv)
printf("[transceiver] got address: %" PRIu16 "\n", a);
}
#ifndef MODULE_NET_IF
uint8_t hex_to_dec(char c)
{
if (c >= '0' && c <= '9') {
return (uint8_t)(c - '0');
}
else if (c >= 'A' && c <= 'F') {
return (uint8_t)(c - 55);
}
else if (c >= 'a' && c <= 'f') {
return (uint8_t)(c - 87);
}
else {
return 0xff;
}
}
uint64_t _str_to_eui64(const char *eui64_str)
{
int i;
const char *eui64_rev = &eui64_str[strlen(eui64_str) - 1];
uint64_t eui64 = 0;
for (i = 7; i >= 0 || eui64_rev >= eui64_str; i--) {
uint8_t digit;
eui64 <<= 8;
while ((digit = hex_to_dec(*eui64_rev)) == 0xFF) {
if (--eui64_rev < eui64_str) {
return eui64;
}
}
eui64 = digit;
eui64_rev--;
while ((digit = hex_to_dec(*eui64_rev)) == 0xFF) {
if (--eui64_rev < eui64_str) {
return eui64;
}
}
eui64 |= digit << 4;
eui64_rev--;
}
return eui64;
}
#endif
/* checked for type safety */
void _transceiver_get_set_long_addr_handler(int argc, char **argv)
{
msg_t mesg;
transceiver_command_t tcmd;
transceiver_eui64_t a;
if (transceiver_pid < 0) {
puts("Transceiver not initialized");
return;
}
tcmd.transceivers = _TC_TYPE;
tcmd.data = &a;
mesg.content.ptr = (char *) &tcmd;
if (argc > 1) {
#ifdef MODULE_NET_IF
net_if_eui64_t eui64;
net_if_hex_to_eui64(&eui64, argv[1]);
a = eui64.uint64;
#else
a = _str_to_eui64(argv[1]);
#endif
printf("[transceiver] trying to set EUI-64 %016"PRIx64"\n", a);
mesg.type = SET_LONG_ADDR;
}
else {
mesg.type = GET_LONG_ADDR;
}
msg_send_receive(&mesg, &mesg, transceiver_pid);
printf("[transceiver] got EUI-64: %016"PRIx64"\n", a);
}
/* checked for type safety */
void _transceiver_get_set_channel_handler(int argc, char **argv)
{

View File

@ -65,7 +65,8 @@ extern void _reset_current_handler(int argc, char **argv);
#define _TC_MON
#define _TC_SEND
#endif
#if (defined(MODULE_CC2420) || defined(MODULE_NATIVENET))
#if (defined(MODULE_CC2420) || defined(MODULE_AT86RF231) || defined(MODULE_NATIVENET))
#define _TC_LONG_ADDR
#define _TC_PAN
#endif
#else /* WITHOUT MODULE_TRANSCEIVER */
@ -79,6 +80,9 @@ extern void _cc110x_get_set_channel_handler(int argc, char **argv);
#ifdef _TC_ADDR
extern void _transceiver_get_set_address_handler(int argc, char **argv);
#endif
#ifdef _TC_LONG_ADDR
extern void _transceiver_get_set_long_addr_handler(int argc, char **argv);
#endif
#ifdef _TC_CHAN
extern void _transceiver_get_set_channel_handler(int argc, char **argv);
#endif
@ -96,6 +100,10 @@ extern void _transceiver_set_ignore_handler(int argc, char **argv);
#endif
#endif
#ifdef MODULE_NET_IF
extern void _net_if_ifconfig(int argc, char **argv);
#endif
#ifdef MODULE_MCI
extern void _get_sectorsize(int argc, char **argv);
extern void _get_blocksize(int argc, char **argv);
@ -133,11 +141,13 @@ const shell_command_t _shell_command_list[] = {
{"cur", "Prints current and average power consumption.", _get_current_handler},
{"rstcur", "Resets coulomb counter.", _reset_current_handler},
#endif
#ifdef MODULE_TRANSCEIVER
#ifdef _TC_ADDR
{"addr", "Gets or sets the address for the transceiver", _transceiver_get_set_address_handler},
#endif
#ifdef _TC_LONG_ADDR
{"eui64", "Gets or sets the EUI-64 for the transceiver", _transceiver_get_set_long_addr_handler},
#endif
#ifdef _TC_CHAN
{"chan", "Gets or sets the channel for the transceiver", _transceiver_get_set_channel_handler},
#endif
@ -159,7 +169,9 @@ const shell_command_t _shell_command_list[] = {
{"chan", "Gets or sets the channel for the CC1100 transceiver", _cc110x_get_set_channel_handler},
#endif
#endif
#ifdef MODULE_NET_IF
{"ifconfig", "Configures a network interface", _net_if_ifconfig},
#endif
#ifdef MODULE_MCI
{DISK_READ_SECTOR_CMD, "Reads the specified sector of inserted memory card", _read_sector},
{DISK_READ_BYTES_CMD, "Reads the specified bytes from inserted memory card", _read_bytes},
@ -171,6 +183,5 @@ const shell_command_t _shell_command_list[] = {
{ "mersenne_init", "initializes the PRNG", _mersenne_init },
{ "mersenne_get", "returns 32 bit of pseudo randomness", _mersenne_get },
#endif
{NULL, NULL, NULL}
};

View File

@ -1,3 +1,15 @@
MODULE =transceiver
ifneq (,$(filter cc2420,$(USEMODULE)))
INCLUDES += -I$(RIOTBASE)/sys/net/include
endif
ifneq (,$(filter at86rf231,$(USEMODULE)))
INCLUDES += -I$(RIOTBASE)/sys/net/include
endif
ifneq (,$(filter mc1322x,$(USEMODULE)))
INCLUDES += -I$(RIOTBASE)/sys/net/include
endif
include $(MAKEBASE)/Makefile.base

View File

@ -40,12 +40,14 @@
#ifdef MODULE_CC2420
#include "cc2420.h"
#include "ieee802154_frame.h"
#endif
#ifdef MODULE_MC1322X
#include "mc1322x.h"
#include "maca.h"
#include "maca_packet.h"
#include "ieee802154_frame.h"
#endif
#ifdef MODULE_NATIVENET
@ -55,10 +57,12 @@
#ifdef MODULE_AT86RF231
#include "at86rf231.h"
#include "ieee802154_frame.h"
#endif
#define ENABLE_DEBUG (0)
#if ENABLE_DEBUG
#define DEBUG_ENABLED
#undef TRANSCEIVER_STACK_SIZE
#define TRANSCEIVER_STACK_SIZE (KERNEL_CONF_STACKSIZE_PRINTF)
#endif
@ -72,7 +76,11 @@ transceiver_type_t transceivers = TRANSCEIVER_NONE;
registered_t reg[TRANSCEIVER_MAX_REGISTERED];
/* packet buffers */
#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X
ieee802154_packet_t transceiver_buffer[TRANSCEIVER_BUFFER_SIZE];
#else
radio_packet_t transceiver_buffer[TRANSCEIVER_BUFFER_SIZE];
#endif
uint8_t data_buffer[TRANSCEIVER_BUFFER_SIZE * PAYLOAD_SIZE];
/* message buffer */
@ -86,10 +94,10 @@ static volatile uint8_t rx_buffer_pos = 0;
static volatile uint8_t transceiver_buffer_pos = 0;
#ifdef MODULE_CC110X
void *cc1100_payload;
int cc1100_payload_size;
packet_info_t *cc1100_packet_info;
uint8_t cc1100_pkt[CC1100_MAX_DATA_LENGTH];
void *cc1100_payload;
int cc1100_payload_size;
packet_info_t *cc1100_packet_info;
uint8_t cc1100_pkt[CC1100_MAX_DATA_LENGTH];
#endif
@ -108,19 +116,22 @@ void cc1100_packet_monitor(void *payload, int payload_size, protocol_t protocol,
void receive_cc1100_packet(radio_packet_t *trans_p);
#endif
#ifdef MODULE_CC2420
static void receive_cc2420_packet(radio_packet_t *trans_p);
static void receive_cc2420_packet(ieee802154_packet_t *trans_p);
#endif
#ifdef MODULE_NATIVENET
static void receive_nativenet_packet(radio_packet_t *trans_p);
#endif
#ifdef MODULE_AT86RF231
void receive_at86rf231_packet(radio_packet_t *trans_p);
void receive_at86rf231_packet(ieee802154_packet_t *trans_p);
#endif
static int8_t send_packet(transceiver_type_t t, void *pkt);
static int32_t get_channel(transceiver_type_t t);
static int32_t set_channel(transceiver_type_t t, void *channel);
static radio_address_t get_address(transceiver_type_t t);
static radio_address_t set_address(transceiver_type_t t, void *address);
static transceiver_eui64_t get_long_addr(transceiver_type_t t);
static transceiver_eui64_t set_long_addr(transceiver_type_t t,
void *address);
static int32_t get_pan(transceiver_type_t t);
static int32_t set_pan(transceiver_type_t t, void *pan);
@ -148,7 +159,7 @@ void transceiver_init(transceiver_type_t t)
}
/* Initializing transceiver buffer and data buffer */
memset(transceiver_buffer, 0, TRANSCEIVER_BUFFER_SIZE * sizeof(radio_packet_t));
memset(transceiver_buffer, 0, sizeof(transceiver_buffer));
memset(data_buffer, 0, TRANSCEIVER_BUFFER_SIZE * PAYLOAD_SIZE);
#ifdef DBG_IGNORE
memset(ignored_addr, 0, MAX_IGNORED_ADDR * sizeof(radio_address_t));
@ -158,6 +169,7 @@ void transceiver_init(transceiver_type_t t)
reg[i].transceivers = TRANSCEIVER_NONE;
reg[i].pid = 0;
}
/* check if a non defined bit is set */
if (t & ~(TRANSCEIVER_CC1100 | TRANSCEIVER_CC2420 | TRANSCEIVER_MC1322X | TRANSCEIVER_NATIVE | TRANSCEIVER_AT86RF231)) {
puts("Invalid transceiver type");
@ -175,11 +187,13 @@ int transceiver_start(void)
if (transceiver_pid < 0) {
puts("Error creating transceiver thread");
}
#ifdef MODULE_CC110X_NG
else if (transceivers & TRANSCEIVER_CC1100) {
DEBUG("transceiver: Transceiver started for CC1100\n");
cc110x_init(transceiver_pid);
}
#endif
#ifdef MODULE_CC110X
else if (transceivers & TRANSCEIVER_CC1100) {
@ -187,28 +201,33 @@ int transceiver_start(void)
cc1100_init();
cc1100_set_packet_monitor(cc1100_packet_monitor);
}
#endif
#ifdef MODULE_CC2420
else if(transceivers & TRANSCEIVER_CC2420) {
else if (transceivers & TRANSCEIVER_CC2420) {
DEBUG("transceiver: Transceiver started for CC2420\n");
cc2420_init(transceiver_pid);
}
#endif
#ifdef MODULE_AT86RF231
else if(transceivers & TRANSCEIVER_AT86RF231) {
else if (transceivers & TRANSCEIVER_AT86RF231) {
DEBUG("transceiver: Transceiver started for AT86RF231\n");
at86rf231_init(transceiver_pid);
}
#endif
#ifdef MODULE_MC1322X
else if (transceivers & TRANSCEIVER_MC1322X) {
maca_init();
}
#endif
#ifdef MODULE_NATIVENET
else if (transceivers & TRANSCEIVER_NATIVE) {
nativenet_init(transceiver_pid);
}
#endif
return transceiver_pid;
}
@ -220,8 +239,8 @@ uint8_t transceiver_register(transceiver_type_t t, int pid)
/* find pid in registered threads or first unused space */
for (i = 0; ((i < TRANSCEIVER_MAX_REGISTERED) &&
(reg[i].pid != pid) &&
(reg[i].transceivers != TRANSCEIVER_NONE)); i++);
(reg[i].pid != pid) &&
(reg[i].transceivers != TRANSCEIVER_NONE)); i++);
if (i >= TRANSCEIVER_MAX_REGISTERED) {
return ENOMEM;
@ -256,7 +275,7 @@ void run(void)
cmd = (transceiver_command_t *) m.content.ptr;
DEBUG("transceiver: Transceiver: Message received, type: %02X\n", m.type);
switch(m.type) {
switch (m.type) {
case RCV_PKT_CC1020:
case RCV_PKT_CC1100:
case RCV_PKT_CC2420:
@ -265,6 +284,7 @@ void run(void)
case RCV_PKT_AT86RF231:
receive_packet(m.type, m.content.value);
break;
case SND_PKT:
response = send_packet(cmd->transceivers, cmd->data);
m.content.value = response;
@ -291,6 +311,16 @@ void run(void)
msg_reply(&m, &m);
break;
case GET_LONG_ADDR:
*((transceiver_eui64_t *) cmd->data) = get_long_addr(cmd->transceivers);
msg_reply(&m, &m);
break;
case SET_LONG_ADDR:
*((transceiver_eui64_t *) cmd->data) = set_long_addr(cmd->transceivers, cmd->data);
msg_reply(&m, &m);
break;
case SET_MONITOR:
set_monitor(cmd->transceivers, cmd->data);
break;
@ -302,17 +332,20 @@ void run(void)
case SWITCH_RX:
switch_to_rx(cmd->transceivers);
break;
case GET_PAN:
*((int32_t *) cmd->data) = get_pan(cmd->transceivers);
msg_reply(&m, &m);
break;
case SET_PAN:
*((int32_t *) cmd->data) = set_pan(cmd->transceivers, cmd->data);
msg_reply(&m, &m);
break;
#ifdef DBG_IGNORE
case DBG_IGN:
*((int16_t*) cmd->data) = ignore_add(cmd->transceivers, cmd->data);
*((int16_t *) cmd->data) = ignore_add(cmd->transceivers, cmd->data);
msg_reply(&m, &m);
break;
#endif
@ -341,7 +374,7 @@ static void receive_packet(uint16_t type, uint8_t pos)
DEBUG("Packet received\n");
switch(type) {
switch (type) {
case RCV_PKT_CC1020:
t = TRANSCEIVER_CC1020;
break;
@ -349,18 +382,23 @@ static void receive_packet(uint16_t type, uint8_t pos)
case RCV_PKT_CC1100:
t = TRANSCEIVER_CC1100;
break;
case RCV_PKT_CC2420:
t = TRANSCEIVER_CC2420;
break;
case RCV_PKT_MC1322X:
t = TRANSCEIVER_MC1322X;
break;
case RCV_PKT_NATIVE:
t = TRANSCEIVER_NATIVE;
break;
case RCV_PKT_NATIVE:
t = TRANSCEIVER_NATIVE;
break;
case RCV_PKT_AT86RF231:
t = TRANSCEIVER_AT86RF231;
break;
default:
t = TRANSCEIVER_NONE;
break;
@ -381,60 +419,59 @@ static void receive_packet(uint16_t type, uint8_t pos)
}
/* copy packet and handle it */
else {
radio_packet_t *trans_p = &(transceiver_buffer[transceiver_buffer_pos]);
m.type = PKT_PENDING;
/* pass a null pointer if a packet from a undefined transceiver is
* received */
if (type == RCV_PKT_CC1100) {
#ifdef MODULE_CC110X_NG
radio_packet_t *trans_p = &(transceiver_buffer[transceiver_buffer_pos]);
receive_cc110x_packet(trans_p);
#elif MODULE_CC110X
radio_packet_t *trans_p = &(transceiver_buffer[transceiver_buffer_pos]);
receive_cc1100_packet(trans_p);
#else
trans_p = NULL;
#endif
}
else if (type == RCV_PKT_MC1322X) {
#ifdef MODULE_MC1322X
ieee802154_packet_t *trans_p = &(transceiver_buffer[transceiver_buffer_pos]);
receive_mc1322x_packet(trans_p);
#else
trans_p = NULL;
#endif
}
else if (type == RCV_PKT_CC2420) {
#ifdef MODULE_CC2420
ieee802154_packet_t *trans_p = &(transceiver_buffer[transceiver_buffer_pos]);
receive_cc2420_packet(trans_p);
#else
trans_p = NULL;
#endif
}
else if (type == RCV_PKT_AT86RF231) {
#ifdef MODULE_AT86RF231
ieee802154_packet_t *trans_p = &(transceiver_buffer[transceiver_buffer_pos]);
receive_at86rf231_packet(trans_p);
#else
trans_p = NULL;
#endif
}
else if (type == RCV_PKT_NATIVE) {
#ifdef MODULE_NATIVENET
radio_packet_t *trans_p = &(transceiver_buffer[transceiver_buffer_pos]);
receive_nativenet_packet(trans_p);
#else
trans_p = NULL;
#endif
}
else {
puts("Invalid transceiver type");
return;
}
#ifdef DBG_IGNORE
for (uint8_t i = 0; (i < MAX_IGNORED_ADDR) && (ignored_addr[i]); i++) {
DEBUG("check if source (%u) is ignored -> %u\n", trans_p->src, ignored_addr[i]);
if (trans_p->src == ignored_addr[i]) {
DEBUG("ignored packet from %" PRIu16 "\n", trans_p->src);
return;
}
}
#endif
}
@ -444,7 +481,7 @@ static void receive_packet(uint16_t type, uint8_t pos)
while (reg[i].transceivers != TRANSCEIVER_NONE) {
if (reg[i].transceivers & t) {
m.content.ptr = (char *) & (transceiver_buffer[transceiver_buffer_pos]);
m.content.ptr = (char *) &(transceiver_buffer[transceiver_buffer_pos]);
DEBUG("transceiver: Notify thread %i\n", reg[i].pid);
if (msg_send(&m, reg[i].pid, false) && (m.type != ENOBUFFER)) {
@ -474,10 +511,10 @@ static void receive_cc110x_packet(radio_packet_t *trans_p)
trans_p->rssi = cc110x_rx_buffer[rx_buffer_pos].rssi;
trans_p->lqi = cc110x_rx_buffer[rx_buffer_pos].lqi;
trans_p->length = p.length - CC1100_HEADER_LENGTH;
memcpy((void *)&(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p.data, CC1100_MAX_DATA_LENGTH);
memcpy((void *) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p.data, CC1100_MAX_DATA_LENGTH);
eINT();
trans_p->data = (uint8_t *)&(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]);
trans_p->data = (uint8_t *) &(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]);
DEBUG("transceiver: Packet %p (%p) was from %hu to %hu, size: %u\n", trans_p, trans_p->data, trans_p->src, trans_p->dst, trans_p->length);
}
#endif
@ -491,51 +528,89 @@ void receive_cc1100_packet(radio_packet_t *trans_p)
trans_p->rssi = cc1100_packet_info->rssi;
trans_p->lqi = cc1100_packet_info->lqi;
trans_p->length = cc1100_payload_size;
memcpy((void *)&(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), cc1100_payload, CC1100_MAX_DATA_LENGTH);
memcpy((void *) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), cc1100_payload, CC1100_MAX_DATA_LENGTH);
eINT();
trans_p->data = (uint8_t *)&(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]);
trans_p->data = (uint8_t *) &(data_buffer[transceiver_buffer_pos * CC1100_MAX_DATA_LENGTH]);
}
#endif
#ifdef MODULE_CC2420
void receive_cc2420_packet(radio_packet_t *trans_p) {
void receive_cc2420_packet(ieee802154_packet_t *trans_p)
{
DEBUG("transceiver: Handling CC2420 packet\n");
dINT();
cc2420_packet_t p = cc2420_rx_buffer[rx_buffer_pos];
trans_p->src = (uint16_t)((p.frame.src_addr[1] << 8) | p.frame.src_addr[0]);
trans_p->dst = (uint16_t)((p.frame.dest_addr[1] << 8)| p.frame.dest_addr[0]);
trans_p->rssi = p.rssi;
trans_p->lqi = p.lqi;
trans_p->length = p.frame.payload_len;
memcpy((void*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p.frame.payload, CC2420_MAX_DATA_LENGTH);
cc2420_packet_t *p = &cc2420_rx_buffer[rx_buffer_pos];
trans_p->length = p->length;
memcpy(&trans_p->frame, &p->frame, p->length);
trans_p->rssi = p->rssi;
trans_p->crc = p->crc;
trans_p->lqi = p->lqi;
memcpy(&data_buffer[transceiver_buffer_pos * CC2420_MAX_DATA_LENGTH],
p->frame.payload, p->frame.payload_len);
trans_p->frame.payload = (uint8_t *) & (data_buffer[transceiver_buffer_pos * CC2420_MAX_DATA_LENGTH]);
eINT();
DEBUG("transceiver: Packet %p was from %u to %u, size: %u\n", trans_p, trans_p->src, trans_p->dst, trans_p->length);
trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * CC2420_MAX_DATA_LENGTH]);
#ifdef DEBUG_ENABLED
if (trans_p->frame.fcf.dest_addr_m == IEEE_802154_SHORT_ADDR_M) {
if (trans_p->frame.fcf.src_addr_m == IEEE_802154_SHORT_ADDR_M) {
DEBUG("Packet %p was from %" PRIu16 " to %" PRIu16 ", size: %u\n", trans_p, *((uint16_t *) &trans_p->frame.src_addr[0]), *((uint16_t *) &trans_p->frame.dest_addr), trans_p->frame.payload_len);
}
else if (trans_p->frame.fcf.src_addr_m == IEEE_802154_LONG_ADDR_M) {
DEBUG("Packet %p was from %016" PRIx64 " to %" PRIu16 ", size: %u\n", trans_p, *((uint64_t *) &trans_p->frame.src_addr[0]), *((uint16_t *) &trans_p->frame.dest_addr), trans_p->frame.payload_len);
}
else {
DEBUG("Illegal source address mode: %d\n", trans_p->frame.fcf.src_addr_m);
return;
}
}
else if (trans_p->frame.fcf.dest_addr_m == IEEE_802154_LONG_ADDR_M) {
if (trans_p->frame.fcf.src_addr_m == IEEE_802154_SHORT_ADDR_M) {
DEBUG("Packet %p was from %" PRIu16 " to %016" PRIx64 ", size: %u\n", trans_p, *((uint16_t *) &trans_p->frame.src_addr[0]), *((uint64_t *) &trans_p->frame.dest_addr), trans_p->frame.payload_len);
}
else if (trans_p->frame.fcf.src_addr_m == IEEE_802154_LONG_ADDR_M) {
DEBUG("Packet %p was from %016" PRIx64 " to %016" PRIx64 ", size: %u\n", trans_p, *((uint64_t *) &trans_p->frame.src_addr[0]), *((uint16_t *) &trans_p->frame.dest_addr), trans_p->frame.payload_len);
}
else {
DEBUG("Illegal source address mode: %d\n", trans_p->frame.fcf.src_addr_m);
return;
}
}
else {
DEBUG("Illegal destination address mode: %d\n", trans_p->frame.fcf.src_addr_m);
return;
}
#endif
trans_p->frame.payload = (uint8_t *) &(data_buffer[transceiver_buffer_pos * CC2420_MAX_DATA_LENGTH]);
trans_p->frame.payload_len = p->frame.payload_len;
DEBUG("transceiver: Content: %s\n", trans_p->data);
}
#endif
#ifdef MODULE_MC1322X
void receive_mc1322x_packet(radio_packet_t *trans_p) {
maca_packet_t* maca_pkt;
void receive_mc1322x_packet(radio_packet_t *trans_p)
{
maca_packet_t *maca_pkt;
dINT();
maca_pkt = maca_get_rx_packet ();
maca_pkt = maca_get_rx_packet();
trans_p->lqi = maca_pkt->lqi;
trans_p->length = maca_pkt->length;
memcpy((void*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), maca_pkt->data, MACA_MAX_PAYLOAD_SIZE);
maca_free_packet( maca_pkt );
memcpy((void *) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), maca_pkt->data, MACA_MAX_PAYLOAD_SIZE);
maca_free_packet(maca_pkt);
eINT();
trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * MACA_MAX_PAYLOAD_SIZE]);
trans_p->data = (uint8_t *) &(data_buffer[transceiver_buffer_pos * MACA_MAX_PAYLOAD_SIZE]);
}
#endif
#ifdef MODULE_NATIVENET
void receive_nativenet_packet(radio_packet_t *trans_p) {
void receive_nativenet_packet(radio_packet_t *trans_p)
{
unsigned state;
radio_packet_t *p = &_nativenet_rx_buffer[rx_buffer_pos].packet;
@ -546,7 +621,7 @@ void receive_nativenet_packet(radio_packet_t *trans_p) {
memcpy(trans_p, p, sizeof(radio_packet_t));
memcpy(&(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p->data, p->length);
trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]);
trans_p->data = (uint8_t *) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]);
DEBUG("Packet %p was from %" PRIu16 " to %" PRIu16 ", size: %" PRIu8 "\n", trans_p, trans_p->src, trans_p->dst, trans_p->length);
@ -556,21 +631,44 @@ void receive_nativenet_packet(radio_packet_t *trans_p) {
#endif
#ifdef MODULE_AT86RF231
void receive_at86rf231_packet(radio_packet_t *trans_p) {
void receive_at86rf231_packet(ieee802154_packet_t *trans_p)
{
DEBUG("Handling AT86RF231 packet\n");
dINT();
at86rf231_packet_t p = at86rf231_rx_buffer[rx_buffer_pos];
trans_p->src = (uint16_t)((p.frame.src_addr[1] << 8) | p.frame.src_addr[0]);
trans_p->dst = (uint16_t)((p.frame.dest_addr[1] << 8)| p.frame.dest_addr[0]);
trans_p->rssi = p.rssi;
trans_p->lqi = p.lqi;
trans_p->length = p.frame.payload_len;
memcpy((void*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p.frame.payload, AT86RF231_MAX_DATA_LENGTH);
at86rf231_packet_t *p = &at86rf231_rx_buffer[rx_buffer_pos];
trans_p->length = p->length;
trans_p->rssi = p->rssi;
trans_p->crc = p->crc;
trans_p->lqi = p->lqi;
memcpy(&trans_p->frame, &p->frame, p->length);
memcpy(&data_buffer[transceiver_buffer_pos * AT86RF231_MAX_DATA_LENGTH], p->frame.payload,
p->frame.payload_len);
trans_p->frame.payload = (uint8_t *) & (data_buffer[transceiver_buffer_pos * AT86RF231_MAX_DATA_LENGTH]);
eINT();
DEBUG("Packet %p was from %u to %u, size: %u\n", trans_p, trans_p->src, trans_p->dst, trans_p->length);
trans_p->data = (uint8_t*) &(data_buffer[transceiver_buffer_pos * AT86RF231_MAX_DATA_LENGTH]);
DEBUG("Content: %s\n", trans_p->data);
#ifdef DEBUG_ENABLED
if (trans_p->frame.fcf.dest_addr_m == IEEE_802154_SHORT_ADDR_M) {
if (trans_p->frame.fcf.src_addr_m == IEEE_802154_SHORT_ADDR_M) {
DEBUG("Packet %p was from %" PRIu16 " to %" PRIu16 ", size: %u\n", trans_p, *((uint16_t *) &trans_p->frame.src_addr[0]), *((uint16_t *) &trans_p->frame.dest_addr), trans_p->frame.payload_len);
}
else {
DEBUG("Packet %p was from %016" PRIx64 " to %" PRIu16 ", size: %u\n", trans_p, *((uint64_t *) &trans_p->frame.src_addr[0]), *((uint16_t *) &trans_p->frame.dest_addr), trans_p->frame.payload_len);
}
}
else {
if (trans_p->frame.fcf.src_addr_m == IEEE_802154_SHORT_ADDR_M) {
DEBUG("Packet %p was from %" PRIu16 " to %016" PRIx64 ", size: %u\n", trans_p, *((uint16_t *) &trans_p->frame.src_addr[0]), *((uint64_t *) &trans_p->frame.dest_addr), trans_p->frame.payload_len);
}
else {
DEBUG("Packet %p was from %016" PRIx64 " to %016" PRIx64 ", size: %u\n", trans_p, *((uint64_t *) &trans_p->frame.src_addr[0]), *((uint16_t *) &trans_p->frame.dest_addr), trans_p->frame.payload_len);
}
}
#endif
DEBUG("Content: %s\n", trans_p->frame.payload);
}
#endif
/*------------------------------------------------------------------------------------*/
@ -578,20 +676,35 @@ void receive_at86rf231_packet(radio_packet_t *trans_p) {
* @brief Sends a radio packet to the receiver
*
* @param t The transceiver device
* @param pkt Generic pointer to the packet
* @param pkt Generic pointer to the packet (use ieee802154_packet_t for
* AT86RF231, CC2420, and MC1322X)
*
* @return A negative value if operation failed, 0 or the number of bytes sent otherwise.
*/
static int8_t send_packet(transceiver_type_t t, void *pkt)
{
int8_t res = -1;
radio_packet_t p = *((radio_packet_t *)pkt);
#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X
ieee802154_packet_t *p = (ieee802154_packet_t *)pkt;
DEBUG("transceiver: Send packet to ");
#ifdef DEBUG_ENABLED
for (size_t i = 0; i < 8; i++) {
printf("%02x ", p->frame.dest_addr[i]);
}
printf("\n");
#endif
#else
radio_packet_t *p = (radio_packet_t *)pkt;
DEBUG("transceiver: Send packet to %" PRIu16 "\n", p->dst);
#endif
#ifdef MODULE_CC110X_NG
cc110x_packet_t cc110x_pkt;
#endif
#ifdef MODULE_MC1322X
maca_packet_t* maca_pkt = maca_get_free_packet();
maca_packet_t *maca_pkt = maca_get_free_packet();
#endif
#ifdef MODULE_CC2420
@ -602,69 +715,55 @@ static int8_t send_packet(transceiver_type_t t, void *pkt)
at86rf231_packet_t at86rf231_pkt;
#endif
DEBUG("transceiver: Send packet to %" PRIu16 "\n", p.dst);
switch (t) {
case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG
cc110x_pkt.length = p.length + CC1100_HEADER_LENGTH;
cc110x_pkt.address = p.dst;
cc110x_pkt.length = p->length + CC1100_HEADER_LENGTH;
cc110x_pkt.address = p->dst;
cc110x_pkt.flags = 0;
memcpy(cc110x_pkt.data, p.data, p.length);
memcpy(cc110x_pkt.data, p->data, p->length);
res = cc110x_send(&cc110x_pkt);
#elif MODULE_CC110X
memcpy(cc1100_pkt, p.data, p.length);
memcpy(cc1100_pkt, p->data, p->length);
res = cc1100_send_csmaca(p.dst, 4, 0, (char *) cc1100_pkt, p.length);
DEBUG("transceiver: snd_ret (%u) = %i\n", p.length, snd_ret);
res = cc1100_send_csmaca(p->dst, 4, 0, (char *) cc1100_pkt, p->length);
DEBUG("transceiver: snd_ret (%u) = %i\n", p->length, snd_ret);
#else
puts("Unknown transceiver");
#endif
break;
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
cc2420_pkt.frame.payload_len = p.length;
cc2420_pkt.frame.dest_addr[1] = (uint8_t)(p.dst >> 8);
cc2420_pkt.frame.dest_addr[0] = (uint8_t)(p.dst & 0xFF);
cc2420_pkt.frame.dest_pan_id = cc2420_get_pan();
cc2420_pkt.frame.fcf.dest_addr_m = 2;
cc2420_pkt.frame.fcf.src_addr_m = 2;
cc2420_pkt.frame.fcf.ack_req = 0;
cc2420_pkt.frame.fcf.sec_enb = 0;
cc2420_pkt.frame.fcf.frame_type = 1;
cc2420_pkt.frame.fcf.frame_pend = 0;
cc2420_pkt.frame.payload = p.data;
memcpy(&cc2420_pkt.frame, &p->frame, sizeof(ieee802154_frame_t));
cc2420_pkt.length = p->frame.payload_len + IEEE_802154_FCS_LEN;
res = cc2420_send(&cc2420_pkt);
break;
#endif
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
maca_pkt->length = p.length;
memcpy(maca_pkt->data, p.data, p.length);
maca_set_tx_packet( maca_pkt );
maca_pkt->length = p->length;
memcpy(maca_pkt->data, p->data, p->length);
maca_set_tx_packet(maca_pkt);
res = 1;
break;
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
res = nativenet_send(&p);
res = nativenet_send(p);
break;
#endif
#ifdef MODULE_AT86RF231
case TRANSCEIVER_AT86RF231:
at86rf231_pkt.frame.payload_len = p.length;
at86rf231_pkt.frame.dest_addr[1] = (uint8_t)(p.dst >> 8);
at86rf231_pkt.frame.dest_addr[0] = (uint8_t)(p.dst & 0xFF);
at86rf231_pkt.frame.dest_pan_id = at86rf231_get_pan();
at86rf231_pkt.frame.fcf.dest_addr_m = 2;
at86rf231_pkt.frame.fcf.src_addr_m = 2;
at86rf231_pkt.frame.fcf.ack_req = 0;
at86rf231_pkt.frame.fcf.sec_enb = 0;
at86rf231_pkt.frame.fcf.frame_type = 1;
at86rf231_pkt.frame.fcf.frame_pend = 0;
at86rf231_pkt.frame.payload = p.data;
memcpy(&at86rf231_pkt.frame, &p->frame, sizeof(ieee802154_frame_t));
at86rf231_pkt.length = p->frame.payload_len + IEEE_802154_FCS_LEN;
res = at86rf231_send(&at86rf231_pkt);
break;
#endif
default:
puts("Unknown transceiver");
break;
@ -686,7 +785,7 @@ static int32_t set_channel(transceiver_type_t t, void *channel)
{
uint8_t c = *((uint8_t *)channel);
switch(t) {
switch (t) {
case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG
return cc110x_set_channel(c);
@ -696,22 +795,27 @@ static int32_t set_channel(transceiver_type_t t, void *channel)
return -1;
#endif
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
return cc2420_set_channel(c);
#endif
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
maca_set_channel(c);
return c; ///< TODO: should be changed! implement get channel
return c; ///< TODO: should be changed!implement get channel
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
return nativenet_set_channel(c);
#endif
#ifdef MODULE_AT86RF231
case TRANSCEIVER_AT86RF231:
return at86rf231_set_channel(c);
#endif
default:
return -1;
}
@ -726,7 +830,7 @@ static int32_t set_channel(transceiver_type_t t, void *channel)
*/
static int32_t get_channel(transceiver_type_t t)
{
switch(t) {
switch (t) {
case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG
return cc110x_get_channel();
@ -736,22 +840,27 @@ static int32_t get_channel(transceiver_type_t t)
return -1;
#endif
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
return cc2420_get_channel();
#endif
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
///< TODO:implement return maca_get_channel();
return -1;
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
return nativenet_get_channel();
#endif
#ifdef MODULE_AT86RF231
case TRANSCEIVER_AT86RF231:
return at86rf231_get_channel();
#endif
default:
return -1;
}
@ -766,25 +875,32 @@ static int32_t get_channel(transceiver_type_t t)
*
* @return The pan AFTER calling the set command, -1 on error
*/
static int32_t set_pan(transceiver_type_t t, void *pan) {
uint16_t c = *((uint16_t*) pan);
static int32_t set_pan(transceiver_type_t t, void *pan)
{
uint16_t c = *((uint16_t *) pan);
switch (t) {
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
return cc2420_set_pan(c);
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
return nativenet_set_pan(c);
#endif
#ifdef MODULE_AT86RF231
case TRANSCEIVER_AT86RF231:
return at86rf231_set_pan(c);
#endif
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
return maca_set_pan(c);
#endif
default:
/* get rid of compiler warning about unused variable */
(void) c;
@ -799,24 +915,30 @@ static int32_t set_pan(transceiver_type_t t, void *pan) {
*
* @return The current pan of the transceiver, -1 on error
*/
static int32_t get_pan(transceiver_type_t t) {
static int32_t get_pan(transceiver_type_t t)
{
switch (t) {
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
return cc2420_get_pan();
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
return nativenet_get_pan();
#endif
#ifdef MODULE_AT86RF231
case TRANSCEIVER_AT86RF231:
return at86rf231_get_pan();
#endif
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
return maca_get_pan();
#endif
default:
return -1;
}
@ -833,7 +955,7 @@ static int32_t get_pan(transceiver_type_t t) {
*/
static radio_address_t get_address(transceiver_type_t t)
{
switch(t) {
switch (t) {
case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG
return cc110x_get_address();
@ -843,21 +965,26 @@ static radio_address_t get_address(transceiver_type_t t)
return 0; /* XXX see TODO above */
#endif
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
return cc2420_get_address();
#endif
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
return maca_get_address();
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
return nativenet_get_address();
#endif
#ifdef MODULE_AT86RF231
case TRANSCEIVER_AT86RF231:
return at86rf231_get_address();
#endif
default:
return 0; /* XXX see TODO above */
}
@ -877,7 +1004,7 @@ static radio_address_t set_address(transceiver_type_t t, void *address)
{
radio_address_t addr = *((radio_address_t *)address);
switch(t) {
switch (t) {
case TRANSCEIVER_CC1100:
#ifdef MODULE_CC110X_NG
return cc110x_set_address(addr);
@ -887,26 +1014,87 @@ static radio_address_t set_address(transceiver_type_t t, void *address)
return 0; /* XXX see TODO above */
#endif
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
return cc2420_set_address(addr);
#endif
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
return maca_set_address(addr);
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
return nativenet_set_address(addr);
#endif
#ifdef MODULE_AT86RF231
case TRANSCEIVER_AT86RF231:
return at86rf231_set_address(addr);
#endif
default:
return 0; /* XXX see TODO above */
}
}
/*
* @brief Get the current long address of transceiver device
*
* @param t The transceiver device
*
* @return The configured long address of the device, 0 on error
*/
static transceiver_eui64_t get_long_addr(transceiver_type_t t)
{
switch (t) {
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
return cc2420_get_address_long();
#endif
#ifdef MODULE_AT86RF231
case TRANSCEIVER_AT86RF231:
return at86rf231_get_address_long();
#endif
default:
return 0;
}
}
/*
* @brief Set the long address of the transceiver device
*
* @param t The transceiver device
* @param address Generic pointer to the long address to set
*
* @return The new long radio address of the device, 0 on error
*/
static transceiver_eui64_t set_long_addr(transceiver_type_t t, void *address)
{
uint64_t addr = *((uint64_t *)address);
switch (t) {
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
return cc2420_set_address_long(addr);
#endif
#ifdef MODULE_AT86RF231
case TRANSCEIVER_AT86RF231:
return at86rf231_set_address_long(addr);
#endif
default:
(void) addr;
return 0;
}
}
/*
* @brief Set the transceiver device into monitor mode (disabling address check)
*
@ -917,26 +1105,31 @@ static void set_monitor(transceiver_type_t t, void *mode)
{
(void) mode;
switch(t) {
switch (t) {
#ifdef MODULE_CC110X_NG
case TRANSCEIVER_CC1100:
cc110x_set_monitor(*((uint8_t *)mode));
break;
#endif
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
cc2420_set_monitor(*((uint8_t*) mode));
cc2420_set_monitor(*((uint8_t *) mode));
break;
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
nativenet_set_monitor(*((uint8_t*) mode));
nativenet_set_monitor(*((uint8_t *) mode));
break;
#endif
#ifdef MODULE_AT86RF231
case TRANSCEIVER_AT86RF231:
at86rf231_set_monitor(*((uint8_t*) mode));
at86rf231_set_monitor(*((uint8_t *) mode));
#endif
default:
break;
}
@ -957,22 +1150,26 @@ void cc1100_packet_monitor(void *payload, int payload_size, protocol_t protocol,
/*------------------------------------------------------------------------------------*/
static void powerdown(transceiver_type_t t)
{
switch(t) {
switch (t) {
#ifdef MODULE_CC110X_NG
case TRANSCEIVER_CC1100:
cc110x_switch_to_pwd();
break;
#endif
#ifdef MODULE_MC1322X
case TRANSCEIVER_MC1322X:
maca_off();
break;
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
nativenet_powerdown();
break;
#endif
default:
break;
}
@ -981,27 +1178,32 @@ static void powerdown(transceiver_type_t t)
/*------------------------------------------------------------------------------------*/
static void switch_to_rx(transceiver_type_t t)
{
switch(t) {
switch (t) {
#ifdef MODULE_CC110X_NG
case TRANSCEIVER_CC1100:
cc110x_switch_to_rx();
break;
#endif
#ifdef MODULE_CC2420
case TRANSCEIVER_CC2420:
cc2420_switch_to_rx();
break;
#endif
#ifdef MODULE_NATIVENET
case TRANSCEIVER_NATIVE:
nativenet_switch_to_rx();
break;
#endif
#ifdef MODULE_AT86RF231
case TRANSCEIVER_AT86RF231:
at86rf231_switch_to_rx();
#endif
default:
break;
}
@ -1020,6 +1222,7 @@ static int16_t ignore_add(transceiver_type_t transceiver, void *address)
return i;
}
}
return -1;
}
#endif

View File

@ -0,0 +1,32 @@
export PROJECT = test_net_if
BOARD_WHITELIST = native msba2 telosb
include ../Makefile.tests_common
ifeq ($(BOARD),stm32f4discovery)
include Makefile.$(BOARD)
endif
USEMODULE += auto_init
USEMODULE += net_if
ifeq ($(BOARD),native)
USEMODULE += nativenet
else ifeq ($(BOARD),msba2)
USEMODULE += cc110x_ng
else ifeq ($(BOARD),telosb)
USEMODULE += cc2420
else ifeq ($(BOARD),wsn430-v1_4)
USEMODULE += cc2420
else ifeq ($(BOARD),iot-lab_M3)
USEMODULE += at86rf231
endif
export INCLUDES += -I$(RIOTBASE)/sys/net/include
ifeq ($(BOARD),msba2)
export INCLUDES += -I$(RIOTBASE)/drivers/cc110x_ng/include \
-I$(RIOTBASE)/boards/msba2-common/include
endif
include $(RIOTBASE)/Makefile.include

470
tests/test_net_if/main.c Normal file
View File

@ -0,0 +1,470 @@
/*
* Copyright (C) 2013 Martin Lenders <mlenders@inf.fu-berlin.de>
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "net_if.h"
#include "net_help.h"
#include "transceiver.h"
#ifndef TRANSCEIVER
#ifdef MODULE_AT86RF231
#define TRANSCEIVER (TRANSCEIVER_AT86RF231)
#elif MODULE_CC110X_NG
#define TRANSCEIVER (TRANSCEIVER_CC1100)
#elif MODULE_NATIVENET
#define TRANSCEIVER (TRANSCEIVER_NATIVE)
#elif MODULE_CC2420
#define TRANSCEIVER (TRANSCEIVER_CC2420)
#endif
#endif
int initialize_tests(void);
int test_net_if_initialization(int iface);
int test_net_if_get_add_l3p_types(int iface);
int test_net_if_add_address(int iface, net_if_addr_t *addr1,
net_if_addr_t *addr2);
int test_net_if_del_address(int iface, net_if_addr_t *addr1,
net_if_addr_t *addr2);
int test_net_if_get_set_hardware_address(int iface, uint16_t addr);
int test_net_if_get_set_pan_id(int iface);
int test_net_if_get_set_eui64(int iface, net_if_eui64_t *eui64,
uint16_t addr);
int main(void)
{
int iface;
char *addr1_data = "abcdefgh", *addr2_data = "12345678";
net_if_addr_t addr1 = {
.addr_next = NULL,
.addr_prev = NULL,
.addr_protocol = NET_IF_L3P_IPV6_MULTICAST,
.addr_data = (void *)addr1_data,
.addr_len = (strlen(addr1_data) + 1) * 8
};
net_if_addr_t addr2 = {
.addr_next = NULL,
.addr_prev = NULL,
.addr_protocol = NET_IF_L3P_IPV6_PREFIX,
.addr_data = (void *)addr2_data,
.addr_len = (strlen(addr2_data) + 1) * 8
};
uint16_t own = 1, target = 2;
net_if_eui64_t eui64;
iface = initialize_tests();
if (!test_net_if_initialization(iface)) {
printf("FAILED: test_net_if_initialization()\n");
return -1;
}
if (!test_net_if_get_add_l3p_types(iface)) {
printf("FAILED: test_net_if_get_add_l3p_types()\n");
return -1;
}
if (!test_net_if_add_address(iface, &addr1, &addr2)) {
printf("FAILED: test_net_if_add_address()\n");
return -1;
}
if (!test_net_if_del_address(iface, &addr1, &addr2)) {
printf("FAILED: test_net_if_del_address()\n");
return -1;
}
if (!test_net_if_get_set_hardware_address(iface, own)) {
printf("FAILED: test_net_if_get_set_hardware_address()\n");
return -1;
}
if (!test_net_if_get_set_pan_id(iface)) {
printf("FAILED: test_net_if_get_set_pan_id()\n");
return -1;
}
if (!test_net_if_get_set_eui64(iface, &eui64, own)) {
printf("FAILED: test_net_if_get_set_eui64()\n");
return -1;
}
int count = net_if_send_packet(iface, target, "Test", 4);
printf("Count was %i after net_if_send_packet()\n", count);
printf("All test ran successfully.\n");
return 0;
}
int initialize_tests(void)
{
int iface;
#ifndef MODULE_AUTO_INIT
transceiver_init(TRANSCEIVER);
transceiver_start();
net_if_init();
iface = net_if_init_interface(0, TRANSCEIVER);
return iface;
#else
iface = -1;
while ((iface = net_if_iter_interfaces(iface)) >= 0) {
return iface;
}
return iface;
#endif
}
int test_net_if_initialization(int iface)
{
net_if_addr_t *addr_ptr = NULL;
if (net_if_get_l3p_types(iface)) {
printf("FAILED: No L3 type expected on interface %d.\n", iface);
return 0;
}
if (net_if_iter_addresses(iface + 1, &addr_ptr)) {
printf("FAILED: Expected error on interface '%d'\n", iface + 1);
return 0;
}
if (net_if_iter_addresses(iface, &addr_ptr)) {
printf("FAILED: Expected error on interface '%d'\n", iface);
return 0;
}
return 1;
}
int test_net_if_get_add_l3p_types(int iface)
{
if (net_if_add_l3p_types(iface + 1, NET_IF_L3P_IPV6_UNICAST)) {
printf("FAILED: expected net_if_add_l3p_types to fail for iface %d.\n",
iface + 1);
return 0;
}
if (!net_if_add_l3p_types(iface, 0)) {
printf("FAILED: expected net_if_add_l3p_types to succeed for iface %d and no type\n",
iface);
return 0;
}
if (!net_if_add_l3p_types(iface, NET_IF_L3P_IPV6_UNICAST)) {
printf("FAILED: expected net_if_add_l3p_types to succeed for iface %d and no type\n",
iface);
return 0;
}
if (!(net_if_get_l3p_types(iface) & NET_IF_L3P_IPV6_UNICAST)) {
printf("FAILED: L3 type IPv6 unicast expected on interface %d.\n", iface);
return 0;
}
if (net_if_get_l3p_types(iface) & ~NET_IF_L3P_IPV6_UNICAST) {
printf("FAILED: L3 type other than IPv6 unicast not expected on interface %d.\n",
iface);
return 0;
}
if (net_if_del_l3p_types(iface + 1, NET_IF_L3P_IPV6_UNICAST)) {
printf("FAILED: expected net_if_del_l3p_types to fail for iface %d.\n",
iface + 1);
return 0;
}
if (!net_if_del_l3p_types(iface, 0)) {
printf("FAILED: expected net_if_del_l3p_types to succeed for iface %d and no type\n",
iface);
return 0;
}
if (!net_if_del_l3p_types(iface, NET_IF_L3P_IPV6_UNICAST)) {
printf("FAILED: expected net_if_del_l3p_types to succeed for iface %d and no type\n",
iface);
return 0;
}
if (net_if_get_l3p_types(iface)) {
printf("FAILED: No L3 type expected on interface %d.\n", iface);
return 0;
}
return 1;
}
int test_net_if_add_address(int iface, net_if_addr_t *addr1,
net_if_addr_t *addr2)
{
int count = 0;
net_if_addr_t *addr_ptr = NULL;
if (net_if_add_address(iface + 1, addr1)) {
printf("FAILED: expected net_if_add_address(%d, %p) to fail.\n",
iface + 1, (void *)addr1);
return 0;
}
if (net_if_add_address(iface, NULL)) {
printf("FAILED: expected net_if_add_address(%d, NULL) to fail.\n",
iface);
return 0;
}
if (!net_if_add_address(iface, addr1)) {
printf("FAILED: Address addition failed\n");
return 0;
}
if (!(net_if_get_l3p_types(iface) & NET_IF_L3P_IPV6_MULTICAST)) {
printf("FAILED: L3 type IPv6 multicast expected on interface %d.\n", iface);
return 0;
}
if (net_if_get_l3p_types(iface) & ~NET_IF_L3P_IPV6_MULTICAST) {
printf("FAILED: L3 type other than IPv6 multicast not expected on interface %d.\n",
iface);
return 0;
}
if (!net_if_add_address(iface, addr2)) {
printf("FAILED: Address addition failed\n");
return 0;
}
if (!(net_if_get_l3p_types(iface) & NET_IF_L3P_IPV6_MULTICAST)) {
printf("FAILED: L3 type IPv6 multcast expected on interface %d.\n", iface);
return 0;
}
if (!(net_if_get_l3p_types(iface) & NET_IF_L3P_IPV6_PREFIX)) {
printf("FAILED: L3 type IPv6 prefix expected on interface %d.\n", iface);
return 0;
}
if (net_if_get_l3p_types(iface) & ~(NET_IF_L3P_IPV6_MULTICAST | NET_IF_L3P_IPV6_PREFIX)) {
printf("FAILED: L3 type other than IPv6 multicast and IPv6 prefix not expected on interface %d.\n",
iface);
return 0;
}
while (net_if_iter_addresses(iface, &addr_ptr)) {
if (addr_ptr == addr1 || addr_ptr == addr2) {
count++;
}
}
if (count != 2) {
printf("FAILED: expected 2 addresses in iface's address list once respectively\n");
printf(" missing '%d'\n", 2 - count);
return 0;
}
return 1;
}
int test_net_if_del_address(int iface, net_if_addr_t *addr1,
net_if_addr_t *addr2)
{
int count = 0;
net_if_addr_t *addr_ptr = NULL;
if (net_if_del_address(iface + 1, addr1)) {
printf("FAILED: expected net_if_del_address(%d, %p) to fail.\n",
iface + 1, (void *)addr1);
return 0;
}
if (net_if_del_address(iface, NULL)) {
printf("FAILED: expected net_if_del_address(%d, NULL) to fail.\n",
iface);
return 0;
}
if (!net_if_del_address(iface, addr1)) {
printf("FAILED: Address deletion failed\n");
return 0;
}
while (net_if_iter_addresses(iface, &addr_ptr)) {
if (addr_ptr == addr1 || addr_ptr == addr2) {
count++;
}
}
if (count != 1) {
printf("FAILED: expected 1 address in iface's address list\n");
printf(" missing '%d'\n", 1 - count);
return 0;
}
return 1;
}
int test_net_if_get_set_hardware_address(int iface, uint16_t addr)
{
uint16_t tmp;
if (net_if_set_hardware_address(iface + 1, addr)) {
printf("FAILED: expected net_if_set_hardware_address(%d, %d) to fail.\n",
iface + 1, addr);
return 0;
}
if (net_if_set_hardware_address(iface, 0)) {
printf("FAILED: expected net_if_set_hardware_address(%d, 0) to fail.\n",
iface);
return 0;
}
tmp = net_if_set_hardware_address(iface, addr);
if (addr != tmp) {
printf("FAILED: Expected '%d' as result of net_if_set_hardware_addr() "
"(was '%d')\n", addr, tmp);
return 0;
}
tmp = net_if_get_hardware_address(iface);
if (addr != tmp) {
printf("FAILED: Expected '%d' as result of net_if_get_hardware_addr() "
"(was '%d')\n", addr, tmp);
return 0;
}
return 1;
}
int test_net_if_get_set_pan_id(int iface)
{
int32_t res;
uint16_t pan_id = 0xabcd;
if ((res = net_if_get_pan_id(iface + 1)) >= 0) {
printf("FAILED: net_if_get_pan_id(%d) not failed\n", iface);
return 0;
}
if ((res = net_if_set_pan_id(iface, pan_id)) < 0) {
printf("FAILED: net_if_set_pan_id(%d, 0x%04x) failed\n", iface, pan_id);
return 0;
}
#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X
if ((res = net_if_get_pan_id(iface)) < 0) {
printf("FAILED: net_if_get_pan_id(%d) failed\n", iface);
return 0;
}
pan_id = (uint16_t)res;
#else
pan_id = 0;
#endif
return 1;
}
int test_net_if_get_set_eui64(int iface, net_if_eui64_t *eui64,
uint16_t addr)
{
uint16_t pan_id;
#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X
int32_t res;
if ((res = net_if_get_pan_id(iface)) < 0) {
printf("FAILED: net_if_get_pan_id(%d) failed\n", iface);
return 0;
}
pan_id = (uint16_t)res;
#else
pan_id = 0;
#endif
if (net_if_get_eui64(NULL, iface, 1)) {
printf("FAILED: expected net_if_get_eui64(NULL, %d, 1) to fail\n",
iface);
return 0;
}
if (!net_if_get_eui64(eui64, iface, 1)) {
printf("FAILED: Error getting EUI-64 on interface %d\n", iface);
return 0;
}
if (eui64->uint16[0] != HTONS(pan_id) || eui64->uint8[2] != 0 ||
eui64->uint8[3] != 0xff || eui64->uint8[4] != 0xfe ||
eui64->uint8[5] != 0 || (uint16_t)eui64->uint16[3] != HTONS(addr)) {
printf("FAILED: Expected last 16 bit of EUI-64 to be 0x%04x (is 0x%04x)\n",
addr, NTOHS(eui64->uint16[3]));
return 0;
}
eui64->uint64 = 0;
if (net_if_set_eui64(iface, NULL)) {
printf("FAILED: expected error on net_if_set_eui64(%d, NULL)\n", iface);
return 0;
}
if (net_if_set_eui64(iface, eui64)) {
printf("FAILED: expected error trying to set EUI-64 to broadcast\n");
return 0;
}
#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X
eui64->uint8[0] = 0x11;
eui64->uint8[1] = 0x22;
eui64->uint8[2] = 0x33;
eui64->uint8[3] = 0x44;
eui64->uint8[4] = 0x55;
eui64->uint8[5] = 0x66;
eui64->uint8[6] = 0x77;
eui64->uint8[7] = 0x88;
if (!net_if_set_eui64(iface, eui64)) {
printf("FAILED: Error setting EUI-64 on interface %d\n", iface);
return 0;
}
eui64->uint64 = 0;
if (!net_if_get_eui64(eui64, iface, 0)) {
printf("FAILED: Error getting EUI-64 on interface %d\n", iface);
return 0;
}
/* transceivers that do not support EUI-64 addresses convert automatically
* so we have to test both cases */
if (eui64->uint8[0] != 0x11 || eui64->uint8[1] != 0x22 ||
eui64->uint8[2] != 0x33 || eui64->uint8[3] != 0x44 ||
eui64->uint8[4] != 0x55 || eui64->uint8[5] != 0x66 ||
eui64->uint8[6] != 0x77 || eui64->uint8[7] != 0x88) {
printf("FAILED: EUI-64 to be 11-22-33-44-55-66-77-88 but is "
"%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n",
eui64->uint8[0], eui64->uint8[1], eui64->uint8[2],
eui64->uint8[3], eui64->uint8[4], eui64->uint8[5],
eui64->uint8[6], eui64->uint8[7]);
return 0;
}
#endif
return 1;
}