1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #170 from LudwigOrtmann/nativenet_cleanup_and_srcaddr

clean up nativenet, add src addr
This commit is contained in:
Oleg Hahm 2013-08-29 07:31:57 -07:00
commit 53557a591e
8 changed files with 209 additions and 40 deletions

View File

@ -1,3 +1,26 @@
/**
* nativenet transceiver interface
*
* A configurable transceiver for the native port.
*
* At the moment only the tap interface is supported, but more network
* layers are intended. So the "configurable" part is a lie for now ;-)
* The effect of calls like nativenet_set_channel depend on the
* network layer.
*
* Copyright (C) 2013 Ludwig Ortmann
*
* 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.
*/
/**
* @defgroup native_net
* @{
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
*/
#ifndef NATIVENET_H #ifndef NATIVENET_H
#define NATIVENET_H #define NATIVENET_H
@ -7,27 +30,87 @@
#define TRANSCEIVER_BUFFER_SIZE (3) #define TRANSCEIVER_BUFFER_SIZE (3)
#ifndef NATIVE_MAX_DATA_LENGTH #ifndef NATIVE_MAX_DATA_LENGTH
/* TODO: set this properly: */ #include "tap.h"
#define NATIVE_MAX_DATA_LENGTH (ETHER_MAX_LEN - (ETHER_HDR_LEN+2)) #define NATIVE_MAX_DATA_LENGTH (TAP_MAX_DATA)
#else #else
#warning be careful not to exceed (ETHER_MAX_LEN) with NATIVE_MAX_DATA_LENGTH #warning be careful not to exceed (TAP_MAX_DATA) with NATIVE_MAX_DATA_LENGTH
#endif /* NATIVE_MAX_DATA_LENGTH */ #endif /* NATIVE_MAX_DATA_LENGTH */
/**
* Initialize transceiver
*
* @param transceiver_pid the pid of the transceiver thread
*/
void nativenet_init(int transceiver_pid); void nativenet_init(int transceiver_pid);
/**
* Shutdown transceiver
*/
void nativenet_powerdown(); void nativenet_powerdown();
/**
* Enable/disable monitor mode
*
* @param mode 0 off, 1 on
*/
void nativenet_set_monitor(uint8_t mode); void nativenet_set_monitor(uint8_t mode);
/**
* Send a packet
*
* @param packet a radio packet
* @return 1 on success, 0 otherwise
*/
uint8_t nativenet_send(radio_packet_t *packet); uint8_t nativenet_send(radio_packet_t *packet);
int16_t nativenet_set_address(radio_address_t address); /**
int16_t nativenet_get_address(); * Set transceiver address
*
* @param address the address
* @return the address
*/
radio_address_t nativenet_set_address(radio_address_t address);
/**
* Get transceiver address
*
* @return the address
*/
radio_address_t nativenet_get_address();
/**
* Set transceiver channel
*
* @param channel the channel
* @return the channel
*/
int16_t nativenet_set_channel(uint8_t channel); int16_t nativenet_set_channel(uint8_t channel);
/**
* Get transceiver channel
*
* @return the channel
*/
int16_t nativenet_get_channel(); int16_t nativenet_get_channel();
/**
* Set transceiver pan
*
* @param channel the pan
* @return the pan
*/
uint16_t nativenet_set_pan(uint16_t pan); uint16_t nativenet_set_pan(uint16_t pan);
/**
* Get transceiver pan
*
* @return the pan
*/
uint16_t nativenet_get_pan(); uint16_t nativenet_get_pan();
/**
* Enable transceiver rx mode
*/
void nativenet_switch_to_rx(); void nativenet_switch_to_rx();
/** @} */
#endif /* NATIVENET_H */ #endif /* NATIVENET_H */

View File

@ -1,3 +1,19 @@
/**
* internal nativenet transceiver interface
*
* Copyright (C) 2013 Ludwig Ortmann
*
* 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.
*/
/**
* @{
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
* @}
*/
#ifndef NATIVENET_INTERNAL_H #ifndef NATIVENET_INTERNAL_H
#define NATIVENET_INTERNAL_H #define NATIVENET_INTERNAL_H

View File

