/*
* Copyright (c) 2008 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @addtogroup net
* @{
*/
/** @file
*/
#include <async.h>
#include <errno.h>
#include <stdio.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
//#include <sys/mman.h>
#include "../err.h"
#include "../messages.h"
#include "../modules.h"
#include "netif.h"
#define DEFAULT_MTU 1500
#define NAME "lo - loopback interface"
netif_globals_t netif_globals;
void change_status( netif_device_ref device, netif_status_t status );
int change_status_message( netif_device_id_t device_id, netif_status_t status );
int netif_create( netif_device_id_t device_id, netif_device_ref * device );
int netif_call( ipc_callid_t callid );
int netif_initialize( void );
void netif_print_name( void );
int netif_probe_auto_message( ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 );
int netif_probe_message( ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 );
int netif_send_message( ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 );
int netif_start_message( ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 );
int netif_stop_message( ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 );
void change_status( netif_device_ref device, netif_status_t status ){
device->status = status;
ll_message( device, NET_LL_DEVICE_STATUS_CHANGED, device->status, NULL, NULL, NULL, NULL );
}
int change_status_message( netif_device_id_t device_id, netif_status_t status ){
ERROR_DECLARE;
netif_device_ref device;
ERROR_PROPAGATE( netif_device_find( device_id, & device ));
change_status( device, status );
return EOK;
}
int netif_create( netif_device_id_t device_id, netif_device_ref * device ){
ERROR_DECLARE;
if( netif_device_map_count( & netif_globals.netif_device_map ) > 0 ){
return EXDEV;
}else{
* device
= ( netif_device_ref
) malloc( sizeof( netif_device_t
));
if( !( * device )) return ENOMEM;
// ( ** device ).device_id = netif_device_id_generate( 1 );
( ** device ).device_id = device_id;
( ** device ).ll_registered = NULL;
netif_device_stats_null( &(( ** device ).stats ));
( ** device ).status = NETIF_STOPPED;
( ** device ).flags = NULL;
( ** device ).mtu = DEFAULT_MTU;
if( ERROR_OCCURED( netif_device_map_add( & netif_globals.netif_device_map, ( ** device ).device_id, * device ))){
* device = NULL;
return ERROR_CODE;
}
}
return EOK;
}
int netif_call( ipc_callid_t callid ){
return EOK;
}
int netif_initialize( void ){
int phonehash;
return REGISTER_ME( SERVICE_LO, & phonehash );
}
void netif_print_name( void ){
}
int netif_probe_auto_message( ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 ){
ERROR_DECLARE;
netif_device_ref device;
ERROR_PROPAGATE( netif_create( arg1, & device ));
networking_message( NET_NETWORKING_DEVICE, device->device_id, NULL, NULL, NULL, NULL, NULL );
return EOK;
}
int netif_probe_message( ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 ){
ERROR_DECLARE;
netif_device_ref device;
ERROR_PROPAGATE( netif_create( arg1, & device ));
return EOK;
}
int netif_send_message( ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 ){
ERROR_DECLARE;
netif_device_ref device;
ERROR_PROPAGATE( netif_device_find( arg1, & device ));
if( device->status == NETIF_ACTIVE ){
++ device->stats.tx_packets;
++ device->stats.rx_packets;
// TODO packet size
//device->stats->tx_bytes += ;
//device->stats->rx_bytes += ;
ll_message( device, NET_LL_RECEIVED, arg2, NULL, NULL, NULL, NULL );
return EOK;
}else{
return EPERM;
}
}
int netif_start_message( ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 ){
return change_status_message( arg1, NETIF_ACTIVE );
}
int netif_stop_message( ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t * result1, ipcarg_t * result2, ipcarg_t * result3 ){
return change_status_message( arg1, NETIF_STOPPED );
}
/** @}
*/