Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

mctxrx.h

Go to the documentation of this file.
00001 
00002 /*
00003 ** Copyright (C) 2004 Russell Leighton
00004 **
00005 ** This program is free software; you can redistribute it and/or modify
00006 ** it under the terms of the GNU General Public License as published by
00007 ** the Free Software Foundation; either version 2 of the License, or
00008 ** (at your option) any later version.
00009 **
00010 ** This program is distributed in the hope that it will be useful,
00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 ** GNU General Public License for more details.
00014 **
00015 ** You should have received a copy of the GNU General Public License
00016 ** along with this program; if not, write to the Free Software
00017 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 */
00019 
00020 
00021 #ifndef __AWHANDLER_MCTXRX__
00022 #define __AWHANDLER_MCTXRX__
00023 
00024 #include "bitvector.h"
00025 
00026 /* shared data structures between tx and rx */
00027 
00028 /* default max tx rate in Mbps */
00029 #define AW_MCTXRX_DEFAULT_MAX_TX_RATE 80
00030 
00031 /* default ip and port  */
00032 #define AW_MCTXRX_DEFAULT_MCAST_GROUP "224.0.0.1"
00033 #define AW_MCTXRX_DEFAULT_MCAST_PORT 1800
00034 #define AW_MCTXRX_DEFAULT_RETX_PORT 1801
00035 
00036 /* default re-transmit timeout */
00037 #define AW_MCTX_DEFAULT_RETX_TIMEOUT (3*AW_TIMESTAMP_PER_SEC)
00038 #define AW_MCRX_DEFAULT_RETX_TIMEOUT (1*AW_TIMESTAMP_PER_SEC)
00039 
00040 /* NOTE: version MUST change if you change msg structures */
00041 #define AW_MCTXRX_MSG_VERSION 1
00042 
00043 #define AW_MCTXRX_MAX_PATHLEN 256
00044 
00045 /* NOTE: all integers sent in "network" byte order */
00046 
00047 /* basic message header */
00048 typedef struct {
00049     
00050   /* version of message format */
00051   u_int16_t
00052    version;
00053 
00054   /* unique (per tx) transaction id, this plus tx ip address should be unique */
00055   u_int32_t
00056    xtnid;
00057 
00058   /* block of file xfer, if 0 is info block */
00059   int32_t
00060    blockid;
00061 
00062   /* size in bytes of the payload data that follows */
00063   u_int16_t
00064    payload_size;
00065 
00066   /* ptr to start of payload */
00067   void
00068    *payload;
00069 
00070 } aw_mctxrx_msghdr_t;
00071 
00072 /* meta info for file xfer */
00073 typedef struct {
00074 
00075   /* string holding path of file */
00076   byte_t
00077    filename[AW_MCTXRX_MAX_PATHLEN];
00078 
00079   /* file size */
00080   u_int64_t
00081    filesize;
00082 
00083   /* number of total blocks in xfer */
00084   u_int32_t
00085    nblocks;
00086 
00087   /* blocksize in xfer EXCEPT last block */
00088   u_int16_t
00089    blocksize;
00090 
00091   /* port sender is listening for retx packets */
00092   u_int16_t
00093    retxport;
00094 
00095 } aw_mctxrx_info_t;
00096 
00097 /* safe max payload, slightly smaller than it needs to be...
00098    account for header plus some safety padding
00099  */
00100 #define AW_MCTXRX_MAX_PAYLOAD_SIZE (  65000 - sizeof(aw_mctxrx_msghdr_t) - 8 )
00101 #define AW_MCTXRX_DEFAULT_PAYLOAD_SIZE 27500
00102 
00103 /* write info into message data, return message size */
00104 inline static u_int32_t mctxrx_create_infomsg(u_int32_t xtnid, aw_mctxrx_info_t *info, byte_t *msg)
00105 {
00106 
00107   /* version first 2 bytes */
00108   {
00109     *((u_int16_t *)msg) = htons(AW_MCTXRX_MSG_VERSION);
00110   }
00111 
00112   /* transaction id follows for 4 bytes */
00113   {
00114     *((u_int32_t *)(msg + 2)) = htonl(xtnid);
00115   }
00116 
00117   /* block id follows for 4 bytes */
00118   {
00119     *((u_int32_t *)(msg + 6)) = htonl(0);
00120   }
00121 
00122   /* payload size follows for 2 bytes */
00123   {
00124     /* sum the elements in the info struct, CAN'T use sizeof() due to potential padding */
00125     *((u_int16_t *)(msg + 10)) = htons( AW_MCTXRX_MAX_PATHLEN + 8 + 4 + 2);
00126   }
00127 
00128   /* filename follows for AW_MCTXRX_MAX_PATHLEN bytes */
00129   {
00130     strncpy(msg + 12, info->filename, AW_MCTXRX_MAX_PATHLEN);
00131   }
00132 
00133   /* filesize follows for 8 bytes */
00134   {
00135     *( (u_int64_t *)(msg + 12 + AW_MCTXRX_MAX_PATHLEN) ) = htonll(info->filesize);
00136   }
00137 
00138   /* number of blocks to be sent follows for 4 bytes */
00139   {
00140     *((u_int32_t *)(msg + 12 + AW_MCTXRX_MAX_PATHLEN + 8)) = htonl(info->nblocks);
00141   }
00142 
00143   /* blocksize follows for 2 bytes */
00144   {
00145     /* sum the elements in the info struct, CAN'T use sizeof() due to potential padding */
00146     *((u_int16_t *)(msg + 12 + AW_MCTXRX_MAX_PATHLEN + 8 + 4)) = htons( info->blocksize );
00147   }
00148 
00149   /* retxport follows for 2 bytes */
00150   {
00151     /* sum the elements in the info struct, CAN'T use sizeof() due to potential padding */
00152     *((u_int16_t *)(msg + 12 + AW_MCTXRX_MAX_PATHLEN + 8 + 4 + 2)) = htons( info->retxport );
00153   }
00154 
00155   return 12 + AW_MCTXRX_MAX_PATHLEN + 8 + 4 + 2 + 2;
00156 }
00157 
00158 /* write data block into message data, return message size on success, else there was a read error */
00159 inline static int32_t mctxrx_create_datamsg(u_int32_t xtnid, u_int32_t blockid, 
00160                                             u_int16_t payload_size, int32_t fd,
00161                                             byte_t *msg)
00162 {
00163   /* version first 2 bytes */
00164   {
00165     *((u_int16_t *)msg) = htons(AW_MCTXRX_MSG_VERSION);
00166   }
00167 
00168   /* transaction id follows for 4 bytes */
00169   {
00170     *((u_int32_t *)(msg + 2)) = htonl(xtnid);
00171   }
00172 
00173   /* block id follows for 4 bytes */
00174   {
00175     *((u_int32_t *)(msg + 6)) = htonl(blockid);
00176   }
00177 
00178   /* payload size follows for 2 bytes */
00179   {
00180     *((u_int16_t *)(msg + 10)) = htons( payload_size );
00181   }
00182 
00183   if ( payload_size && read(fd, msg + 12, payload_size) != payload_size )
00184     return -1;
00185   else
00186     return 12 + payload_size ;
00187 
00188 }
00189 
00190 /* bitvector into message data, return message size on success */
00191 inline static int32_t mctxrx_create_retxmsg(u_int32_t xtnid, 
00192                                             aw_bitvector_t *bv,
00193                                             byte_t *msg)
00194 {
00195   int32_t
00196     payload_size = AW_BITVECTOR_GET_VECTOR_SIZE(bv) + sizeof(*bv);
00197 
00198   /* important to keep this in sync with bitvector.h */
00199   assert( sizeof(*bv) == sizeof(u_int32_t) );
00200 
00201   /* version first 2 bytes */
00202   {
00203     *((u_int16_t *)msg) = htons(AW_MCTXRX_MSG_VERSION);
00204   }
00205 
00206   /* transaction id follows for 4 bytes */
00207   {
00208     *((u_int32_t *)(msg + 2)) = htonl(xtnid);
00209   }
00210 
00211   /* block id follows for 4 bytes */
00212   {
00213     *((u_int32_t *)(msg + 6)) = htonl(~0); /* all 1's indicates not a valid block */
00214   }
00215 
00216   /* payload size follows for 2 bytes */
00217   {
00218     *((u_int16_t *)(msg + 10)) = htons( payload_size );
00219   }
00220 
00221   /* take each u_int32_t to network byte order */
00222   {
00223     u_int32_t
00224       i,
00225       nwords = payload_size / sizeof(u_int32_t),
00226       *words = (u_int32_t *)(msg + 12);
00227 
00228     /* copy data */
00229     memcpy(words, bv, payload_size );
00230 
00231     /* convert words to network order */
00232     for(i=0; i<nwords; i++) words[i] = htonl( words[i] );
00233   }
00234 
00235   return 12 + payload_size ;
00236 
00237 }
00238 
00239 
00240 /* read msg header, return 0 on success */
00241 inline static int32_t mctxrx_extract_msghdr(aw_mctxrx_msghdr_t *hdr, byte_t *msg)
00242 {
00243 
00244   /* version first 2 bytes */
00245   {
00246     hdr->version = ntohs( *((u_int16_t *)msg) );
00247   }
00248 
00249   /* validate */
00250   if (hdr->version != AW_MCTXRX_MSG_VERSION ) return -1;
00251 
00252   /* transaction id follows for 4 bytes */
00253   {
00254     hdr->xtnid = ntohl( *((u_int32_t *)(msg + 2)) );
00255   }
00256 
00257   /* block id follows for 4 bytes */
00258   {
00259     hdr->blockid = ntohl( *((u_int32_t *)(msg + 6)) );
00260   }
00261 
00262   /* payload size follows for 2 bytes */
00263   {
00264     hdr->payload_size = ntohs( *((u_int16_t *)(msg + 10)) );
00265   }
00266 
00267   /* set to rest of message */
00268   hdr->payload = msg + 12;
00269 
00270   return 0 ;
00271 }
00272 
00273 /* read info, return 0 on success */
00274 inline static int32_t mctxrx_extract_info(aw_mctxrx_info_t *info, aw_mctxrx_msghdr_t *hdr)
00275 {
00276   /* only 0 has info! */
00277   if ( hdr->blockid != 0 ) return -1;
00278 
00279   /* filename follows for AW_MCTXRX_MAX_PATHLEN bytes */
00280   {
00281     strncpy(info->filename, hdr->payload, AW_MCTXRX_MAX_PATHLEN);
00282     info->filename[AW_MCTXRX_MAX_PATHLEN -1] = 0; /* string safety! */
00283   }
00284 
00285   /* filesize follows for 8 bytes */
00286   {
00287     info->filesize = ntohll ( *( (u_int64_t *)(hdr->payload + AW_MCTXRX_MAX_PATHLEN) ) );
00288   }
00289 
00290   /* number of blocks to be sent follows for 4 bytes */
00291   {
00292     info->nblocks =  ntohl( *((u_int32_t *)(hdr->payload + AW_MCTXRX_MAX_PATHLEN + 8)) );
00293   }
00294 
00295   /* blocksize follows for 2 bytes */
00296   {
00297     info->blocksize =  ntohs( *((u_int16_t *)(hdr->payload + AW_MCTXRX_MAX_PATHLEN + 8 + 4)) );
00298   }
00299 
00300   /* retxport follows for 2 bytes */
00301   {
00302     info->retxport =  ntohs( *((u_int16_t *)(hdr->payload + AW_MCTXRX_MAX_PATHLEN + 8 + 4 + 2)) );
00303   }
00304 
00305 
00306   return 0 ;
00307 }
00308 
00309 /* extract a bitvector, dynamically allocated. Return NULL on failure */
00310 inline static aw_bitvector_t *mctxrx_extract_retxmsg(aw_mctxrx_msghdr_t *hdr)
00311 {
00312   aw_bitvector_t
00313     *bv = NULL;
00314 
00315   /* important to keep this in sync with bitvector.h */
00316   assert( sizeof(*bv) == sizeof(u_int32_t) );
00317 
00318   /* all 1's is a re-tx */
00319   if ( hdr->blockid != ~0 ) goto done;
00320 
00321   bv = aw_bitvector_create( 8*(hdr->payload_size - sizeof(*bv)) );
00322   if (bv == NULL) goto done;
00323 
00324   /* convert msg to host order and copy */
00325   {
00326     u_int32_t
00327       i,
00328       nwords = hdr->payload_size / sizeof(u_int32_t),
00329       *words = (u_int32_t *)(hdr->payload);
00330 
00331     /* convert words to network order */
00332     for(i=0; i<nwords; i++) words[i] = ntohl( words[i] );
00333 
00334     /* copy */
00335     *bv = *( (aw_bitvector_t *)(hdr->payload) );
00336     memcpy(AW_BITVECTOR_GET_VECTOR(bv), hdr->payload + sizeof(*bv), (nwords*sizeof(u_int32_t)) - sizeof(*bv));
00337 
00338   }
00339 
00340  done:;
00341 
00342   return bv;
00343 }
00344 
00345 #endif
Aware 0.11.1 Copyright (C) 1998-2005 Russell Leighton (russ@elegant-software.com)