@ -1,3 +1,18 @@
/**
* internal nativenet tap network layer interface
*
* Copyright (C) 2013 Ludwig Ortmann
*
* 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.
*/
/**
* @{
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
* @}
*/
#ifndef _TAP_H #ifndef _TAP_H
#define _TAP_H #define _TAP_H
@ -11,6 +26,8 @@
* if "name" is an empty string, the kernel chooses a name * if "name" is an empty string, the kernel chooses a name
* if "name" is an existing device, that device is used * if "name" is an existing device, that device is used
* otherwise a device named "name" is created * otherwise a device named "name" is created
*
* On OSX a name has to be provided.
*/ */
int tap_init(char *name); int tap_init(char *name);
int send_buf(radio_packet_t *packet); int send_buf(radio_packet_t *packet);
@ -18,12 +35,24 @@ int send_buf(radio_packet_t *packet);
extern int _native_tap_fd; extern int _native_tap_fd;
extern unsigned char _native_tap_mac[ETHER_ADDR_LEN]; extern unsigned char _native_tap_mac[ETHER_ADDR_LEN];
struct nativenet_header {
uint16_t length;
radio_address_t dst;
radio_address_t src;
} __attribute__((packed));
#define TAP_MAX_DATA ((ETHERMTU) - 6) /* XXX: this is suboptimal */
struct nativenet_packet {
struct nativenet_header nn_header;
unsigned char data[ETHERMTU - sizeof(struct nativenet_header)];
} __attribute__((packed));
union eth_frame { union eth_frame {
struct { struct {
struct ether_header header; struct ether_header header;
unsigned char data[ETHERMTU]; struct nativenet_packet payload;
} field; } field;
unsigned char buffer[ETHER_MAX_LEN]; unsigned char buffer[ETHER_MAX_LEN];
}; } __attribute__((packed));
#endif /* _TAP_H */ #endif /* _TAP_H */

View File

