Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3911 → Rev 3912

/branches/network/uspace/srv/net/structures/packet/packet_server.h
1,5 → 1,5
/*
* Copyright (c) 2008 Lukas Mejdrech
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,11 → 26,17
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup net
/** @addtogroup packet
* @{
*/
 
/** @file
* Packet server.
* The hosting module has to be compiled with both the packet.c and the packet_server.c source files.
* To function correctly, initialization of the packet map by the pm_init() function has to happen at the first place.
* Then the packet messages have to be processed by the packet_server_message() function.
* The packet map should be released by the pm_destroy() function during the module termination.
* @see IS_NET_PACKET_MESSAGE()
*/
 
#ifndef __NET_PACKET_SERVER_H__
38,6 → 44,15
 
#include <ipc/ipc.h>
 
/** Processes the packet server message.
* @param callid The message identifier. Input parameter.
* @param call The message parameters. Input parameter.
* @param answer The message answer parameters. Output parameter.
* @param answer_count The last parameter for the actual answer in the answer parameter. Output parameter.
* \todo all possible message returns?
* @returns EOK on success.
* @returns ENOTSUP if the message is not known.
*/
int packet_server_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count );
 
#endif
/branches/network/uspace/srv/net/structures/packet/packet_header.h
1,5 → 1,5
/*
* Copyright (c) 2008 Lukas Mejdrech
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,11 → 26,12
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup net
/** @addtogroup packet
* @{
*/
 
/** @file
* Packet header.
*/
 
#ifndef __NET_PACKET_HEADER_H__
40,27 → 41,73
 
#include "packet.h"
 
/** Packet integrity check magic value.
*/
#define PACKET_MAGIC_VALUE 0x11227788
 
/** Packet header.
*/
struct packet{
/** Packet identifier.
*/
packet_id_t packet_id;
//TODO packet owner not used
/** Packet owner.
*/
services_t owner;
//TODO needed packet mode?
/** Packet mode.
*/
packet_mode_t mode;
/** Packet queue sorting value.
* The packet queue is sorted the ascending order.
*/
int order;
/** Packet metric.
*/
size_t metric;
/** Previous packet in the queue.
*/
packet_id_t previous;
/** Next packet in the queue.
*/
packet_id_t next;
/** Total length of the packet.
* Contains the header, the addresses and the data of the packet.
* Corresponds to the mapped sharable memory block.
*/
size_t length;
/** Source and destination addresses length.
*/
size_t addr_len;
/** Souce address offset in bytes from the beginning of the packet header.
*/
size_t src_addr;
/** Destination address offset in bytes from the beginning of the packet header.
*/
size_t dest_addr;
/** Reserved data prefix length in bytes.
*/
size_t max_prefix;
/** Reserved content length in bytes.
*/
size_t max_content;
/** Actual data start offset in bytes from the beginning of the packet header.
*/
size_t data_start;
/** Actual data end offset in bytes from the beginning of the packet header.
*/
size_t data_end;
/** Integrity check magic value.
*/
int magic_value;
};
 
/** Returns whether the packet is valid.
* @param packet The packet to be checked. Input parameter.
* @returns true if the packet is not NULL and the magic value is correct.
* @returns false otherwise.
*/
static inline int packet_is_valid( const packet_t packet ){
return packet && ( packet->magic_value == PACKET_MAGIC_VALUE );
}
/branches/network/uspace/srv/net/structures/packet/packet_client.c
1,5 → 1,5
/*
* Copyright (c) 2008 Lukas Mejdrech
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,11 → 26,12
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup net
/** @addtogroup packet
* @{
*/
 
/** @file
* Packet client implementation.
*/
 
#include <async.h>
50,6 → 51,16
#include "packet_header.h"
#include "packet_client.h"
 
/** Obtains the packet from the packet server as the shared memory block.
* Creates the local packet mapping as well.
* @param phone The packet server module phone. Input parameter.
* @param packet The packet reference pointer to store the received packet reference. Output parameter.
* @param packet_id The packet identifier. Input parameter.
* @param size The packet total size in bytes. Input parameter.
* @returns EOK on success.
* \todo ipc_share_in_start() error?
* @returns Other error codes as defined for the pm_add() function.
*/
int packet_return( int phone, packet_ref packet, packet_id_t packet_id, size_t size );
 
