2013-08-29 14:41:55 +02:00
/**
* 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 >
*/
2013-08-08 11:08:33 +02:00
# include <stdio.h>
# include <err.h>
# include <stdint.h>
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
2013-08-21 19:22:32 +02:00
# include <inttypes.h>
2013-08-08 11:08:33 +02:00
# include <arpa/inet.h>
# define ENABLE_DEBUG (0)
# include "debug.h"
# include "transceiver.h"
# include "tap.h"
# include "nativenet.h"
# include "nativenet_internal.h"
# include "cpu.h"
struct nativenet_callback_s {
void ( * func ) ( void ) ;
} ;
static struct nativenet_callback_s _nativenet_callbacks [ 255 ] ;
struct rx_buffer_s _nativenet_rx_buffer [ RX_BUF_SIZE ] ;
volatile uint8_t rx_buffer_next ;
uint8_t _native_net_chan ;
uint16_t _native_net_pan ;
uint8_t _native_net_monitor ;
static int _native_net_tpid ;
radio_address_t _native_net_addr ;
/************************************************************************/
/* nativenet.h **********************************************************/
/************************************************************************/
void nativenet_init ( int transceiver_pid )
{
DEBUG ( " nativenet_init(transceiver_pid=%d) " , transceiver_pid ) ;
2013-08-29 17:02:26 +02:00
rx_buffer_next = 0 ;
2013-08-08 11:08:33 +02:00
_native_net_pan = 0 ;
_native_net_chan = 0 ;
_native_net_monitor = 0 ;
_native_net_tpid = transceiver_pid ;
}
void nativenet_powerdown ( )
{
return ;
}
void nativenet_set_monitor ( uint8_t mode )
{
DEBUG ( " nativenet_set_monitor(mode=%d) \n " , mode ) ;
_native_net_monitor = mode ;
}
int16_t nativenet_set_channel ( uint8_t channel )
{
_native_net_chan = channel ;
return _native_net_chan ;
}
int16_t nativenet_get_channel ( )
{
return _native_net_chan ;
}
uint16_t nativenet_set_pan ( uint16_t pan )
{
_native_net_pan = pan ;
return _native_net_pan ;
}
uint16_t nativenet_get_pan ( )
{
return _native_net_pan ;
}
2013-08-21 19:22:32 +02:00
radio_address_t nativenet_set_address ( radio_address_t address )
2013-08-08 11:08:33 +02:00
{
_native_net_addr = address ;
return _native_net_addr ;
}
2013-08-21 19:22:32 +02:00
radio_address_t nativenet_get_address ( )
2013-08-08 11:08:33 +02:00
{
return _native_net_addr ;
}
uint8_t nativenet_send ( radio_packet_t * packet )
{
2013-08-21 19:22:32 +02:00
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 ) ;
2013-08-08 11:08:33 +02:00
if ( send_buf ( packet ) = = - 1 ) {
warnx ( " nativenet_send: error sending packet " ) ;
2013-08-21 19:22:32 +02:00
return 0 ;
2013-08-08 11:08:33 +02:00
}
2013-08-21 19:22:32 +02:00
return true ;
2013-08-08 11:08:33 +02:00
}
void nativenet_switch_to_rx ( )
{
return ;
}
/************************************************************************/
/* nativenet_internal.h *************************************************/
/************************************************************************/
2013-08-21 15:10:24 +02:00
int _nativenet_register_cb ( int event , void ( * func ) ( void ) )
2013-08-08 11:08:33 +02:00
{
if ( event > NNEV_MAXEV ) {
DEBUG ( " _nativenet_register_cb: event > NNEV_MAXEV " ) ;
return - 1 ;
}
_nativenet_callbacks [ event ] . func = func ;
return 0 ;
}
int _nativenet_unregister_cb ( int event )
{
if ( event > NNEV_MAXEV ) {
DEBUG ( " _nativenet_unregister_cb: event > NNEV_MAXEV " ) ;
return - 1 ;
}
_nativenet_callbacks [ event ] . func = NULL ;
return 0 ;
}
void do_cb ( int event )
{
if ( event > NNEV_MAXEV ) {
DEBUG ( " do_cb: event > NNEV_MAXEV " ) ;
return ;
}
if ( _nativenet_callbacks [ event ] . func ! = NULL ) {
_nativenet_callbacks [ event ] . func ( ) ;
}
}
void _nativenet_handle_packet ( radio_packet_t * packet )
{
2013-08-21 19:22:32 +02:00
radio_address_t dst_addr = packet - > dst ;
2013-08-08 11:08:33 +02:00
/* address filter / monitor mode */
if ( _native_net_monitor = = 1 ) {
DEBUG ( " _nativenet_handle_packet: monitoring, not filtering address \n " ) ;
}
else {
/* own addr check */
if ( dst_addr = = _native_net_addr ) {
DEBUG ( " _nativenet_handle_packet: accept packet, addressed to us \n " ) ;
}
else if ( dst_addr = = 0 ) {
DEBUG ( " _nativenet_handle_packet: accept packet, broadcast \n " ) ;
}
else {
DEBUG ( " _nativenet_handle_packet: discard packet addressed to someone else \n " ) ;
return ;
}
}
/* copy packet to rx buffer */
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 ) ) ;
2013-09-04 20:39:56 +02:00
_nativenet_rx_buffer [ rx_buffer_next ] . packet . data = & _nativenet_rx_buffer [ rx_buffer_next ] . data ;
2013-08-08 11:08:33 +02:00
/* notify transceiver thread if any */
if ( _native_net_tpid ) {
DEBUG ( " _nativenet_handle_packet: notifying transceiver thread! \n " ) ;
msg_t m ;
m . type = ( uint16_t ) RCV_PKT_NATIVE ;
m . content . value = rx_buffer_next ;
msg_send_int ( & m , _native_net_tpid ) ;
}
else {
DEBUG ( " _nativenet_handle_packet: no one to notify =( \n " ) ;
}
/* shift to next buffer element */
if ( + + rx_buffer_next = = RX_BUF_SIZE ) {
rx_buffer_next = 0 ;
}
}
2013-08-29 14:41:55 +02:00
/** @} */