@ -1,9 +1,26 @@
/**
* nativenet.h implementation
*
* Copyright (C) 2013 Ludwig Ortmann
*
* 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.
*
* @ingroup native_cpu
* @ingroup net
* @{
* @file
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
*/
#include <stdio.h> #include <stdio.h>
#include <err.h> #include <err.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <inttypes.h>
#include <arpa/inet.h> #include <arpa/inet.h>
@ -76,25 +93,27 @@ uint16_t nativenet_get_pan()
return _native_net_pan; return _native_net_pan;
} }
int16_t nativenet_set_address(radio_address_t address) radio_address_t nativenet_set_address(radio_address_t address)
{ {
_native_net_addr = address; _native_net_addr = address;
return _native_net_addr; return _native_net_addr;
} }
int16_t nativenet_get_address() radio_address_t nativenet_get_address()
{ {
return _native_net_addr; return _native_net_addr;
} }
uint8_t nativenet_send(radio_packet_t *packet) uint8_t nativenet_send(radio_packet_t *packet)
{ {
DEBUG("nativenet_send: Sending packet of length %u to %u: %s\n", packet->length, packet->dst, (char*) packet->data); packet->src = _native_net_addr;
DEBUG("nativenet_send: Sending packet of length %"PRIu16" from %"PRIu16" to %"PRIu16": %s\n", packet->length, packet->src, packet->dst, (char*) packet->data);
if (send_buf(packet) == -1) { if (send_buf(packet) == -1) {
warnx("nativenet_send: error sending packet"); warnx("nativenet_send: error sending packet");
}
return 0; return 0;
}
return true;
} }
void nativenet_switch_to_rx() void nativenet_switch_to_rx()
@ -142,7 +161,7 @@ void do_cb(int event)
void _nativenet_handle_packet(radio_packet_t *packet) void _nativenet_handle_packet(radio_packet_t *packet)
{ {
uint8_t dst_addr = packet->dst; radio_address_t dst_addr = packet->dst;
/* address filter / monitor mode */ /* address filter / monitor mode */
if (_native_net_monitor == 1) { if (_native_net_monitor == 1) {
@ -182,5 +201,5 @@ void _nativenet_handle_packet(radio_packet_t *packet)
if (++rx_buffer_next == RX_BUF_SIZE) { if (++rx_buffer_next == RX_BUF_SIZE) {
rx_buffer_next = 0; rx_buffer_next = 0;
} }
} }
/** @} */

View File

@ -1,3 +1,18 @@
/**
* tap.h implementation
*
* Copyright (C) 2013 Ludwig Ortmann
*
* 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.
*
* @ingroup native_cpu
* @{
* @file
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -7,6 +22,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <fcntl.h> #include <fcntl.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <inttypes.h>
#ifdef __MACH__ #ifdef __MACH__
#define _POSIX_C_SOURCE #define _POSIX_C_SOURCE
@ -38,8 +54,7 @@ unsigned char _native_tap_mac[ETHER_ADDR_LEN];
void _native_handle_tap_input(void) void _native_handle_tap_input(void)
{ {
int nread; int nread;
unsigned char buf[TAP_BUFFER_LENGTH]; union eth_frame frame;
union eth_frame *f;
radio_packet_t p; radio_packet_t p;
DEBUG("_native_handle_tap_input\n"); DEBUG("_native_handle_tap_input\n");
@ -48,22 +63,22 @@ void _native_handle_tap_input(void)
TODO: refactor this into general io-signal multiplexer */ TODO: refactor this into general io-signal multiplexer */
_native_in_syscall = 1; _native_in_syscall = 1;
nread = read(_native_tap_fd, buf, TAP_BUFFER_LENGTH); nread = read(_native_tap_fd, &frame, sizeof(union eth_frame));
_native_in_syscall = 0; _native_in_syscall = 0;
DEBUG("_native_handle_tap_input - read %d bytes\n", nread); DEBUG("_native_handle_tap_input - read %d bytes\n", nread);
if (nread > 0) { if (nread > 0) {
f = (union eth_frame*)&buf; if (ntohs(frame.field.header.ether_type) == NATIVE_ETH_PROTO) {
if (ntohs(f->field.header.ether_type) == NATIVE_ETH_PROTO) {
nread = nread - ETHER_HDR_LEN; nread = nread - ETHER_HDR_LEN;
if ((nread - 1) <= 0) { if ((nread - 1) <= 0) {
DEBUG("_native_handle_tap_input: no payload"); DEBUG("_native_handle_tap_input: no payload");
} }
else { else {
/* XXX: check overflow */ /* XXX: check overflow */
p.length = (uint8_t)buf[ETHER_HDR_LEN]; p.length = ntohs(frame.field.payload.nn_header.length);
p.dst = (uint8_t)buf[ETHER_HDR_LEN+1]; p.dst = ntohs(frame.field.payload.nn_header.dst);
p.data = buf+ETHER_HDR_LEN+2; p.src = ntohs(frame.field.payload.nn_header.src);
DEBUG("_native_handle_tap_input: received packet of length %u for %u: %s\n", p.length, p.dst, (char*) p.data); p.data = frame.field.payload.data;
DEBUG("_native_handle_tap_input: received packet of length %"PRIu16" for %"PRIu16" from %"PRIu16": %s\n", p.length, p.dst, p.src, (char*) p.data);
_nativenet_handle_packet(&p); _nativenet_handle_packet(&p);
} }
} }
@ -93,10 +108,12 @@ int _native_marshall_ethernet(uint8_t *framebuf, radio_packet_t *packet)
f->field.header.ether_type = htons(NATIVE_ETH_PROTO); f->field.header.ether_type = htons(NATIVE_ETH_PROTO);
/* XXX: check overflow */ /* XXX: check overflow */
memcpy(f->field.data+2, packet->data, packet->length); memcpy(f->field.payload.data, packet->data, packet->length);
f->field.data[0] = packet->length; f->field.payload.nn_header.length = htons(packet->length);
f->field.data[1] = packet->dst; f->field.payload.nn_header.dst = htons(packet->dst);
data_len = packet->length + 2; f->field.payload.nn_header.src = htons(packet->src);
data_len = packet->length + sizeof(struct nativenet_header);
return data_len; return data_len;
} }
@ -106,12 +123,12 @@ int send_buf(radio_packet_t *packet)
uint8_t buf[TAP_BUFFER_LENGTH]; uint8_t buf[TAP_BUFFER_LENGTH];
int nsent, to_send; int nsent, to_send;
DEBUG("send_buf: Sending packet of length %u to %u: %s\n", packet->length, packet->dst, (char*) packet->data); DEBUG("send_buf: Sending packet of length %"PRIu16" from %"PRIu16" to %"PRIu16": %s\n", packet->length, packet->src, packet->dst, (char*) packet->data);
to_send = _native_marshall_ethernet(buf, packet); to_send = _native_marshall_ethernet(buf, packet);
if ((ETHER_HDR_LEN + to_send) < ETHERMIN) { if ((ETHER_HDR_LEN + to_send) < ETHERMIN) {
DEBUG("padding data! (%d ->", to_send); DEBUG("padding data! (%d ->", to_send);
to_send = ETHERMIN - ETHER_HDR_LEN; to_send = ETHERMIN - (ETHER_HDR_LEN + sizeof(struct nativenet_header));
DEBUG("%d)\n", to_send); DEBUG("%d)\n", to_send);
} }
@ -201,3 +218,4 @@ int tap_init(char *name)
puts("RIOT native tap initialized."); puts("RIOT native tap initialized.");
return _native_tap_fd; return _native_tap_fd;
} }
/** @} */