packet_t packet_copy( int phone, services_t owner, const packet_t packet ){
74,31 → 85,33
return EOK;
}
 
void * packet_prepend( packet_t packet, size_t length ){
void * packet_prefix( packet_t packet, size_t length ){
if(( ! packet_is_valid( packet )) || ( packet->data_start - sizeof( struct packet ) - 2 * packet->addr_len < length )) return NULL;
packet->data_start -= length;
return ( void * ) packet + packet->data_start;
}
 
void * packet_append( packet_t packet, size_t length ){
void * packet_suffix( packet_t packet, size_t length ){
if(( ! packet_is_valid( packet )) || ( packet->data_end + length >= packet->length )) return NULL;
packet->data_end += length;
return ( void * ) packet + packet->data_end - length;
}
 
int packet_trim( packet_t packet, size_t prefix, size_t sufix ){
if(( ! packet_is_valid( packet )) || ( prefix + sufix > packet->data_end - packet->data_start )) return EINVAL;
int packet_trim( packet_t packet, size_t prefix, size_t suffix ){
if( ! packet_is_valid( packet )) return EINVAL;
if( prefix + suffix > packet->data_end - packet->data_start ) return ENOMEM;
packet->data_start += prefix;
packet->data_end -= sufix;
packet->data_end -= suffix;
return EOK;
}
 
packet_id_t packet_get_id( packet_t packet ){
packet_id_t packet_get_id( const packet_t packet ){
return packet_is_valid( packet ) ? packet->packet_id : 0;
}
 
int packet_get_addr( const packet_t packet, uint8_t ** src, uint8_t ** dest ){
if( !( packet_is_valid( packet ) && src && dest )) return 0;
if( !( packet_is_valid( packet ) && src && dest )) return EINVAL;
if( ! packet->addr_len ) return 0;
* src = ( void * ) packet + packet->src_addr;
* dest = ( void * ) packet + packet->dest_addr;
return packet->addr_len;
116,13 → 129,14
 
packet_mode_t packet_get_mode( const packet_t packet ){
if( packet_is_valid( packet )) return packet->mode;
return PM_ONEWAY;
return PM_ONE_WAY;
}
 
int packet_set_addr( packet_t packet, const uint8_t * src, const uint8_t * dest, size_t addr_len ){
size_t padding;
 
if( !( packet_is_valid( packet ) && ( packet->addr_len >= addr_len ))) return EINVAL;
if( ! packet_is_valid( packet )) return EINVAL;
if( packet->addr_len >= addr_len ) return ENOMEM;
padding = packet->addr_len - addr_len;
if( src ){
memcpy(( void * ) packet + packet->src_addr, src, addr_len );
168,20 → 182,21
 
aid_t message;
ipc_call_t answer;
ipcarg_t result;
 
message = async_send_1( phone, NET_PACKET_GET, packet_id, & answer );
* packet = ( packet_t ) as_get_mappable_page( size );
if( ERROR_OCCURED( ipc_share_in_start_0_0( phone, * packet, size ))
|| ERROR_OCCURED( pm_add( * packet ))){
if( ERROR_OCCURRED( ipc_share_in_start_0_0( phone, * packet, size ))
|| ERROR_OCCURRED( pm_add( * packet ))){
munmap( * packet, size );
async_wait_for( message, NULL );
return ERROR_CODE;
}
async_wait_for( message, NULL );
return EOK;
async_wait_for( message, & result );
return result;
}
 
packet_t packet_get_5( int phone, services_t owner, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_sufix ){
packet_t packet_get_5( int phone, services_t owner, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix ){
ERROR_DECLARE;
 
packet_id_t packet_id;
188,8 → 203,8
unsigned int size;
packet_t packet;
 
if( ERROR_OCCURED( async_req_5_2( phone, NET_PACKET_CREATE_5, owner, max_content, addr_len, max_prefix, max_sufix, & packet_id, & size ))
|| ERROR_OCCURED( packet_return( phone, & packet, packet_id, size ))){
if( ERROR_OCCURRED( async_req_5_2( phone, NET_PACKET_CREATE_5, owner, max_content, addr_len, max_prefix, max_suffix, & packet_id, & size ))
|| ERROR_OCCURRED( packet_return( phone, & packet, packet_id, size ))){
return NULL;
}
return packet;
202,8 → 217,8
unsigned int size;
packet_t packet;
 
if( ERROR_OCCURED( async_req_2_2( phone, NET_PACKET_CREATE_1, owner, content, & packet_id, & size ))
|| ERROR_OCCURED( packet_return( phone, & packet, packet_id, size ))){
if( ERROR_OCCURRED( async_req_2_2( phone, NET_PACKET_CREATE_1, owner, content, & packet_id, & size ))
|| ERROR_OCCURRED( packet_return( phone, & packet, packet_id, size ))){
return NULL;
}
return packet;
/branches/network/uspace/srv/net/structures/packet/packet.c
1,5 → 1,5
/*
* Copyright (c) 2008 Lukas Mejdrech
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,11 → 26,13
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup net
/** @addtogroup packet
* @{
*/
 
/** @file
* Packet map and queue implementation.
* This file has to be compiled with both the packet server and the client.
*/
 
#include <errno.h>
48,26 → 50,51
#include "packet.h"
 
// TODO power of 2 aritmetic => div and mod speedup?
/** Packet map page size.
*/
#define PACKET_MAP_SIZE 100
 
/** Returns the packet map page index.
* @param packet_id The packet identifier.
*/
#define PACKET_MAP_PAGE( packet_id ) ((( packet_id ) - 1 ) / PACKET_MAP_SIZE )
 
/** Returns the packet index in the corresponding packet map page.
* @param packet_id The packet identifier.
*/
#define PACKET_MAP_INDEX( packet_id ) ((( packet_id ) - 1 ) % PACKET_MAP_SIZE )
 
 
int packet_destroy( packet_t packet );
 
/** Type definition of the packet map page.
*/
typedef packet_t packet_map_t[ PACKET_MAP_SIZE ];
/** Type definition of the packet map page pointer.
*/
typedef packet_map_t * packet_map_ref;
 
/** Packet map.
* Maps packet identifiers to the packet references.
* @see generic_field.h
*/
GENERIC_FIELD_DECLARE( gpm, packet_map_t );
 
GENERIC_FIELD_IMPLEMENT( gpm, packet_map_t );
/** Releases the packet.
* @param packet The packet to be released. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the packet is not valid.
*/
int packet_destroy( packet_t packet );
 
/** Packet map global data.
*/
static struct{
// TODO lock
gpm_t map;
/** Packet map.
*/
gpm_t packet_map;
} pm_globals;
 
GENERIC_FIELD_IMPLEMENT( gpm, packet_map_t );
 
int packet_destroy( packet_t packet ){
if( ! packet_is_valid( packet )) return EINVAL;
return munmap( packet, packet->length );
74,7 → 101,7
}
 
int pm_init( void ){
return gpm_initialize( & pm_globals.map );
return gpm_initialize( & pm_globals.packet_map );
}
 
packet_t pm_find( packet_id_t packet_id ){
81,8 → 108,8
packet_map_ref map;
 
if( ! packet_id ) return NULL;
if( packet_id > PACKET_MAP_SIZE * gpm_count( & pm_globals.map )) return NULL;
map = gpm_get_index( & pm_globals.map, PACKET_MAP_PAGE( packet_id ));
if( packet_id > PACKET_MAP_SIZE * gpm_count( & pm_globals.packet_map )) return NULL;
map = gpm_get_index( & pm_globals.packet_map, PACKET_MAP_PAGE( packet_id ));
if( ! map ) return NULL;
return ( * map )[ PACKET_MAP_INDEX( packet_id ) ];
}
92,19 → 119,19
 
packet_map_ref map;
 
if(( ! packet_is_valid( packet )) || ( gpm_count( & pm_globals.map ) < -1 )) return EINVAL;
if( PACKET_MAP_PAGE( packet->packet_id ) < gpm_count( & pm_globals.map )){
map = gpm_get_index( & pm_globals.map, PACKET_MAP_PAGE( packet->packet_id ));
if(( ! packet_is_valid( packet )) || ( gpm_count( & pm_globals.packet_map ) < 0 )) return EINVAL;
if( PACKET_MAP_PAGE( packet->packet_id ) < gpm_count( & pm_globals.packet_map )){
map = gpm_get_index( & pm_globals.packet_map, PACKET_MAP_PAGE( packet->packet_id ));
}else{
do{
map = ( packet_map_ref ) malloc( sizeof( packet_map_t ));
if( ! map ) return ENOMEM;
memset( map, 0, sizeof( packet_map_t ));
if(( ERROR_CODE = gpm_add( & pm_globals.map, map )) < 0 ){
if(( ERROR_CODE = gpm_add( & pm_globals.packet_map, map )) < 0 ){
free( map );
return ERROR_CODE;
}
}while( PACKET_MAP_PAGE( packet->packet_id ) >= gpm_count( & pm_globals.map ));
}while( PACKET_MAP_PAGE( packet->packet_id ) >= gpm_count( & pm_globals.packet_map ));
}
( * map )[ PACKET_MAP_INDEX( packet->packet_id ) ] = packet;
return EOK;
116,9 → 143,9
packet_map_ref map;
packet_t packet;
 
count = gpm_count( & pm_globals.map );
count = gpm_count( & pm_globals.packet_map );
while( count > 0 ){
map = gpm_get_index( & pm_globals.map, count - 1 );
map = gpm_get_index( & pm_globals.packet_map, count - 1 );
for( index = PACKET_MAP_SIZE - 1; index >= 0; -- index ){
packet = ( * map )[ index ];
if( packet_is_valid( packet )){
126,7 → 153,7
}
}
}
gpm_destroy( & pm_globals.map );
gpm_destroy( & pm_globals.packet_map );
}
 
packet_t pq_add( packet_t first, packet_t packet, int order, size_t metric ){
/branches/network/uspace/srv/net/structures/packet/packet_client.h
1,5 → 1,5
/*
* Copyright (c) 2008 Lukas Mejdrech
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,11 → 26,17
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup net
/** @addtogroup packet
* @{
*/
 
/** @file
* Packet client.
* The hosting module has to be compiled with both the packet.c and the packet_client.c source files.
* To function correctly, initialization of the packet map by the pm_init() function has to happen at the first place.
* The module should not send the packet messages to the packet server but use the functions provided.
* The packet map should be released by the pm_destroy() function during the module termination.
* @see packet.h
*/
 
#ifndef __NET_PACKET_CLIENT_H__
38,28 → 44,197
 
#include "packet.h"
 
#define PACKET_PREPEND( packet, type ) ( type * ) packet_prepend(( packet ), sizeof( type ))
#define PACKET_APPEND( packet, type ) ( type * ) packet_append(( packet ), sizeof( type ))
#define PACKET_TRIM( packet, prefix, sufix ) packet_trim(( packet ), sizeof( prefix ), sizeof( sufix ))
/** Allocates the specified type right before the actual packet content and returns its pointer.
* The wrapper of the packet_prepend() function.
* @param packet The packet to be used. Input parameter.
* @param type The type to be allocated at the beginning of the packet content. Input parameter.
* @returns The typed pointer to the allocated memory.
* @returns NULL if the packet is not valid.
* @returns NULL if there is not enough memory left.
*/
#define PACKET_PREFIX( packet, type ) ( type * ) packet_prepend(( packet ), sizeof( type ))
 
void * packet_prepend( packet_t packet, size_t length );
void * packet_append( packet_t packet, size_t length );
/** Allocates the specified type right after the actual packet content and returns its pointer.
* The wrapper of the packet_append() function.
* @param packet The packet to be used. Input parameter.
* @param type The type to be allocated at the end of the packet content. Input parameter.
* @returns The typed pointer to the allocated memory.
* @returns NULL if the packet is not valid.
* @returns NULL if there is not enough memory left.
*/
#define PACKET_SUFFIX( packet, type ) ( type * ) packet_append(( packet ), sizeof( type ))
 
/** Trims the actual packet content by the specified prefix and suffix types.
* The wrapper of the packet_trim() function.
* @param packet The packet to be trimmed. Input parameter.
* @param prefix The type of the prefix to be removed from the beginning of the packet content. Input parameter.
* @param suffix The type of the suffix to be removed from the end of the packet content. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the packet is not valid.
* @returns EINVAL if there is not enough memory left.
*/
#define PACKET_TRIM( packet, prefix, suffix ) packet_trim(( packet ), sizeof( prefix ), sizeof( suffix ))
 
/** Allocates the specified space right before the actual packet content and returns its pointer.
* @param packet The packet to be used. Input parameter.
* @param length The space length to be allocated at the beginning of the packet content. Input parameter.
* @returns The pointer to the allocated memory.
* @returns NULL if there is not enough memory left.
*/
void * packet_prefix( packet_t packet, size_t length );
 
/** Allocates the specified space right after the actual packet content and returns its pointer.
* @param packet The packet to be used. Input parameter.
* @param length The space length to be allocated at the end of the packet content. Input parameter.
* @returns The pointer to the allocated memory.
* @returns NULL if there is not enough memory left.
*/
void * packet_suffix( packet_t packet, size_t length );
 
/** Trims the actual packet content by the specified prefix and suffix lengths.
* @param packet The packet to be trimmed. Input parameter.
* @param prefix The prefix length to be removed from the beginning of the packet content. Input parameter.
* @param suffix The suffix length to be removed from the end of the packet content. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the packet is not valid.
* @returns ENOMEM if there is not enough memory left.
*/
int packet_trim( packet_t packet, size_t prefix, size_t suffix );
 
/** Copies the packet content.
* Obtains the new packet from the packet server.
* @param phone The packet server module phone. Input parameter.
* @param owner The owner of the new packet. Input parameter.
* @param packet The packet reference. Input parameter.
* @returns The packet copy.
* @returns NULL if the source packet ids not valid.
* @returns NULL on error.
* \todo other error?
*/
packet_t packet_copy( int phone, services_t owner, const packet_t packet );
 
/** Copies the specified data to the beginning of the actual packet content.
* Pushes the content end if needed.
* @param packet The packet to be filled. Input parameter.
* @param data The data to be copied. Input parameter.
* @param length The length of the copied data. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the packet is not valid.
* @returns ENOMEM if there is not enough memory left.
*/
int packet_copy_data( packet_t packet, const void * data, size_t length );
int packet_trim( packet_t packet, size_t prefix, size_t sufix );
int packet_destroy( packet_t packet );
packet_id_t packet_get_id( packet_t packet );
 
/** Returns the packet identifier.
* @param packet The packet. Input parameter.
* @returns The packet identifier.
* @returns Zero (0) if the packet is not valid.
*/
packet_id_t packet_get_id( const packet_t packet );
 
/** Returns the packet content length.
* @param packet The packet. Input parameter.
* @returns The packet content length in bytes.
* @returns Zero (0) if the packet is not valid.
*/
size_t packet_get_data_length( const packet_t packet );
 
/** Returns the pointer to the beginning of the packet content.
* @param packet The packet. Input parameter.
* @returns The pointer to the beginning of the packet content.
* @returns NULL if the packet is not valid.
*/
void * packet_get_data( const packet_t packet );
 
/** Returns the stored packet addresses and their length.
* @param packet The packet. Input parameter.
* @param src The source address. Output parameter.
* @param dest The destination address. Output parameter.
* @returns The addresses length.
* @returns Zero (0) if the addresses are not present.
* @returns EINVAL if the packet is not valid.
* @returns EINVAL if the src and/or the dest parameter is NULL.
*/
int packet_get_addr( const packet_t packet, uint8_t ** src, uint8_t ** dest );
 
/** Returns the packet operation mode.
* @param packet The packet. Input parameter.
* @returns The packet operation mode.
* @see packet_mode
*/
packet_mode_t packet_get_mode( const packet_t packet );
 
/** Sets the packet addresses.
* @param packet The packet. Input parameter.
* @param src The new source address. Output parameter.
* @param dest The new destination address. Output parameter.
* @param addr_len The addresses length.
* @returns EOK on success.
* @returns EINVAL if the packet is not valid.
* @returns ENOMEM if there is not enough memory left.
*/
int packet_set_addr( packet_t packet, const uint8_t * src, const uint8_t * dest, size_t addr_len );
 
/** Sets the packet operation mode.
* @param packet The packet. Input parameter.
* @param mode The new packet operation mode. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the packet is not valid.
* @see packet_mode
*/
int packet_set_mode( packet_t packet, packet_mode_t mode );
 
/** Sets the packet owner.
* @param packet The packet. Input parameter.
* @param owner The new packet owner. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the packet is not valid.
*/
int packet_set_owner( packet_t packet, services_t owner );
 
/** Translates the packet identifier to the packet reference.
* Tries to find mapping first.
* Contacts the packet server to share the packet if the mapping is not present.
* @param phone The packet server module phone. Input parameter.
* @param packet The packet reference. Output parameter.
* @param packet_id The packet identifier. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the packet parameter is NULL.
* @returns Other error codes as defined for the NET_PACKET_GET_SIZE message.
* \todo errors as packet_return()
*/
int packet_translate( int phone, packet_ref packet, packet_id_t packet_id );
packet_t packet_get_5( int phone, services_t owner, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_sufix );
 
/** Obtains the packet of the given dimensions.
* Contacts the packet server to return the appropriate packet.
* @param phone The packet server module phone. Input parameter.
* @param owner The owner of the new packet. Input parameter.
* @param addr_len The source and destination addresses maximal length in bytes. Input parameter.
* @param max_prefix The maximal prefix length in bytes. Input parameter.
* @param max_content The maximal content length in bytes. Input parameter.
* @param max_suffix The maximal suffix length in bytes. Input parameter.
* @returns The packet reference.
* @returns NULL on error.
* \todo error as NET_PACKET_CREATE_5, packet_return()
*/
packet_t packet_get_5( int phone, services_t owner, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix );
 
/** Obtains the packet of the given content size.
* Contacts the packet server to return the appropriate packet.
* @param phone The packet server module phone. Input parameter.
* @param owner The owner of the new packet. Input parameter.
* @param content The maximal content length in bytes. Input parameter.
* @returns The packet reference.
* @returns NULL on error.
* \todo error as NET_PACKET_CREATE_1, packet_return()
*/
packet_t packet_get_1( int phone, services_t owner, size_t content );
 
/** Releases the packet.
* The packet is marked as free for use.
* The module should not use the packet after this point until it is received or obtained again.
* @param phone The packet server module phone. Input parameter.
* @param packet_id The packet identifier. Input parameter.
*/
void packet_release( int phone, packet_id_t packet_id );
 
#endif
/branches/network/uspace/srv/net/structures/packet/packet.h
1,5 → 1,5
/*
* Copyright (c) 2008 Lukas Mejdrech
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,36 → 26,104
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup net
/** @addtogroup packet
* @{
*/
 
/** @file
* Packet map and queue.
*/
 
#ifndef __NET_PACKET_H__
#define __NET_PACKET_H__
 
/** Packet identifier type.
* Value zero (0) is used as an invalid identifier.
*/
typedef unsigned int packet_id_t;
 
/** Type definition of the packet.
* @see packet
*/
typedef struct packet * packet_t;
typedef packet_t * packet_ref;
 
/** Type definition of the packet pointer.
* @see packet
*/
typedef packet_t * packet_ref;
 
/** Packet operation mode type.
*/
typedef enum packet_mode packet_mode_t;
 
/** Packet operation mode.
*/
enum packet_mode{
PM_ONEWAY,
/** The packet is processed in one direction and can be released at any time.
*/
PM_ONE_WAY,
/** The packet should be returned at the end of the processing back to its initiator.
*/
PM_RETURN
};
 
packet_t pm_find( packet_id_t packet_id );
int pm_add( packet_t packet );
int pm_init( void );
void pm_destroy( void );
/** Finds the packet mapping.
* @param packet_id The packet identifier to be found. Input parameter.
* @returns The found packet reference.
* @returns NULL if the mapping does not exist.
*/
packet_t pm_find( packet_id_t packet_id );
 
/** Adds the packet mapping.
* @param packet The packet to be remembered. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the packet is not valid.
* @returns EINVAL if the packet map is not initialized.
* @returns ENOMEM if there is not enough memory left.
*/
int pm_add( packet_t packet );
 
/** Initializes the packet map.
* @returns EOK on success.
* @returns ENOMEM if there is not enough memory left.
*/
int pm_init( void );
 
/** Releases the packet map.
*/
void pm_destroy( void );
 
/** Add packet to the sorted queue.
* The queue is sorted in the ascending order.
* The packet is inserted right before the packets of the same order value.
* @param first The first packet of the queue. May be NULL. Input parameter.
* @param packet The packet to be added. Input parameter.
* @param order The packet order value. Input parameter.
* @param metric The metric value of the packet. Input parameter.
* @returns The first packet of the queue. The original first packet may be shifted by the new packet.
* @returns NULL if the packet is not valid.
*/
packet_t pq_add( packet_t first, packet_t packet, int order, size_t metric );
packet_t pq_detach( packet_t packet );
 
/** Detach the packet from the queue.
* @param packet The packet to be detached. Input parameter.
* @returns The next packet in the queue. If the packet is the first one of the queue, this becomes the new first one.
* @returns NULL if the packet is not valid.
*/
packet_t pq_detach( packet_t packet );
 
/** Sets the packet order and metric attributes.
* @param packet The packet to be set. Input parameter.
* @param order The packet order value. Input parameter.
* @param metric The metric value of the packet. Input parameter.
*/
int pq_set( packet_t packet, int order, size_t metric );
 
/** Releases the whole queue.
* Detaches all packets of the queue and calls the packet_release() for each of them.
* @param first The first packet of the queue. Input parameter.
* @param packet_release The releasing function called for each of the packets after its detachment. Input parameter.
*/
void pq_destroy( packet_t first, void ( * packet_release )( packet_t packet ));
 
#endif
/branches/network/uspace/srv/net/structures/packet/packet_server.c
1,5 → 1,5
/*
* Copyright (c) 2008 Lukas Mejdrech
* Copyright (c) 2009 Lukas Mejdrech
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,11 → 26,12
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup net
/** @addtogroup packet
* @{
*/
 
/** @file
* Packet server implementation.
*/
 
#include <async.h>
50,18 → 51,45
#include "packet_header.h"
#include "packet_server.h"
 
/** Returns the packet identifier message parameter.
*/
#define IPC_GET_ID( call ) ( packet_id_t ) IPC_GET_ARG1( * call )
 
/** Returns the owner message parameter.
*/
#define IPC_GET_OWNER( call ) ( services_t ) IPC_GET_ARG1( * call )
 
/** Returns the maximal content length message parameter.
*/
#define IPC_GET_CONTENT( call ) ( size_t ) IPC_GET_ARG2( * call )
 
/** Returns the maximal address length message parameter.
*/
#define IPC_GET_ADDR_LEN( call ) ( size_t ) IPC_GET_ARG3( * call )
 
/** Returns the maximal prefix length message parameter.
*/
#define IPC_GET_PREFIX( call ) ( size_t ) IPC_GET_ARG4( * call )
 
/** Returns the maximal suffix length message parameter.
*/
#define IPC_GET_SUFIX( call ) ( size_t ) IPC_GET_ARG5( * call )
 
#define FREE_QUEUES_COUNT 7
 
/** Packet server global data.
*/
static struct{
/** Free packet queues.
*/
packet_t free[ FREE_QUEUES_COUNT ];
/** Packet length upper bounds of the free packet queues.
* The maximal lengths of packets in each queue in the ascending order.
* The last queue is not limited.
*/
int sizes[ FREE_QUEUES_COUNT ];
/** Total packets allocated.
*/
unsigned int count;
} ps_globals = {
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL },
69,10 → 97,54
0
};
 
/** Releases the packet and returns it to the appropriate free packet queue.
* @param packet The packet to be released. Input parameter.
*/
void packet_release( packet_t packet );
packet_t packet_get( services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_sufix );
packet_t packet_create( size_t length, services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_sufix );
void packet_init( packet_t packet, services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_sufix );
 
/** Returns the packet of dimensions at least as given.
* Tries to reuse free packets first.
* Creates a&nbsp;new packet aligned to the memory page size if none available.
* @param owner The new owner of the packet. Input parameter.
* @param addr_len The source and destination addresses maximal length in bytes. Input parameter.
* @param max_prefix The maximal prefix length in bytes. Input parameter.
* @param max_content The maximal content length in bytes. Input parameter.
* @param max_suffix The maximal suffix length in bytes. Input parameter.
* @returns The packet of dimensions at least as given.
* @returns NULL if there is not enough memory left.
*/
packet_t packet_get( services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix );
 
/** Creates a&nbsp;new packet of dimensions at least as given.
* @param length The total length of the packet, including the header, the addresses and the data of the packet. Input parameter.
* @param owner The new owner of the packet. Input parameter.
* @param addr_len The source and destination addresses maximal length in bytes. Input parameter.
* @param max_prefix The maximal prefix length in bytes. Input parameter.
* @param max_content The maximal content length in bytes. Input parameter.
* @param max_suffix The maximal suffix length in bytes. Input parameter.
* @returns The packet of dimensions at least as given.
* @returns NULL if there is not enough memory left.
*/
packet_t packet_create( size_t length, services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix );
 
/** Initializes the packet according to the given dimensions.
* @param packet The packet to be initialized. Input parameter.
* @param owner The new owner of the packet. Input parameter.
* @param addr_len The source and destination addresses maximal length in bytes. Input parameter.
* @param max_prefix The maximal prefix length in bytes. Input parameter.
* @param max_content The maximal content length in bytes. Input parameter.
* @param max_suffix The maximal suffix length in bytes. Input parameter.
*/
void packet_init( packet_t packet, services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix );
 
/** Shares the packet memory block.
* @param packet The packet to be shared.
* @returns EOK on success.
* @returns EINVAL if the packet is not valid.
* @returns EINVAL if the calling module does not accept the memory.
* @returns ENOMEM if the desired and actual sizes differ.
* @returns Other error codes as defined for the ipc_share_in_finalize() function.
*/
int packet_reply( const packet_t packet );
 
int packet_server_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ){
122,12 → 194,12
ps_globals.free[ index ] = pq_add( ps_globals.free[ index ], packet, packet->length, packet->length );
}
 
packet_t packet_get( services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_sufix ){
packet_t packet_get( services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix ){
int index;
packet_t packet;
size_t length;
 
length = ALIGN_UP( sizeof( struct packet ) + 2 * addr_len + max_prefix + max_content + max_sufix, PAGE_SIZE );
length = ALIGN_UP( sizeof( struct packet ) + 2 * addr_len + max_prefix + max_content + max_suffix, PAGE_SIZE );
for( index = 0; index < FREE_QUEUES_COUNT - 1; ++ index ){
if( length <= ps_globals.sizes[ index ] ){
packet = ps_globals.free[ index ];
135,15 → 207,15
packet = pm_find( packet->next );
}
if( packet ){
packet_init( packet, owner, addr_len, max_prefix, max_content, max_sufix );
packet_init( packet, owner, addr_len, max_prefix, max_content, max_suffix );
return packet;
}
}
}
return packet_create( length, owner, addr_len, max_prefix, max_content, max_sufix );
return packet_create( length, owner, addr_len, max_prefix, max_content, max_suffix );
}
 
packet_t packet_create( size_t length, services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_sufix ){
packet_t packet_create( size_t length, services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix ){
ERROR_DECLARE;
 
packet_t packet;
152,11 → 224,11
if( packet == MAP_FAILED ) return NULL;
++ ps_globals.count;
packet->packet_id = ps_globals.count;
packet->mode = PM_ONEWAY;
packet->mode = PM_ONE_WAY;
packet->length = length;
packet_init( packet, owner, addr_len, max_prefix, max_content, max_sufix );
packet_init( packet, owner, addr_len, max_prefix, max_content, max_suffix );
packet->magic_value = PACKET_MAGIC_VALUE;
if( ERROR_OCCURED( pm_add( packet ))){
if( ERROR_OCCURRED( pm_add( packet ))){
munmap( packet, packet->length );
return NULL;
}
164,7 → 236,7
return packet;
}
 
void packet_init( packet_t packet, services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_sufix ){
void packet_init( packet_t packet, services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix ){
packet->owner = owner;
packet->order = 0;
packet->metric = 0;