/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 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 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; |