View File

@ -24,11 +24,13 @@ if [ "${COMMAND}" = 'create' ]; then
COUNT="${DEFCOUNT}" COUNT="${DEFCOUNT}"
fi fi
echo "creating ${BRNAME} ..."
sudo brctl addbr ${BRNAME} || exit 1 sudo brctl addbr ${BRNAME} || exit 1
sudo -s sh -c "echo 1 > /proc/sys/net/ipv6/conf/${BRNAME}/disable_ipv6" || exit 1 sudo -s sh -c "echo 1 > /proc/sys/net/ipv6/conf/${BRNAME}/disable_ipv6" || exit 1
sudo ip link set ${BRNAME} up || exit 1 sudo ip link set ${BRNAME} up || exit 1
for N in $(seq 0 "$((COUNT - 1))"); do for N in $(seq 0 "$((COUNT - 1))"); do
echo "creating tap${N} ..."
sudo ip tuntap add dev tap${N} mode tap user ${USER} || exit 1 sudo ip tuntap add dev tap${N} mode tap user ${USER} || exit 1
sudo -s sh -c "echo 1 > /proc/sys/net/ipv6/conf/tap${N}/disable_ipv6" || exit 1 sudo -s sh -c "echo 1 > /proc/sys/net/ipv6/conf/tap${N}/disable_ipv6" || exit 1
sudo brctl addif ${BRNAME} tap${N} || exit 1 sudo brctl addif ${BRNAME} tap${N} || exit 1
@ -37,8 +39,10 @@ if [ "${COMMAND}" = 'create' ]; then
elif [ "${COMMAND}" = 'delete' ]; then elif [ "${COMMAND}" = 'delete' ]; then
for IF in $(ls /sys/class/net/${BRNAME}/brif); do for IF in $(ls /sys/class/net/${BRNAME}/brif); do
echo "deleting ${IF} ..."
sudo ip link delete "${IF}" sudo ip link delete "${IF}"
done done
echo "deleting ${BRNAME} ..."
sudo ip link set ${BRNAME} down sudo ip link set ${BRNAME} down
sudo brctl delbr ${BRNAME} sudo brctl delbr ${BRNAME}

View File

