From 333c49a344b807cb27f15afd1b8da0e195153481 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 6 Aug 2014 22:09:18 +0200 Subject: [PATCH 1/3] nativenet: Apply coding conventions --- cpu/native/net/interface.c | 6 ++-- cpu/native/net/tap.c | 60 +++++++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/cpu/native/net/interface.c b/cpu/native/net/interface.c index ddffc53141ea..d2c9741a3945 100644 --- a/cpu/native/net/interface.c +++ b/cpu/native/net/interface.c @@ -126,7 +126,8 @@ uint64_t nativenet_set_address_long(uint64_t address) int8_t nativenet_send(radio_packet_t *packet) { packet->src = _native_net_addr; - DEBUG("nativenet_send: Sending packet of length %" PRIu16 " from %" PRIu16 " to %" PRIu16 "\n", packet->length, packet->src, packet->dst); + DEBUG("nativenet_send: Sending packet of length %" PRIu16 " from %" PRIu16 " to %" PRIu16 "\n", + packet->length, packet->src, packet->dst); return send_buf(packet); } @@ -200,7 +201,8 @@ void _nativenet_handle_packet(radio_packet_t *packet) DEBUG("\n\t\trx_buffer_next: %i\n\n", rx_buffer_next); memcpy(&_nativenet_rx_buffer[rx_buffer_next].data, packet->data, packet->length); memcpy(&_nativenet_rx_buffer[rx_buffer_next].packet, packet, sizeof(radio_packet_t)); - _nativenet_rx_buffer[rx_buffer_next].packet.data = (uint8_t *) &_nativenet_rx_buffer[rx_buffer_next].data; + _nativenet_rx_buffer[rx_buffer_next].packet.data = (uint8_t *) + &_nativenet_rx_buffer[rx_buffer_next].data; /* notify transceiver thread if any */ if (_native_net_tpid != KERNEL_PID_UNDEF) { diff --git a/cpu/native/net/tap.c b/cpu/native/net/tap.c index cd24124bdd5f..abf91b1fd871 100644 --- a/cpu/native/net/tap.c +++ b/cpu/native/net/tap.c @@ -80,9 +80,11 @@ void _native_handle_tap_input(void) nread = real_read(_native_tap_fd, &frame, sizeof(union eth_frame)); DEBUG("_native_handle_tap_input - read %d bytes\n", nread); + if (nread > 0) { if (ntohs(frame.field.header.ether_type) == NATIVE_ETH_PROTO) { nread = nread - ETHER_HDR_LEN; + if ((nread - 1) <= 0) { DEBUG("_native_handle_tap_input: no payload\n"); } @@ -93,16 +95,18 @@ void _native_handle_tap_input(void) p.dst = ntohs(frame.field.payload.nn_header.dst); p.rssi = 0; p.lqi = 0; - p.toa.seconds = HWTIMER_TICKS_TO_US(t)/1000000; - p.toa.microseconds = HWTIMER_TICKS_TO_US(t)%1000000; + p.toa.seconds = HWTIMER_TICKS_TO_US(t) / 1000000; + p.toa.microseconds = HWTIMER_TICKS_TO_US(t) % 1000000; /* XXX: check overflow */ p.length = ntohs(frame.field.payload.nn_header.length); p.data = frame.field.payload.data; + if (p.length > (nread - sizeof(struct nativenet_header))) { warnx("_native_handle_tap_input: packet with malicious length field received, discarding"); } else { - DEBUG("_native_handle_tap_input: received packet of length %" PRIu16 " for %" PRIu16 " from %" PRIu16 "\n", p.length, p.dst, p.src); + DEBUG("_native_handle_tap_input: received packet of length %" PRIu16 " for %" PRIu16 " from %" + PRIu16 "\n", p.length, p.dst, p.src); _nativenet_handle_packet(&p); } } @@ -119,10 +123,11 @@ void _native_handle_tap_input(void) FD_SET(_native_tap_fd, &rfds); _native_in_syscall++; // no switching here - if (select(_native_tap_fd +1, &rfds, NULL, NULL, &t) == 1) { + + if (select(_native_tap_fd + 1, &rfds, NULL, NULL, &t) == 1) { int sig = SIGIO; extern int _sig_pipefd[2]; - extern ssize_t (*real_write)(int fd, const void *buf, size_t count); + extern ssize_t (*real_write)(int fd, const void * buf, size_t count); real_write(_sig_pipefd[1], &sig, sizeof(int)); _native_sigpend++; DEBUG("_native_handle_tap_input: sigpend++\n"); @@ -133,10 +138,11 @@ void _native_handle_tap_input(void) kill(sigio_child_pid, SIGCONT); #endif } + _native_in_syscall--; } else if (nread == -1) { - if ((errno == EAGAIN ) || (errno == EWOULDBLOCK)) { + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { //warn("read"); } else { @@ -166,16 +172,19 @@ void sigio_child(void) * available */ fd_set rfds; + while (1) { FD_ZERO(&rfds); FD_SET(_native_tap_fd, &rfds); - if (select(_native_tap_fd +1, &rfds, NULL, NULL, NULL) == 1) { + + if (select(_native_tap_fd + 1, &rfds, NULL, NULL, NULL) == 1) { kill(parent, SIGIO); } else { kill(parent, SIGKILL); err(EXIT_FAILURE, "osx_sigio_child: select"); } + pause(); } } @@ -187,7 +196,7 @@ int _native_marshall_ethernet(uint8_t *framebuf, radio_packet_t *packet) union eth_frame *f; unsigned char addr[ETHER_ADDR_LEN]; - f = (union eth_frame*)framebuf; + f = (union eth_frame *)framebuf; addr[0] = addr[1] = addr[2] = addr[3] = addr[4] = addr[5] = 0xFF; memcpy(f->field.header.ether_dhost, addr, ETHER_ADDR_LEN); @@ -206,7 +215,7 @@ int _native_marshall_ethernet(uint8_t *framebuf, radio_packet_t *packet) * Linux does this on its own, but it doesn't hurt to do it here. * As of now only tuntaposx needs this. */ if (data_len < ETHERMIN) { - DEBUG("padding data! (%d -> ", data_len); + DEBUG("padding data!(%d -> ", data_len); data_len = ETHERMIN; DEBUG("%d)\n", data_len); } @@ -221,15 +230,17 @@ int8_t send_buf(radio_packet_t *packet) memset(buf, 0, sizeof(buf)); - DEBUG("send_buf: Sending packet of length %" PRIu16 " from %" PRIu16 " to %" PRIu16 "\n", packet->length, packet->src, packet->dst); + DEBUG("send_buf: Sending packet of length %" PRIu16 " from %" PRIu16 " to %" PRIu16 "\n", + packet->length, packet->src, packet->dst); to_send = _native_marshall_ethernet(buf, packet); DEBUG("send_buf: trying to send %d bytes\n", to_send); - if ((nsent = _native_write(_native_tap_fd, buf, to_send)) == -1) {; + if ((nsent = _native_write(_native_tap_fd, buf, to_send)) == -1) { warn("write"); return -1; } + return (nsent > INT8_MAX ? INT8_MAX : nsent); } @@ -238,10 +249,10 @@ int tap_init(char *name) #ifdef __MACH__ /* OSX */ char clonedev[255] = "/dev/"; /* XXX bad size */ - strncpy(clonedev+5, name, 250); + strncpy(clonedev + 5, name, 250); #elif defined(__FreeBSD__) char clonedev[255] = "/dev/"; /* XXX bad size */ - strncpy(clonedev+5, name, 250); + strncpy(clonedev + 5, name, 250); #else /* Linux */ struct ifreq ifr; const char *clonedev = "/dev/net/tun"; @@ -253,11 +264,12 @@ int tap_init(char *name) } #if (defined(__MACH__) || defined(__FreeBSD__)) /* OSX/FreeBSD */ - struct ifaddrs* iflist; + struct ifaddrs *iflist; + if (getifaddrs(&iflist) == 0) { for (struct ifaddrs *cur = iflist; cur; cur = cur->ifa_next) { if ((cur->ifa_addr->sa_family == AF_LINK) && (strcmp(cur->ifa_name, name) == 0) && cur->ifa_addr) { - struct sockaddr_dl* sdl = (struct sockaddr_dl*)cur->ifa_addr; + struct sockaddr_dl *sdl = (struct sockaddr_dl *)cur->ifa_addr; memcpy(_native_tap_mac, LLADDR(sdl), sdl->sdl_alen); break; } @@ -265,6 +277,7 @@ int tap_init(char *name) freeifaddrs(iflist); } + #else /* Linux */ memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; @@ -282,21 +295,26 @@ int tap_init(char *name) /* get MAC address */ - memset (&ifr, 0, sizeof (ifr)); - snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", name); + memset(&ifr, 0, sizeof(ifr)); + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", name); + if (ioctl(_native_tap_fd, SIOCGIFHWADDR, &ifr) == -1) { _native_in_syscall++; warn("ioctl SIOCGIFHWADDR"); + if (real_close(_native_tap_fd) == -1) { warn("close"); } + exit(EXIT_FAILURE); } + memcpy(_native_tap_mac, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); #endif - DEBUG("_native_tap_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", _native_tap_mac[0], _native_tap_mac[1], _native_tap_mac[2], _native_tap_mac[3], _native_tap_mac[4], _native_tap_mac[5]); + DEBUG("_native_tap_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", _native_tap_mac[0], _native_tap_mac[1], + _native_tap_mac[2], _native_tap_mac[3], _native_tap_mac[4], _native_tap_mac[5]); - unsigned char *eui_64 = (unsigned char*)&_native_net_addr_long; + unsigned char *eui_64 = (unsigned char *)&_native_net_addr_long; eui_64[0] = _native_tap_mac[0]; eui_64[1] = _native_tap_mac[1]; eui_64[2] = _native_tap_mac[2]; @@ -314,15 +332,17 @@ int tap_init(char *name) * check http://sourceforge.net/p/tuntaposx/bugs/17/ */ sigio_child(); #else + /* configure fds to send signals on io */ if (fcntl(_native_tap_fd, F_SETOWN, _native_pid) == -1) { err(EXIT_FAILURE, "tap_init(): fcntl(F_SETOWN)"); } /* set file access mode to nonblocking */ - if (fcntl(_native_tap_fd, F_SETFL, O_NONBLOCK|O_ASYNC) == -1) { + if (fcntl(_native_tap_fd, F_SETFL, O_NONBLOCK | O_ASYNC) == -1) { err(EXIT_FAILURE, "tap_init(): fcntl(F_SETFL)"); } + #endif /* not OSX */ DEBUG("RIOT native tap initialized.\n"); From 264785852e8df138bf2583357f2ad73dd235d723 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 6 Aug 2014 15:51:46 +0200 Subject: [PATCH 2/3] nativenet: Supply net_dev_t support for nativenet --- boards/native/Makefile.dep | 6 +- boards/native/board_config.c | 2 +- cpu/native/include/nativenet.h | 19 +- cpu/native/include/nativenet_internal.h | 58 ++- cpu/native/net/interface.c | 450 ++++++++++++++++++++++-- cpu/native/net/tap.c | 8 +- drivers/include/netdev/default.h | 9 + 7 files changed, 515 insertions(+), 37 deletions(-) diff --git a/boards/native/Makefile.dep b/boards/native/Makefile.dep index c2782aff8026..604eed461fad 100644 --- a/boards/native/Makefile.dep +++ b/boards/native/Makefile.dep @@ -1,4 +1,6 @@ ifneq (,$(filter defaulttransceiver,$(USEMODULE))) - USEMODULE += nativenet - USEMODULE += transceiver + USEMODULE += nativenet + ifeq (,$(filter netdev_base,$(USEMODULE))) + USEMODULE += transceiver + endif endif diff --git a/boards/native/board_config.c b/boards/native/board_config.c index 1f2bff04d2c1..1444728f33db 100644 --- a/boards/native/board_config.c +++ b/boards/native/board_config.c @@ -41,7 +41,7 @@ void config_load(void) sysconfig.id = _native_id; #ifdef MODULE_NATIVENET - _native_net_addr = _native_id; + _nativenet_default_dev_more._radio_addr = _native_id; #endif return; diff --git a/cpu/native/include/nativenet.h b/cpu/native/include/nativenet.h index 402edea707ae..b7a5b5bad34b 100644 --- a/cpu/native/include/nativenet.h +++ b/cpu/native/include/nativenet.h @@ -28,10 +28,17 @@ #include #include "kernel_types.h" +#include "netdev/base.h" #define RX_BUF_SIZE (10) #define TRANSCEIVER_BUFFER_SIZE (3) +/** + * @brief Number of registrable netdev_rcv_data_cb_t callbacks per nativenet + * device + */ +#define NATIVENET_DEV_CB_MAX (128) + #ifndef NATIVE_MAX_DATA_LENGTH #include "tap.h" #ifdef MODULE_SIXLOWPAN @@ -44,7 +51,17 @@ #endif /* NATIVE_MAX_DATA_LENGTH */ /** - * Initialize transceiver + * @brief Implementation of netdev_driver_t for nativenet + */ +extern const netdev_driver_t nativenet_driver; + +/** + * @brief Default @netdev API device + */ +extern netdev_t nativenet_default_dev; + +/** + * Initialize @ref sys_transceiver and @ref nativenet_default_dev * * @param transceiver_pid the pid of the transceiver thread */ diff --git a/cpu/native/include/nativenet_internal.h b/cpu/native/include/nativenet_internal.h index 7cd3c4cd486a..4e10c8c06555 100644 --- a/cpu/native/include/nativenet_internal.h +++ b/cpu/native/include/nativenet_internal.h @@ -32,14 +32,68 @@ #define NNEV_SWTRX 0x0b #define NNEV_MAXEV 0x0b +#define _NATIVENET_DEV_MORE(dev) ((_nativenet_netdev_more_t *)dev->more) + struct rx_buffer_s { radio_packet_t packet; char data[NATIVE_MAX_DATA_LENGTH]; }; extern struct rx_buffer_s _nativenet_rx_buffer[RX_BUF_SIZE]; -extern uint64_t _native_net_addr_long; -extern radio_address_t _native_net_addr; + +/** + * @brief Definition of network device data. + */ +typedef struct { + /** + * @brief The channel assigned to this device + * + * @note For internal use only, do not change externally! + * + * @internal + */ + uint8_t _channel; + + /** + * @brief The PAN ID assigned to this device + * + * @note For internal use only, do not change externally! + * @internal + */ + uint16_t _pan_id; + + /** + * @brief The short address assigned to this device + * + * @note For internal use only, do not change externally! + * @internal + */ + radio_address_t _radio_addr; + + /** + * @brief The long address assigned to this device + * + * @note For internal use only, do not change externally! + * @internal + */ + uint64_t _long_addr; + + /** + * @brief Flag to determine if device is in promiscuous mode + * + * @note For internal use only, do not change externally! + * @internal + */ + uint8_t _is_monitoring; + + /** + * @brief Receive data callbacks for this device + */ + netdev_rcv_data_cb_t _callbacks[NATIVENET_DEV_CB_MAX]; +} _nativenet_netdev_more_t; + +/* internal counterpart to nativenet_default_dev */ +extern _nativenet_netdev_more_t _nativenet_default_dev_more; void _nativenet_handle_packet(radio_packet_t *packet); int8_t send_buf(radio_packet_t *packet); diff --git a/cpu/native/net/interface.c b/cpu/native/net/interface.c index d2c9741a3945..43ac8b9fafc8 100644 --- a/cpu/native/net/interface.c +++ b/cpu/native/net/interface.c @@ -42,24 +42,32 @@ static struct nativenet_callback_s _nativenet_callbacks[255]; struct rx_buffer_s _nativenet_rx_buffer[RX_BUF_SIZE]; static volatile uint8_t rx_buffer_next; -uint8_t _native_net_chan; -uint16_t _native_net_pan; -uint8_t _native_net_monitor; static kernel_pid_t _native_net_tpid = KERNEL_PID_UNDEF; -radio_address_t _native_net_addr; -uint64_t _native_net_addr_long; /************************************************************************/ /* nativenet.h **********************************************************/ /************************************************************************/ +int _nativenet_init(netdev_t *dev) +{ + if ((dev->type != NETDEV_TYPE_BASE) || (dev->more == NULL)) { + return -ENODEV; + } + + _NATIVENET_DEV_MORE(dev)->_channel = 0; + _NATIVENET_DEV_MORE(dev)->_pan_id = 0; + _NATIVENET_DEV_MORE(dev)->_is_monitoring = 0; + memset(_NATIVENET_DEV_MORE(dev)->_callbacks, 0, + sizeof((_NATIVENET_DEV_MORE(dev)->_callbacks))); + + return 0; +} + void nativenet_init(kernel_pid_t transceiver_pid) { DEBUG("nativenet_init(transceiver_pid=%" PRIkernel_pid ")\n", transceiver_pid); rx_buffer_next = 0; - _native_net_pan = 0; - _native_net_chan = 0; - _native_net_monitor = 0; + _nativenet_init((netdev_t *)(&nativenet_default_dev)); _native_net_tpid = transceiver_pid; } @@ -71,61 +79,63 @@ void nativenet_powerdown(void) void nativenet_set_monitor(uint8_t mode) { DEBUG("nativenet_set_monitor(mode=%d)\n", mode); - _native_net_monitor = mode; + _nativenet_default_dev_more._is_monitoring = mode; } int16_t nativenet_set_channel(uint8_t channel) { - _native_net_chan = channel; - return _native_net_chan; + _nativenet_default_dev_more._channel = channel; + return _nativenet_default_dev_more._channel; } int16_t nativenet_get_channel(void) { - return _native_net_chan; + return _nativenet_default_dev_more._channel; } uint16_t nativenet_set_pan(uint16_t pan) { - _native_net_pan = pan; - return _native_net_pan; + _nativenet_default_dev_more._pan_id = pan; + return _nativenet_default_dev_more._pan_id; } uint16_t nativenet_get_pan(void) { - return _native_net_pan; + return _nativenet_default_dev_more._pan_id; } radio_address_t nativenet_set_address(radio_address_t address) { DEBUG("nativenet_set_address(address=%d)\n", address); - _native_net_addr = address; - return _native_net_addr; + _nativenet_default_dev_more._radio_addr = address; + return _nativenet_default_dev_more._radio_addr; } radio_address_t nativenet_get_address(void) { - DEBUG("nativenet_get_address -> address = %d\n", _native_net_addr); - return _native_net_addr; + DEBUG("nativenet_get_address -> address = %d\n", + _nativenet_default_dev_more._radio_addr); + return _nativenet_default_dev_more._radio_addr; } uint64_t nativenet_get_address_long(void) { - DEBUG("nativenet_get_address_long -> address = %" PRIx64 "\n", _native_net_addr_long); - return _native_net_addr_long; + DEBUG("nativenet_get_address_long -> address = %" PRIx64 "\n", + _nativenet_default_dev_more._long_addr); + return _nativenet_default_dev_more._long_addr; } uint64_t nativenet_set_address_long(uint64_t address) { DEBUG("nativenet_set_address_long(address=%" PRIx64 ")\n", address); warnx("nativenet_set_address_long: this does not actually change the interfaces address"); - _native_net_addr_long = address; - return _native_net_addr_long; + _nativenet_default_dev_more._long_addr = address; + return _nativenet_default_dev_more._long_addr; } int8_t nativenet_send(radio_packet_t *packet) { - packet->src = _native_net_addr; + packet->src = _nativenet_default_dev_more._radio_addr; DEBUG("nativenet_send: Sending packet of length %" PRIu16 " from %" PRIu16 " to %" PRIu16 "\n", packet->length, packet->src, packet->dst); @@ -178,14 +188,19 @@ void do_cb(int event) void _nativenet_handle_packet(radio_packet_t *packet) { radio_address_t dst_addr = packet->dst; + int notified = 0; + + /* TODO: find way to demultiplex reception from several taps and map them + * to devices. */ + netdev_t *dev = &nativenet_default_dev; /* address filter / monitor mode */ - if (_native_net_monitor == 1) { + if (_nativenet_default_dev_more._is_monitoring == 1) { DEBUG("_nativenet_handle_packet: monitoring, not filtering address \n"); } else { /* own addr check */ - if (dst_addr == _native_net_addr) { + if (dst_addr == _nativenet_default_dev_more._radio_addr) { DEBUG("_nativenet_handle_packet: accept packet, addressed to us\n"); } else if (dst_addr == 0) { @@ -211,8 +226,23 @@ void _nativenet_handle_packet(radio_packet_t *packet) m.type = (uint16_t) RCV_PKT_NATIVE; m.content.value = rx_buffer_next; msg_send_int(&m, _native_net_tpid); + notified = 1; } - else { + + for (int i = 0; i < NATIVENET_DEV_CB_MAX; i++) { + if (_NATIVENET_DEV_MORE(dev)->_callbacks[i]) { + _NATIVENET_DEV_MORE(dev)->_callbacks[i]((netdev_t *)dev, + &(_nativenet_rx_buffer[rx_buffer_next].packet.src), + sizeof(uint16_t), + &(_nativenet_rx_buffer[rx_buffer_next].packet.dst), + sizeof(uint16_t), + &(_nativenet_rx_buffer[rx_buffer_next].data), + (size_t)_nativenet_rx_buffer[rx_buffer_next].packet.length); + notified = 1; + } + } + + if (!notified) { DEBUG("_nativenet_handle_packet: no one to notify =(\n"); } @@ -221,4 +251,370 @@ void _nativenet_handle_packet(radio_packet_t *packet) rx_buffer_next = 0; } } + +/*************************************************************** + * netdev_base wrapper + ***************************************************************/ + +#ifdef MODULE_NETDEV_BASE +int _nativenet_send_data(netdev_t *dev, void *dest, size_t dest_len, + netdev_hlist_t *upper_layer_hdrs, void *data, + size_t data_len) +{ + netdev_hlist_t *ptr = upper_layer_hdrs; + uint8_t tx_buffer[data_len + netdev_get_hlist_len(upper_layer_hdrs)]; + size_t tx_ptr = 0; + radio_packet_t pkt = {0, 0, 0, 0, 0, {0, 0}, sizeof(tx_buffer), tx_buffer}; + + if (dev->type != NETDEV_TYPE_BASE) { + return -ENODEV; + } + + if (dest_len > sizeof(uint16_t)) { + return -EAFNOSUPPORT; + } + + if (sizeof(tx_buffer) > NATIVE_MAX_DATA_LENGTH) { + return -EMSGSIZE; + } + + if (upper_layer_hdrs) { + do { + memcpy(&(tx_buffer[tx_ptr]), ptr->header, ptr->header_len); + tx_ptr += ptr->header_len; + netdev_hlist_advance(&ptr); + } while (ptr != upper_layer_hdrs); + } + + memcpy(&(tx_buffer[tx_ptr]), data, data_len); + + if (dest_len == sizeof(uint16_t)) { + pkt.dst = *((uint16_t *)dest); + } + else { + pkt.dst = (uint16_t)(*((uint8_t *)dest)); + } + + return nativenet_send(&pkt); +} + +int _nativenet_add_rcv_data_cb(netdev_t *dev, netdev_rcv_data_cb_t cb) +{ + int i = 0; + + if (dev->type != NETDEV_TYPE_BASE) { + return -ENODEV; + } + + for (i = 0; i < NATIVENET_DEV_CB_MAX; i++) { + if (_NATIVENET_DEV_MORE(dev)->_callbacks[i] == NULL || + _NATIVENET_DEV_MORE(dev)->_callbacks[i] == cb) { + break; + } + } + + if (i >= NATIVENET_DEV_CB_MAX) { + return -ENOBUFS; + } + + _NATIVENET_DEV_MORE(dev)->_callbacks[i] = cb; + + return 0; +} + +int _nativenet_rem_rcv_data_cb(netdev_t *dev, netdev_rcv_data_cb_t cb) +{ + int i = 0; + + if (dev->type != NETDEV_TYPE_BASE) { + return -ENODEV; + } + + for (i = 0; i < NATIVENET_DEV_CB_MAX; i++) { + if (_NATIVENET_DEV_MORE(dev)->_callbacks[i] == cb) { + _NATIVENET_DEV_MORE(dev)->_callbacks[i] = NULL; + } + } + + return 0; +} + +int _nativenet_get_option(netdev_t *dev, netdev_opt_t opt, void *value, + size_t *value_len) +{ + if (dev->type != NETDEV_TYPE_BASE) { + return -ENODEV; + } + + switch (opt) { + case NETDEV_OPT_CHANNEL: + if (*value_len == 0) { + return -EOVERFLOW; + } + + if (*value_len > sizeof(uint8_t)) { + *value_len = sizeof(uint8_t); + } + + *((uint8_t *)value) = _NATIVENET_DEV_MORE(dev)->_channel; + break; + + case NETDEV_OPT_ADDRESS: + if (*value_len < sizeof(radio_address_t)) { + return -EOVERFLOW; + } + + if (*value_len > sizeof(radio_address_t)) { + *value_len = sizeof(radio_address_t); + } + + *((radio_address_t *)value) = _NATIVENET_DEV_MORE(dev)->_radio_addr; + break; + + case NETDEV_OPT_NID: + if (*value_len < sizeof(uint16_t)) { + return -EOVERFLOW; + } + + if (*value_len > sizeof(uint16_t)) { + *value_len = sizeof(uint16_t); + } + + *((uint16_t *)value) = _NATIVENET_DEV_MORE(dev)->_pan_id; + break; + + case NETDEV_OPT_ADDRESS_LONG: + if (*value_len < sizeof(uint64_t)) { + return -EOVERFLOW; + } + + if (*value_len > sizeof(uint64_t)) { + *value_len = sizeof(uint64_t); + } + + *((uint64_t *)value) = _NATIVENET_DEV_MORE(dev)->_long_addr; + break; + + case NETDEV_OPT_MAX_PACKET_SIZE: + if (*value_len < sizeof(NATIVE_MAX_DATA_LENGTH)) { + return -EOVERFLOW; + } + + if (*value_len > sizeof(NATIVE_MAX_DATA_LENGTH)) { + *value_len = sizeof(NATIVE_MAX_DATA_LENGTH); + } + + *((netdev_proto_t *)value) = NATIVE_MAX_DATA_LENGTH; + break; + + case NETDEV_OPT_PROTO: + if (*value_len < sizeof(netdev_proto_t)) { + return -EOVERFLOW; + } + + if (*value_len > sizeof(netdev_proto_t)) { + *value_len = sizeof(netdev_proto_t); + } + + *((netdev_proto_t *)value) = NETDEV_PROTO_RADIO; + break; + + default: + return -ENOTSUP; + } + + return 0; +} + +static int _type_pun_up(void *value_out, size_t desired_len, + void *value_in, size_t given_len) +{ + if (given_len > desired_len) { + return -EOVERFLOW; + } + + /* XXX this is ugly, but bear with me */ + switch (given_len) { + case 8: + switch (desired_len) { + case 8: + *((uint64_t *)value_out) = (*((uint64_t *)value_in)); + return 0; + + default: + return -EINVAL; + } + + case 4: + switch (desired_len) { + case 8: + *((uint64_t *)value_out) = (uint64_t)(*((uint32_t *)value_in)); + return 0; + + case 4: + *((uint32_t *)value_out) = (*((uint32_t *)value_in)); + return 0; + + default: + return -EINVAL; + } + + case 2: + switch (desired_len) { + case 8: + *((uint64_t *)value_out) = (uint64_t)(*((uint16_t *)value_in)); + return 0; + + case 4: + *((uint32_t *)value_out) = (uint32_t)(*((uint16_t *)value_in)); + return 0; + + case 2: + *((uint16_t *)value_out) = (*((uint16_t *)value_in)); + return 0; + + default: + return -EINVAL; + } + + case 1: + switch (desired_len) { + case 8: + *((uint64_t *)value_out) = (uint64_t)(*((uint8_t *)value_in)); + return 0; + + case 4: + *((uint32_t *)value_out) = (uint32_t)(*((uint8_t *)value_in)); + return 0; + + case 2: + *((uint16_t *)value_out) = (uint16_t)(*((uint8_t *)value_in)); + return 0; + + case 1: + *((uint8_t *)value_out) = (*((uint8_t *)value_in)); + return 0; + + default: + return -EINVAL; + } + + default: + return -EINVAL; + } +} + +int _nativenet_set_option(netdev_t *dev, netdev_opt_t opt, void *value, + size_t value_len) +{ + uint8_t set_value[sizeof(uint64_t)]; + int res = 0; + + if (dev->type != NETDEV_TYPE_BASE) { + return -ENODEV; + } + + switch (opt) { + case NETDEV_OPT_CHANNEL: + if ((res = _type_pun_up(set_value, sizeof(uint8_t), + value, value_len)) == 0) { + _NATIVENET_DEV_MORE(dev)->_channel = *((uint8_t *)set_value); + } + + break; + + case NETDEV_OPT_ADDRESS: + if ((res = _type_pun_up(set_value, sizeof(radio_address_t), + value, value_len)) == 0) { + _NATIVENET_DEV_MORE(dev)->_radio_addr = *((radio_address_t *)set_value); + } + + break; + + case NETDEV_OPT_NID: + if ((res = _type_pun_up(set_value, sizeof(uint16_t), + value, value_len)) == 0) { + _NATIVENET_DEV_MORE(dev)->_pan_id = *((uint16_t *)set_value); + } + + break; + + case NETDEV_OPT_PROTO: + /* TODO: wouldn't this be awesome */ + return -ENOTSUP; + + default: + return -ENOTSUP; + } + + return res; +} + +int _nativenet_get_state(netdev_t *dev, netdev_state_t *state) +{ + if (dev->type != NETDEV_TYPE_BASE) { + return -ENODEV; + } + + if (_NATIVENET_DEV_MORE(dev)->_is_monitoring) { + *state = NETDEV_STATE_PROMISCUOUS_MODE; + } + else { + *state = NETDEV_STATE_RX_MODE; + } + + return 0; +} + +int _nativenet_set_state(netdev_t *dev, netdev_state_t state) +{ + if (state != NETDEV_STATE_PROMISCUOUS_MODE && _NATIVENET_DEV_MORE(dev)->_is_monitoring) { + _NATIVENET_DEV_MORE(dev)->_is_monitoring = 0; + } + + switch (state) { + case NETDEV_STATE_RX_MODE: + nativenet_switch_to_rx(); + break; + + case NETDEV_STATE_PROMISCUOUS_MODE: + _NATIVENET_DEV_MORE(dev)->_is_monitoring = 1; + break; + + default: + return -ENOTSUP; + } + + return 0; +} + +void _nativenet_event(netdev_t *dev, uint32_t event_type) +{ + (void)dev; + (void)event_type; +} + +const netdev_driver_t nativenet_driver = { + _nativenet_init, + _nativenet_send_data, + _nativenet_add_rcv_data_cb, + _nativenet_rem_rcv_data_cb, + _nativenet_get_option, + _nativenet_set_option, + _nativenet_get_state, + _nativenet_set_state, + _nativenet_event, +}; + +_nativenet_netdev_more_t _nativenet_default_dev_more; +netdev_t nativenet_default_dev = {NETDEV_TYPE_BASE, &nativenet_driver, + &_nativenet_default_dev_more + }; +#else +_nativenet_netdev_more_t _nativenet_default_dev_more; +netdev_t nativenet_default_dev = {NETDEV_TYPE_BASE, NULL, + &_nativenet_default_dev_more + }; +#endif /* MODULE_NETDEV_BASE */ + /** @} */ diff --git a/cpu/native/net/tap.c b/cpu/native/net/tap.c index abf91b1fd871..f9c930cdab70 100644 --- a/cpu/native/net/tap.c +++ b/cpu/native/net/tap.c @@ -127,7 +127,7 @@ void _native_handle_tap_input(void) if (select(_native_tap_fd + 1, &rfds, NULL, NULL, &t) == 1) { int sig = SIGIO; extern int _sig_pipefd[2]; - extern ssize_t (*real_write)(int fd, const void * buf, size_t count); + extern ssize_t (*real_write)(int fd, const void *buf, size_t count); real_write(_sig_pipefd[1], &sig, sizeof(int)); _native_sigpend++; DEBUG("_native_handle_tap_input: sigpend++\n"); @@ -215,7 +215,7 @@ int _native_marshall_ethernet(uint8_t *framebuf, radio_packet_t *packet) * Linux does this on its own, but it doesn't hurt to do it here. * As of now only tuntaposx needs this. */ if (data_len < ETHERMIN) { - DEBUG("padding data!(%d -> ", data_len); + DEBUG("padding data! (%d -> ", data_len); data_len = ETHERMIN; DEBUG("%d)\n", data_len); } @@ -314,7 +314,7 @@ int tap_init(char *name) DEBUG("_native_tap_mac: %02x:%02x:%02x:%02x:%02x:%02x\n", _native_tap_mac[0], _native_tap_mac[1], _native_tap_mac[2], _native_tap_mac[3], _native_tap_mac[4], _native_tap_mac[5]); - unsigned char *eui_64 = (unsigned char *)&_native_net_addr_long; + unsigned char *eui_64 = (unsigned char *)(&(_nativenet_default_dev_more._long_addr)); eui_64[0] = _native_tap_mac[0]; eui_64[1] = _native_tap_mac[1]; eui_64[2] = _native_tap_mac[2]; @@ -338,7 +338,7 @@ int tap_init(char *name) err(EXIT_FAILURE, "tap_init(): fcntl(F_SETOWN)"); } - /* set file access mode to nonblocking */ + /* set file access mode to non-blocking */ if (fcntl(_native_tap_fd, F_SETFL, O_NONBLOCK | O_ASYNC) == -1) { err(EXIT_FAILURE, "tap_init(): fcntl(F_SETFL)"); } diff --git a/drivers/include/netdev/default.h b/drivers/include/netdev/default.h index c3cc45c62505..50d49830236f 100644 --- a/drivers/include/netdev/default.h +++ b/drivers/include/netdev/default.h @@ -27,4 +27,13 @@ * * @brief Default device as a pointer of netdev_t. */ + +#ifdef MODULE_NATIVENET +#include "nativenet.h" + +#ifndef NETDEV_DEFAULT +#define NETDEV_DEFAULT (&nativenet_default_dev) +#endif /* NETDEV_DEFAULT */ +#endif /* MODULE_NATIVENET */ + #endif /* __NETDEV_DEFAULT_H_ */ From bf21a9eb0bb17af88e42bd53f024a138492da987 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Thu, 9 Oct 2014 09:18:12 +0200 Subject: [PATCH 3/3] netdev.tests: Remove unneccessary #ifndef path --- tests/netdev/main.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/netdev/main.c b/tests/netdev/main.c index c183bd5c2d95..b65b62c0f710 100644 --- a/tests/netdev/main.c +++ b/tests/netdev/main.c @@ -34,14 +34,8 @@ #ifdef NETDEV_DEFAULT #define SHELL_BUFSIZE (UART0_BUFSIZE) -#ifndef MODULE_NATIVENET -static netdev_t dev_mem; -static netdev_t *dev = &dev_mem; -#else -static netdev_t *dev = (netdev_t *) &nativenet_default_dev; -#endif - static size_t dev_address_len = 0; +static netdev_t *dev = NULL; /*********************************** * test channel *