Subversion Repositories HelenOS

Rev

Rev 3901 | Rev 3990 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2009 Lukas Mejdrech
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup packet
  30.  *  @{
  31.  */
  32.  
  33. /** @file
  34.  *  Packet client implementation.
  35.  */
  36.  
  37. #include <async.h>
  38. #include <errno.h>
  39. #include <unistd.h>
  40. //#include <stdio.h>
  41. #include <string.h>
  42.  
  43. #include <ipc/ipc.h>
  44. #include <ipc/services.h>
  45. #include <sys/mman.h>
  46.  
  47. #include "../../err.h"
  48. #include "../../messages.h"
  49.  
  50. #include "packet.h"
  51. #include "packet_header.h"
  52. #include "packet_client.h"
  53.  
  54. /** Obtains the packet from the packet server as the shared memory block.
  55.  *  Creates the local packet mapping as well.
  56.  *  @param phone The packet server module phone. Input parameter.
  57.  *  @param packet The packet reference pointer to store the received packet reference. Output parameter.
  58.  *  @param packet_id The packet identifier. Input parameter.
  59.  *  @param size The packet total size in bytes. Input parameter.
  60.  *  @returns EOK on success.
  61.  *  \todo ipc_share_in_start() error?
  62.  *  @returns Other error codes as defined for the pm_add() function.
  63.  */
  64. int packet_return( int phone, packet_ref packet, packet_id_t packet_id, size_t size );
  65.  
  66. packet_t packet_copy( int phone, services_t owner, const packet_t packet ){
  67.     packet_t    new;
  68.  
  69.     if( ! packet_is_valid( packet )) return NULL;
  70. //  new = ( packet_t ) mmap( NULL, packet->length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0 );
  71. //  if( new == MAP_FAILED ) return NULL;
  72. //  memcpy( new, packet, packet->length );
  73.     new = packet_get_1( phone, owner, packet_get_data_length( packet ));
  74.     packet_copy_data( new, packet_get_data( packet ), packet_get_data_length( packet ));
  75.     return new;
  76. }
  77.  
  78. int packet_copy_data( packet_t packet, const void * data, size_t length ){
  79.     if( ! packet_is_valid( packet )) return EINVAL;
  80.     if( packet->data_start + length >= packet->length ) return ENOMEM;
  81.     memcpy(( void * ) packet + packet->data_start, data, length );
  82.     if( packet->data_start + length > packet->data_end ){
  83.         packet->data_end = packet->data_start + length;
  84.     }
  85.     return EOK;
  86. }
  87.  
  88. void * packet_prefix( packet_t packet, size_t length ){
  89.     if(( ! packet_is_valid( packet )) || ( packet->data_start - sizeof( struct packet ) - 2 * packet->addr_len < length )) return NULL;
  90.     packet->data_start -= length;
  91.     return ( void * ) packet + packet->data_start;
  92. }
  93.  
  94. void * packet_suffix( packet_t packet, size_t length ){
  95.     if(( ! packet_is_valid( packet )) || ( packet->data_end + length >= packet->length )) return NULL;
  96.     packet->data_end += length;
  97.     return ( void * ) packet + packet->data_end - length;
  98. }
  99.  
  100. int packet_trim( packet_t packet, size_t prefix, size_t suffix ){
  101.     if( ! packet_is_valid( packet )) return EINVAL;
  102.     if( prefix + suffix > packet->data_end - packet->data_start ) return ENOMEM;
  103.     packet->data_start += prefix;
  104.     packet->data_end -= suffix;
  105.     return EOK;
  106. }
  107.  
  108. packet_id_t packet_get_id( const packet_t packet ){
  109.     return packet_is_valid( packet ) ? packet->packet_id : 0;
  110. }
  111.  
  112. int packet_get_addr( const packet_t packet, uint8_t ** src, uint8_t ** dest ){
  113.     if( !( packet_is_valid( packet ) && src && dest )) return EINVAL;
  114.     if( ! packet->addr_len ) return 0;
  115.     * src = ( void * ) packet + packet->src_addr;
  116.     * dest = ( void * ) packet + packet->dest_addr;
  117.     return packet->addr_len;
  118. }
  119.  
  120. size_t packet_get_data_length( const packet_t packet ){
  121.     if( ! packet_is_valid( packet )) return 0;
  122.     return packet->data_end - packet->data_start;
  123. }
  124.  
  125. void * packet_get_data( const packet_t packet ){
  126.     if( ! packet_is_valid( packet )) return NULL;
  127.     return ( void * ) packet + packet->data_start;
  128. }
  129.  
  130. packet_mode_t packet_get_mode( const packet_t packet ){
  131.     if( packet_is_valid( packet )) return packet->mode;
  132.     return PM_ONE_WAY;
  133. }
  134.  
  135. int packet_set_addr( packet_t packet, const uint8_t * src, const uint8_t * dest, size_t addr_len ){
  136.     size_t  padding;
  137.  
  138.     if( ! packet_is_valid( packet )) return EINVAL;
  139.     if( packet->addr_len >= addr_len ) return ENOMEM;
  140.     padding = packet->addr_len - addr_len;
  141.     if( src ){
  142.         memcpy(( void * ) packet + packet->src_addr, src, addr_len );
  143.         memset(( void * ) packet + packet->src_addr + addr_len, 0, padding );
  144.     }else{
  145.         memset(( void * ) packet + packet->src_addr + addr_len, 0, packet->addr_len );
  146.     }
  147.     if( dest ){
  148.         memcpy(( void * ) packet + packet->dest_addr, dest, addr_len );
  149.         memset(( void * ) packet + packet->dest_addr + addr_len, 0, padding );
  150.     }else{
  151.         memset(( void * ) packet + packet->dest_addr + addr_len, 0, packet->addr_len );
  152.     }
  153.     return EOK;
  154. }
  155.  
  156. int packet_set_mode( packet_t packet, packet_mode_t mode ){
  157.     if( ! packet_is_valid( packet )) return EINVAL;
  158.     packet->mode = mode;
  159.     return EOK;
  160. }
  161.  
  162. int packet_set_owner( packet_t packet, services_t owner ){
  163.     if( ! packet_is_valid( packet )) return EINVAL;
  164.     packet->owner = owner;
  165.     return EOK;
  166. }
  167.  
  168. int packet_translate( int phone, packet_ref packet, packet_id_t packet_id ){
  169.     ERROR_DECLARE;
  170.  
  171.     unsigned int        size;
  172.  
  173.     if( ! packet ) return EINVAL;
  174.     * packet = pm_find( packet_id );
  175.     if( * packet ) return EOK;
  176.     ERROR_PROPAGATE( async_req_1_1( phone, NET_PACKET_GET_SIZE, packet_id, & size ));
  177.     return packet_return( phone, packet, packet_id, size );
  178. }
  179.  
  180. int packet_return( int phone, packet_ref packet, packet_id_t packet_id, size_t size ){
  181.     ERROR_DECLARE;
  182.  
  183.     aid_t       message;
  184.     ipc_call_t  answer;
  185.     ipcarg_t    result;
  186.  
  187.     message = async_send_1( phone, NET_PACKET_GET, packet_id, & answer );
  188.     * packet = ( packet_t ) as_get_mappable_page( size );
  189.     if( ERROR_OCCURRED( ipc_share_in_start_0_0( phone, * packet, size ))
  190.     || ERROR_OCCURRED( pm_add( * packet ))){
  191.         munmap( * packet, size );
  192.         async_wait_for( message, NULL );
  193.         return ERROR_CODE;
  194.     }
  195.     async_wait_for( message, & result );
  196.     return result;
  197. }
  198.  
  199. 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 ){
  200.     ERROR_DECLARE;
  201.  
  202.     packet_id_t packet_id;
  203.     unsigned int size;
  204.     packet_t packet;
  205.  
  206.     if( ERROR_OCCURRED( async_req_5_2( phone, NET_PACKET_CREATE_5, owner, max_content, addr_len, max_prefix, max_suffix, & packet_id, & size ))
  207.     || ERROR_OCCURRED( packet_return( phone, & packet, packet_id, size ))){
  208.         return NULL;
  209.     }
  210.     return packet;
  211. }
  212.  
  213. packet_t packet_get_1( int phone, services_t owner, size_t content ){
  214.     ERROR_DECLARE;
  215.  
  216.     packet_id_t packet_id;
  217.     unsigned int    size;
  218.     packet_t    packet;
  219.  
  220.     if( ERROR_OCCURRED( async_req_2_2( phone, NET_PACKET_CREATE_1, owner, content, & packet_id, & size ))
  221.     || ERROR_OCCURRED( packet_return( phone, & packet, packet_id, size ))){
  222.         return NULL;
  223.     }
  224.     return packet;
  225. }
  226.  
  227. void packet_release( int phone, packet_id_t packet_id ){
  228.     async_msg_1( phone, NET_PACKET_RELEASE, packet_id );
  229. }
  230.  
  231. /** @}
  232.  */
  233.