packet_client.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2009 Lukas Mejdrech
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00037 #include <errno.h>
00038 #include <mem.h>
00039 #include <unistd.h>
00040 #include <sys/mman.h>
00041 
00042 #include <packet_client.h>
00043 #include <packet_remote.h>
00044 
00045 #include <net/packet.h>
00046 #include <net/packet_header.h>
00047 
00059 int packet_copy_data(packet_t *packet, const void *data, size_t length)
00060 {
00061         if (!packet_is_valid(packet))
00062                 return EINVAL;
00063 
00064         if (packet->data_start + length >= packet->length)
00065                 return ENOMEM;
00066 
00067         memcpy((void *) packet + packet->data_start, data, length);
00068         if (packet->data_start + length > packet->data_end) 
00069                 packet->data_end = packet->data_start + length;
00070 
00071         return EOK;
00072 }
00073 
00083 void *packet_prefix(packet_t *packet, size_t length)
00084 {
00085         if ((!packet_is_valid(packet)) ||
00086             (packet->data_start - sizeof(packet_t) -
00087             2 * (packet->dest_addr - packet->src_addr) < length)) {
00088                 return NULL;
00089         }
00090 
00091         packet->data_start -= length;
00092         return (void *) packet + packet->data_start;
00093 }
00094 
00104 void *packet_suffix(packet_t *packet, size_t length)
00105 {
00106         if ((!packet_is_valid(packet)) ||
00107             (packet->data_end + length >= packet->length)) {
00108                 return NULL;
00109         }
00110 
00111         packet->data_end += length;
00112         return (void *) packet + packet->data_end - length;
00113 }
00114 
00126 int packet_trim(packet_t *packet, size_t prefix, size_t suffix)
00127 {
00128         if (!packet_is_valid(packet))
00129                 return EINVAL;
00130 
00131         if (prefix + suffix > PACKET_DATA_LENGTH(packet))
00132                 return ENOMEM;
00133 
00134         packet->data_start += prefix;
00135         packet->data_end -= suffix;
00136         return EOK;
00137 }
00138 
00145 packet_id_t packet_get_id(const packet_t *packet)
00146 {
00147         return packet_is_valid(packet) ? packet->packet_id : 0;
00148 }
00149 
00159 int packet_get_addr(const packet_t *packet, uint8_t **src, uint8_t **dest)
00160 {
00161         if (!packet_is_valid(packet))
00162                 return EINVAL;
00163         if (!packet->addr_len)
00164                 return 0;
00165         if (src)
00166                 *src = (void *) packet + packet->src_addr;
00167         if (dest)
00168                 *dest = (void *) packet + packet->dest_addr;
00169 
00170         return packet->addr_len;
00171 }
00172 
00179 size_t packet_get_data_length(const packet_t *packet)
00180 {
00181         if (!packet_is_valid(packet))
00182                 return 0;
00183 
00184         return PACKET_DATA_LENGTH(packet);
00185 }
00186 
00193 void *packet_get_data(const packet_t *packet)
00194 {
00195         if (!packet_is_valid(packet))
00196                 return NULL;
00197 
00198         return (void *) packet + packet->data_start;
00199 }
00200 
00211 int
00212 packet_set_addr(packet_t *packet, const uint8_t *src, const uint8_t *dest,
00213     size_t addr_len)
00214 {
00215         size_t padding;
00216         size_t allocated;
00217 
00218         if (!packet_is_valid(packet))
00219                 return EINVAL;
00220 
00221         allocated = PACKET_MAX_ADDRESS_LENGTH(packet);
00222         if (allocated < addr_len)
00223                 return ENOMEM;
00224 
00225         padding = allocated - addr_len;
00226         packet->addr_len = addr_len;
00227 
00228         if (src) {
00229                 memcpy((void *) packet + packet->src_addr, src, addr_len);
00230                 if (padding)
00231                         bzero((void *) packet + packet->src_addr + addr_len,
00232                             padding);
00233         } else {
00234                 bzero((void *) packet + packet->src_addr, allocated);
00235         }
00236 
00237         if (dest) {
00238                 memcpy((void *) packet + packet->dest_addr, dest, addr_len);
00239                 if (padding)
00240                         bzero((void *) packet + packet->dest_addr + addr_len,
00241                             padding);
00242         } else {
00243                 bzero((void *) packet + packet->dest_addr, allocated);
00244         }
00245 
00246         return EOK;
00247 }
00248 
00259 packet_t *packet_get_copy(int phone, packet_t *packet)
00260 {
00261         packet_t *copy;
00262         uint8_t * src = NULL;
00263         uint8_t * dest = NULL;
00264         size_t addrlen;
00265 
00266         if (!packet_is_valid(packet))
00267                 return NULL;
00268 
00269         /* Get a new packet */
00270         copy = packet_get_4_remote(phone, PACKET_DATA_LENGTH(packet),
00271             PACKET_MAX_ADDRESS_LENGTH(packet), packet->max_prefix,
00272             PACKET_MIN_SUFFIX(packet));
00273         if (!copy)
00274                 return NULL;
00275 
00276         /* Get addresses */
00277         addrlen = packet_get_addr(packet, &src, &dest);
00278         /* Copy data */
00279         if ((packet_copy_data(copy, packet_get_data(packet),
00280             PACKET_DATA_LENGTH(packet)) == EOK) &&
00281             /* Copy addresses if present */
00282             ((addrlen <= 0) ||
00283             (packet_set_addr(copy, src, dest, addrlen) == EOK))) {
00284                 copy->order = packet->order;
00285                 copy->metric = packet->metric;
00286                 return copy;
00287         } else {
00288                 pq_release_remote(phone, copy->packet_id);
00289                 return NULL;
00290         }
00291 }
00292 

Generated on Thu Jun 2 07:45:47 2011 for HelenOS/USB by  doxygen 1.4.7