@ -32,15 +32,15 @@ transceiver_command_t tcmd;
void _nativenet_get_set_address_handler(char *addr) void _nativenet_get_set_address_handler(char *addr)
{ {
int16_t a; uint16_t a;
tcmd.transceivers = TRANSCEIVER_NATIVE; tcmd.transceivers = TRANSCEIVER_NATIVE;
tcmd.data = &a; tcmd.data = &a;
mesg.content.ptr = (char *) &tcmd; mesg.content.ptr = (char *) &tcmd;
a = (int16_t)atoi(addr + 5); a = atoi(addr + 5);
if (strlen(addr) > 5) { if (strlen(addr) > 5) {
printf("[nativenet] trying to set address %" PRIi16 "\n", a); printf("[nativenet] trying to set address %"PRIu16"\n", a);
mesg.type = SET_ADDRESS; mesg.type = SET_ADDRESS;
} }
else { else {
@ -48,12 +48,12 @@ void _nativenet_get_set_address_handler(char *addr)
} }
msg_send_receive(&mesg, &mesg, transceiver_pid); msg_send_receive(&mesg, &mesg, transceiver_pid);
printf("[nativenet] got address: %i\n", a); printf("[nativenet] got address: %"PRIu16"\n", a);
} }
void _nativenet_get_set_channel_handler(char *chan) void _nativenet_get_set_channel_handler(char *chan)
{ {
int16_t c; uint8_t c;
tcmd.transceivers = TRANSCEIVER_NATIVE; tcmd.transceivers = TRANSCEIVER_NATIVE;
tcmd.data = &c; tcmd.data = &c;
@ -61,7 +61,7 @@ void _nativenet_get_set_channel_handler(char *chan)
c = atoi(chan + 5); c = atoi(chan + 5);
if (strlen(chan) > 5) { if (strlen(chan) > 5) {
printf("[nativenet] Trying to set channel %i\n", c); printf("[nativenet] Trying to set channel %"PRIu8"\n", c);
mesg.type = SET_CHANNEL; mesg.type = SET_CHANNEL;
} }
else { else {
@ -69,7 +69,7 @@ void _nativenet_get_set_channel_handler(char *chan)
} }
msg_send_receive(&mesg, &mesg, transceiver_pid); msg_send_receive(&mesg, &mesg, transceiver_pid);
printf("[nativenet] Got channel: %i\n", c); printf("[nativenet] Got channel: %"PRIu8"\n", c);
} }
void _nativenet_send_handler(char *pkt) void _nativenet_send_handler(char *pkt)
@ -96,10 +96,10 @@ void _nativenet_send_handler(char *pkt)
p.dst = addr; p.dst = addr;
mesg.type = SND_PKT; mesg.type = SND_PKT;
mesg.content.ptr = (char *)&tcmd; mesg.content.ptr = (char *)&tcmd;
printf("[nativenet] Sending packet of length %u to %u: %s\n", p.length, p.dst, (char*) p.data); printf("[nativenet] Sending packet of length %"PRIu16" to %"PRIu16": %s\n", p.length, p.dst, (char*) p.data);
msg_send_receive(&mesg, &mesg, transceiver_pid); msg_send_receive(&mesg, &mesg, transceiver_pid);
response = mesg.content.value; response = mesg.content.value;
printf("[nativenet] Packet sent: %" PRIu32 "\n", response); printf("[nativenet] Packet sent: %"PRIu32"\n", response);
return; return;
} }
} }
@ -109,7 +109,7 @@ void _nativenet_send_handler(char *pkt)
void _nativenet_monitor_handler(char *mode) void _nativenet_monitor_handler(char *mode)
{ {
unsigned int m; uint8_t m;
tcmd.transceivers = TRANSCEIVER_NATIVE; tcmd.transceivers = TRANSCEIVER_NATIVE;
tcmd.data = &m; tcmd.data = &m;
@ -117,7 +117,7 @@ void _nativenet_monitor_handler(char *mode)
m = atoi(mode + 8); m = atoi(mode + 8);
if (strlen(mode) > 8) { if (strlen(mode) > 8) {
printf("Setting monitor mode: %u\n", m); printf("Setting monitor mode: %"PRIu8"\n", m);
mesg.type = SET_MONITOR; mesg.type = SET_MONITOR;
msg_send(&mesg, transceiver_pid, 1); msg_send(&mesg, transceiver_pid, 1);
} }

View File

@ -532,7 +532,7 @@ void receive_nativenet_packet(radio_packet_t *trans_p) {
memcpy((void*) &(data_buffer[transceiver_buffer_pos * PAYLOAD_SIZE]), p->data, p->length); memcpy((void*) &(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 %hu to %hu, size: %u\n", trans_p, trans_p->src, trans_p->dst, trans_p->length); DEBUG("Packet %p was from %"PRIu16" to %"PRIu16", size: %"PRIu8"\n", trans_p, trans_p->src, trans_p->dst, trans_p->length);
/* reset interrupts */ /* reset interrupts */
restoreIRQ(state); restoreIRQ(state);