/branches/network/uspace/srv/net/structures/packet/packet_queue.c |
---|
File deleted |
/branches/network/uspace/srv/net/structures/packet/packet_queue.h |
---|
File deleted |
/branches/network/uspace/srv/net/structures/packet/packet_server.h |
---|
0,0 → 1,46 |
/* |
* 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 |
*/ |
#ifndef __NET_PACKET_SERVER_H__ |
#define __NET_PACKET_SERVER_H__ |
#include <ipc/ipc.h> |
int packet_server_message( ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count ); |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/structures/packet/packet_header.h |
---|
0,0 → 1,71 |
/* |
* 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 |
*/ |
#ifndef __NET_PACKET_HEADER_H__ |
#define __NET_PACKET_HEADER_H__ |
#include <ipc/services.h> |
#include "packet.h" |
#define PACKET_MAGIC_VALUE 0x11227788 |
struct packet{ |
packet_id_t packet_id; |
services_t owner; |
packet_mode_t mode; |
int order; |
size_t metric; |
packet_id_t previous; |
packet_id_t next; |
size_t length; |
size_t addr_len; |
size_t src_addr; |
size_t dest_addr; |
size_t max_prefix; |
size_t max_content; |
size_t data_start; |
size_t data_end; |
int magic_value; |
}; |
static inline int packet_is_valid( const packet_t packet ){ |
return packet && ( packet->magic_value == PACKET_MAGIC_VALUE ); |
} |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/structures/packet/packet_client.c |
---|
0,0 → 1,217 |
/* |
* 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 <unistd.h> |
//#include <stdio.h> |
#include <string.h> |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include <sys/mman.h> |
#include "../../err.h" |
#include "../../messages.h" |
#include "packet.h" |
#include "packet_header.h" |
#include "packet_client.h" |
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 ){ |
packet_t new; |
if( ! packet_is_valid( packet )) return NULL; |
// new = ( packet_t ) mmap( NULL, packet->length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0 ); |
// if( new == MAP_FAILED ) return NULL; |
// memcpy( new, packet, packet->length ); |
new = packet_get_1( phone, owner, packet_get_data_length( packet )); |
packet_copy_data( new, packet_get_data( packet ), packet_get_data_length( packet )); |
return new; |
} |
int packet_copy_data( packet_t packet, const void * data, size_t length ){ |
if( ! packet_is_valid( packet )) return EINVAL; |
if( packet->data_start + length >= packet->length ) return ENOMEM; |
memcpy(( void * ) packet + packet->data_start, data, length ); |
if( packet->data_start + length > packet->data_end ){ |
packet->data_end = packet->data_start + length; |
} |
return EOK; |
} |
void * packet_prepend( 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 ){ |
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; |
packet->data_start += prefix; |
packet->data_end -= sufix; |
return EOK; |
} |
packet_id_t packet_get_id( 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; |
* src = ( void * ) packet + packet->src_addr; |
* dest = ( void * ) packet + packet->dest_addr; |
return packet->addr_len; |
} |
size_t packet_get_data_length( const packet_t packet ){ |
if( ! packet_is_valid( packet )) return 0; |
return packet->data_end - packet->data_start; |
} |
void * packet_get_data( const packet_t packet ){ |
if( ! packet_is_valid( packet )) return NULL; |
return ( void * ) packet + packet->data_start; |
} |
packet_mode_t packet_get_mode( const packet_t packet ){ |
if( packet_is_valid( packet )) return packet->mode; |
return PM_ONEWAY; |
} |
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; |
padding = packet->addr_len - addr_len; |
if( src ){ |
memcpy(( void * ) packet + packet->src_addr, src, addr_len ); |
memset(( void * ) packet + packet->src_addr + addr_len, 0, padding ); |
}else{ |
memset(( void * ) packet + packet->src_addr + addr_len, 0, packet->addr_len ); |
} |
if( dest ){ |
memcpy(( void * ) packet + packet->dest_addr, dest, addr_len ); |
memset(( void * ) packet + packet->dest_addr + addr_len, 0, padding ); |
}else{ |
memset(( void * ) packet + packet->dest_addr + addr_len, 0, packet->addr_len ); |
} |
return EOK; |
} |
int packet_set_mode( packet_t packet, packet_mode_t mode ){ |
if( ! packet_is_valid( packet )) return EINVAL; |
packet->mode = mode; |
return EOK; |
} |
int packet_set_owner( packet_t packet, services_t owner ){ |
if( ! packet_is_valid( packet )) return EINVAL; |
packet->owner = owner; |
return EOK; |
} |
int packet_translate( int phone, packet_ref packet, packet_id_t packet_id ){ |
ERROR_DECLARE; |
unsigned int size; |
if( ! packet ) return EINVAL; |
* packet = pm_find( packet_id ); |
if( * packet ) return EOK; |
ERROR_PROPAGATE( async_req_1_1( phone, NET_PACKET_GET_SIZE, packet_id, & size )); |
return packet_return( phone, packet, packet_id, size ); |
} |
int packet_return( int phone, packet_ref packet, packet_id_t packet_id, size_t size ){ |
ERROR_DECLARE; |
aid_t message; |
ipc_call_t answer; |
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 ))){ |
munmap( * packet, size ); |
async_wait_for( message, NULL ); |
return ERROR_CODE; |
} |
async_wait_for( message, NULL ); |
return EOK; |
} |
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 ){ |
ERROR_DECLARE; |
packet_id_t packet_id; |
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 ))){ |
return NULL; |
} |
return packet; |
} |
packet_t packet_get_1( int phone, services_t owner, size_t content ){ |
ERROR_DECLARE; |
packet_id_t packet_id; |
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 ))){ |
return NULL; |
} |
return packet; |
} |
void packet_release( int phone, packet_id_t packet_id ){ |
async_msg_1( phone, NET_PACKET_RELEASE, packet_id ); |
} |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/structures/packet/packet.c |
---|
27,7 → 27,7 |
*/ |
/** @addtogroup net |
* @{ |
* @{ |
*/ |
/** @file |
34,124 → 34,167 |
*/ |
#include <errno.h> |
#include <unistd.h> |
#include <malloc.h> |
//#include <stdio.h> |
#include <string.h> |
#include <ipc/ipc.h> |
#include <sys/mman.h> |
#include "../../err.h" |
#include "../generic_field.h" |
#include "packet_header.h" |
#include "packet.h" |
#define PACKET_MAGIC_VALUE 0x11227788 |
// TODO power of 2 aritmetic => div and mod speedup? |
#define PACKET_MAP_SIZE 100 |
struct packet{ |
size_t length; |
size_t max_prefix; |
size_t max_content; |
size_t data_start; |
size_t data_end; |
int magic_value; |
}; |
#define PACKET_MAP_PAGE( packet_id ) ((( packet_id ) - 1 ) / PACKET_MAP_SIZE ) |
#define PACKET_MAP_INDEX( packet_id ) ((( packet_id ) - 1 ) % PACKET_MAP_SIZE ) |
int packet_is_valid( packet_t packet ); |
packet_t packet_create( size_t max_prefix, size_t max_content, size_t max_sufix ){ |
size_t length; |
packet_t packet; |
int packet_destroy( packet_t packet ); |
length = max_prefix + max_content + max_sufix; |
packet = ( packet_t ) mmap( NULL, sizeof( struct packet ) + length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0 ); |
if( packet == MAP_FAILED ) return NULL; |
packet->length = length; |
packet->max_prefix = max_prefix; |
packet->max_content = max_content; |
packet->data_start = sizeof( struct packet ) + packet->max_prefix; |
packet->data_end = packet->data_start; |
packet->magic_value = PACKET_MAGIC_VALUE; |
return packet; |
typedef packet_t packet_map_t[ PACKET_MAP_SIZE ]; |
typedef packet_map_t * packet_map_ref; |
GENERIC_FIELD_DECLARE( gpm, packet_map_t ); |
GENERIC_FIELD_IMPLEMENT( gpm, packet_map_t ); |
static struct{ |
// TODO lock |
gpm_t map; |
} pm_globals; |
int packet_destroy( packet_t packet ){ |
if( ! packet_is_valid( packet )) return EINVAL; |
return munmap( packet, packet->length ); |
} |
int packet_is_valid( packet_t packet ){ |
return packet && ( packet->magic_value == PACKET_MAGIC_VALUE ); |
int pm_init( void ){ |
return gpm_initialize( & pm_globals.map ); |
} |
packet_t packet_copy( packet_t packet ){ |
packet_t new; |
packet_t pm_find( packet_id_t packet_id ){ |
packet_map_ref map; |
if( ! packet_is_valid( packet )) return NULL; |
new = ( packet_t ) mmap( NULL, packet->length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0 ); |
if( new == MAP_FAILED ) return NULL; |
memcpy( new, packet, packet->length ); |
return new; |
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( ! map ) return NULL; |
return ( * map )[ PACKET_MAP_INDEX( packet_id ) ]; |
} |
int packet_copy_data( packet_t packet, void * data, size_t length ){ |
if( ! packet_is_valid( packet )) return EINVAL; |
if( packet->data_start + length >= (( size_t ) packet ) + packet->length ) return ENOMEM; |
memcpy( packet + packet->data_start, data, length ); |
if( packet->data_start + length > packet->data_end ){ |
packet->data_end = packet->data_start + length; |
int pm_add( packet_t packet ){ |
ERROR_DECLARE; |
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 )); |
}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 ){ |
free( map ); |
return ERROR_CODE; |
} |
}while( PACKET_MAP_PAGE( packet->packet_id ) >= gpm_count( & pm_globals.map )); |
} |
( * map )[ PACKET_MAP_INDEX( packet->packet_id ) ] = packet; |
return EOK; |
} |
void * packet_prepend( packet_t packet, size_t length ){ |
if(( ! packet_is_valid( packet )) || ( packet->data_start - sizeof( struct packet ) < length )) return NULL; |
packet->data_start -= length; |
return packet + packet->data_start; |
} |
void pm_destroy( void ){ |
int count; |
int index; |
packet_map_ref map; |
packet_t packet; |
void * packet_append( packet_t packet, size_t length ){ |
if(( ! packet_is_valid( packet )) || ( packet->data_end + length >= (( size_t ) packet ) + packet->length )) return NULL; |
packet->data_end += length; |
return packet + packet->data_end - length; |
count = gpm_count( & pm_globals.map ); |
while( count > 0 ){ |
map = gpm_get_index( & pm_globals.map, count - 1 ); |
for( index = PACKET_MAP_SIZE - 1; index >= 0; -- index ){ |
packet = ( * map )[ index ]; |
if( packet_is_valid( packet )){ |
munmap( packet, packet->length ); |
} |
} |
} |
gpm_destroy( & pm_globals.map ); |
} |
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; |
packet->data_start += prefix; |
packet->data_end -= sufix; |
return EOK; |
} |
packet_t pq_add( packet_t first, packet_t packet, int order, size_t metric ){ |
packet_t item; |
int packet_send( packet_t packet, int phone ){ |
if( ! packet_is_valid( packet )) return EINVAL; |
return ipc_share_out_start( phone, packet, PROTO_READ | PROTO_WRITE ); |
if( ! packet_is_valid( packet )) return NULL; |
pq_set( packet, order, metric ); |
if( packet_is_valid( first )){ |
item = first; |
do{ |
if( item->order < order ){ |
if( item->next ){ |
item = pm_find( item->next ); |
}else{ |
item->next = packet->packet_id; |
packet->previous = item->packet_id; |
return first; |
} |
}else{ |
packet->previous = item->previous; |
packet->next = item->packet_id; |
item->previous = packet->packet_id; |
item = pm_find( packet->previous ); |
if( item ) item->next = packet->packet_id; |
return item; |
} |
}while( packet_is_valid( item )); |
} |
return packet; |
} |
int packet_receive( packet_ref packet ){ |
ERROR_DECLARE; |
packet_t pq_detach( packet_t packet ){ |
packet_t next; |
packet_t previous; |
ipc_callid_t callid; |
size_t size; |
int flags; |
if( ! packet ) return EINVAL; |
if( ! ipc_share_out_receive( & callid, & size, & flags )) return EINVAL; |
* packet = ( packet_t ) as_get_mappable_page( size ); |
if( !( * packet )) return ENOMEM; |
if( ERROR_OCCURED( ipc_share_out_finalize( callid, * packet ))){ |
munmap( * packet, size ); |
return ERROR_CODE; |
if( ! packet_is_valid( packet )) return NULL; |
next = pm_find( packet->next ); |
if( next ){ |
next->previous = packet->previous; |
previous = pm_find( next->previous ); |
if( previous ){ |
previous->next = next->packet_id; |
} |
} |
return EOK; |
packet->previous = 0; |
packet->next = 0; |
return next; |
} |
int packet_destroy( packet_t packet ){ |
int pq_set( packet_t packet, int order, size_t metric ){ |
if( ! packet_is_valid( packet )) return EINVAL; |
return munmap( packet, sizeof( struct packet ) + packet->length ); |
packet->order = order; |
packet->metric = metric; |
return EOK; |
} |
size_t packet_get_data_length( packet_t packet ){ |
if( ! packet_is_valid( packet )) return 0; |
return packet->data_end - packet->data_start; |
} |
void pq_destroy( packet_t first, void ( * packet_release )( packet_t packet )){ |
packet_t actual; |
packet_t next; |
void * packet_get_data( packet_t packet ){ |
if( ! packet_is_valid( packet )) return NULL; |
return packet + packet->data_start; |
actual = first; |
while( packet_is_valid( actual )){ |
next = pm_find( actual->next ); |
actual->next = 0; |
actual->previous = 0; |
if( packet_release ) packet_release( actual ); |
actual = next; |
} |
} |
/** @} |
/branches/network/uspace/srv/net/structures/packet/packet_client.h |
---|
0,0 → 1,68 |
/* |
* 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 |
*/ |
#ifndef __NET_PACKET_CLIENT_H__ |
#define __NET_PACKET_CLIENT_H__ |
#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 )) |
void * packet_prepend( packet_t packet, size_t length ); |
void * packet_append( packet_t packet, size_t length ); |
packet_t packet_copy( int phone, services_t owner, const packet_t packet ); |
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 ); |
size_t packet_get_data_length( const packet_t packet ); |
void * packet_get_data( const packet_t packet ); |
int packet_get_addr( const packet_t packet, uint8_t ** src, uint8_t ** dest ); |
packet_mode_t packet_get_mode( const packet_t packet ); |
int packet_set_addr( packet_t packet, const uint8_t * src, const uint8_t * dest, size_t addr_len ); |
int packet_set_mode( packet_t packet, packet_mode_t mode ); |
int packet_set_owner( packet_t packet, services_t owner ); |
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 ); |
packet_t packet_get_1( int phone, services_t owner, size_t content ); |
void packet_release( int phone, packet_id_t packet_id ); |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |
/branches/network/uspace/srv/net/structures/packet/packet.h |
---|
27,7 → 27,7 |
*/ |
/** @addtogroup net |
* @{ |
* @{ |
*/ |
/** @file |
36,26 → 36,28 |
#ifndef __NET_PACKET_H__ |
#define __NET_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 )) |
typedef unsigned int packet_id_t; |
typedef struct packet * packet_t; |
typedef packet_t * packet_ref; |
packet_t packet_create( size_t max_prefix, size_t max_content, size_t max_sufix ); |
void * packet_prepend( packet_t packet, size_t length ); |
void * packet_append( packet_t packet, size_t length ); |
packet_t packet_copy( packet_t packet ); |
int packet_copy_data( packet_t packet, void * data, size_t length ); |
// TODO protocol identification? |
int packet_send( packet_t packet, int phone ); |
int packet_receive( packet_ref packet ); |
int packet_trim( packet_t packet, size_t prefix, size_t sufix ); |
int packet_destroy( packet_t packet ); |
size_t packet_get_data_length( packet_t packet ); |
void * packet_get_data( packet_t packet ); |
typedef enum packet_mode packet_mode_t; |
enum packet_mode{ |
PM_ONEWAY, |
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 ); |
packet_t pq_add( packet_t first, packet_t packet, int order, size_t metric ); |
packet_t pq_detach( packet_t packet ); |
int pq_set( packet_t packet, int order, size_t metric ); |
void pq_destroy( packet_t first, void ( * packet_release )( packet_t packet )); |
#endif |
/** @} |
/branches/network/uspace/srv/net/structures/packet/packet_server.c |
---|
0,0 → 1,193 |
/* |
* 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 <align.h> |
#include <errno.h> |
//#include <stdio.h> |
#include <unistd.h> |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include <sys/mman.h> |
#include "../../err.h" |
#include "../../messages.h" |
#include "packet.h" |
#include "packet_header.h" |
#include "packet_server.h" |
#define IPC_GET_ID( call ) ( packet_id_t ) IPC_GET_ARG1( * call ) |
#define IPC_GET_OWNER( call ) ( services_t ) IPC_GET_ARG1( * call ) |
#define IPC_GET_CONTENT( call ) ( size_t ) IPC_GET_ARG2( * call ) |
#define IPC_GET_ADDR_LEN( call ) ( size_t ) IPC_GET_ARG3( * call ) |
#define IPC_GET_PREFIX( call ) ( size_t ) IPC_GET_ARG4( * call ) |
#define IPC_GET_SUFIX( call ) ( size_t ) IPC_GET_ARG5( * call ) |
#define FREE_QUEUES_COUNT 7 |
static struct{ |
packet_t free[ FREE_QUEUES_COUNT ]; |
int sizes[ FREE_QUEUES_COUNT ]; |
unsigned int count; |
} ps_globals = { |
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL }, |
{ PAGE_SIZE, PAGE_SIZE * 2, PAGE_SIZE * 4, PAGE_SIZE * 8, PAGE_SIZE * 16, PAGE_SIZE * 32, PAGE_SIZE * 64 }, |
0 |
}; |
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 ); |
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 ){ |
packet_t packet; |
* answer_count = 0; |
switch( IPC_GET_METHOD( * call )){ |
case IPC_M_PHONE_HUNGUP: |
return EOK; |
case NET_PACKET_CREATE_1: |
packet = packet_get( IPC_GET_OWNER( call ), 0, 0, IPC_GET_CONTENT( call ), 0 ); |
if( ! packet ) return ENOMEM; |
* answer_count = 2; |
IPC_SET_ARG1( * answer, packet->packet_id ); |
IPC_SET_ARG2( * answer, packet->length ); |
return EOK; |
case NET_PACKET_CREATE_5: |
packet = packet_get( IPC_GET_OWNER( call ), IPC_GET_ADDR_LEN( call ), IPC_GET_PREFIX( call ), IPC_GET_CONTENT( call ), IPC_GET_SUFIX( call )); |
if( ! packet ) return ENOMEM; |
* answer_count = 2; |
IPC_SET_ARG1( * answer, packet->packet_id ); |
IPC_SET_ARG2( * answer, packet->length ); |
return EOK; |
case NET_PACKET_GET: |
packet = pm_find( IPC_GET_ID( call )); |
if( ! packet_is_valid( packet )) return ENOENT; |
return packet_reply( packet ); |
case NET_PACKET_GET_SIZE: |
packet = pm_find( IPC_GET_ID( call )); |
if( ! packet_is_valid( packet )) return ENOENT; |
* answer_count = 1; |
IPC_SET_ARG1( * answer, packet->length ); |
return EOK; |
case NET_PACKET_RELEASE: |
packet = pm_find( IPC_GET_ID( call )); |
if( ! packet_is_valid( packet )) return ENOENT; |
pq_destroy( packet, packet_release ); |
return EOK; |
} |
return ENOTSUP; |
} |
void packet_release( packet_t packet ){ |
int index; |
for( index = 0; ( index < FREE_QUEUES_COUNT - 1 ) && ( packet->length > ps_globals.sizes[ index ] ); ++ index ); |
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 ){ |
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 ); |
for( index = 0; index < FREE_QUEUES_COUNT - 1; ++ index ){ |
if( length <= ps_globals.sizes[ index ] ){ |
packet = ps_globals.free[ index ]; |
while( packet_is_valid( packet ) && ( packet->length < length )){ |
packet = pm_find( packet->next ); |
} |
if( packet ){ |
packet_init( packet, owner, addr_len, max_prefix, max_content, max_sufix ); |
return packet; |
} |
} |
} |
return packet_create( length, owner, addr_len, max_prefix, max_content, 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 ){ |
ERROR_DECLARE; |
packet_t packet; |
packet = ( packet_t ) mmap( NULL, length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0 ); |
if( packet == MAP_FAILED ) return NULL; |
++ ps_globals.count; |
packet->packet_id = ps_globals.count; |
packet->mode = PM_ONEWAY; |
packet->length = length; |
packet_init( packet, owner, addr_len, max_prefix, max_content, max_sufix ); |
packet->magic_value = PACKET_MAGIC_VALUE; |
if( ERROR_OCCURED( pm_add( packet ))){ |
munmap( packet, packet->length ); |
return NULL; |
} |
packet_release( packet ); |
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 ){ |
packet->owner = owner; |
packet->order = 0; |
packet->metric = 0; |
packet->previous = 0; |
packet->next = 0; |
packet->addr_len = addr_len; |
packet->src_addr = sizeof( struct packet ); |
packet->dest_addr = packet->src_addr + packet->addr_len; |
packet->max_prefix = max_prefix; |
packet->max_content = max_content; |
packet->data_start = packet->dest_addr + packet->addr_len + packet->max_prefix; |
packet->data_end = packet->data_start; |
} |
int packet_reply( const packet_t packet ){ |
ipc_callid_t callid; |
size_t size; |
if( ! packet_is_valid( packet )) return EINVAL; |
if( ipc_share_in_receive( & callid, & size ) <= 0 ) return EINVAL; |
if( size != packet->length ) return ENOMEM; |
return ipc_share_in_finalize( callid, packet, PROTO_READ | PROTO_WRITE ); |
} |
/** @} |
*/ |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |