Main Page | Class List | File List | Class Members | File Members

al_sending.c

Go to the documentation of this file.
00001 #include "standard.h"
00002 #include "al_sending.h"
00003 #include "arq.h"
00004 #include "Buffer.h"
00005 #include "rcpc.h"
00006 #include "error.h"
00007 #include "bits.h"
00008 #include "bytes.h"
00009 #include "bch.h"
00010 #include "uep_rcpcc.h"
00011 
00012 extern int debug;
00013 
00014 int al_send_request(al_sending_entity *which, bytes *al_sdu)
00015      /*
00016       * Called by an AL user to send an SDU through a logical channel.  Data
00017       * is put into the al_sending_entity buffer and will be made into an AL_PDU
00018       * and sent when an AL_PDU is requested by the MUX.  Note: the pdu does
00019       * not make it to the remote end in a whole format, ie. the size of it
00020       * may change.
00021       *
00022       * Returns 1 if succesful, 0 if unsuccesful (ie. buffer full)
00023       */
00024 {
00025   int i;
00026   byte b;
00027   
00028   /* 
00029    * check to make sure there's sufficient room in buffer for
00030    * incoming SDU.  If not, fail. 
00031    */
00032   if ((bsize(which->al_sdus)) < num_bytes(al_sdu) + blevel(which->al_sdus))
00033     return 0;
00034   
00035   /* otherwise put the bytes into the buffer and now free it */
00036   for (i=0;i<num_bytes(al_sdu);i++) {
00037     b=get_byte(al_sdu,i);
00038     bwrite(which->al_sdus,&b);
00039   }
00040   
00041   return 1;
00042 }
00043 
00044 int al_send_byte(al_sending_entity *which, unsigned char b)
00045      /* 
00046       * Sends a single byte to an al-sending entity's incoming data buffer.
00047       */
00048 {
00049   if (bsize(which->al_sdus) < (1+blevel(which->al_sdus)))
00050     return (0);
00051   
00052   bwrite(which->al_sdus, &b);
00053   return (1);
00054 }
00055 
00056 int al_request(al_sending_entity *which)
00057      /*
00058       * This function is called by the MUX to see if an al_sending_entity
00059       * has data which needs to be sent.  
00060       *
00061       * Return values:
00062       * 
00063       * 0     When the al_sending_entity has nothing to send.
00064       * -1    There is an ARQ waiting to be requested.
00065       * 1     New data available (no ARQ). 
00066       */
00067 {
00068   int val;
00069   if (blevel(which->forward_arq))
00070     val = -1;
00071   else if (blevel(which->al_sdus))
00072     val = 1;
00073   else
00074     val = 0;
00075   return val;
00076 }
00077 
00078 int al_requested_size(al_sending_entity *which)
00079      /*
00080       * This function is called by the MUX to see how big an ARQ packet needs
00081       * to be sent.  It returns the AL-PDU length needed for the ARQ, or 0 if
00082       * there are no forward ARQ's.
00083       */
00084 {
00085   int i,val=0;
00086   buf_rcpc* grossie;
00087   arq_message* jon;
00088   
00089   if (blevel(which->forward_arq)) {
00090     /*
00091      * return size of al_pdu at top of buffer (plus forward/backward control)
00092      * Check all buf_rcpc's in rcpcs buffer and see which one's sequence 
00093      * number matches the sequence number of the arq message on top of the
00094      * forward_arq buffer
00095      */
00096     
00097     if ((jon = bpeek(which->forward_arq,0)) == NULL) {
00098       printf("al_requested_size() - ERROR forward arq buffer has entries that");
00099       printf(" can't be read!\n");
00100     }
00101     
00102     for(i=0;i<blevel(which->rcpcs);i++) {
00103       grossie = (buf_rcpc *) bpeek(which->rcpcs,i);
00104       if (grossie->sequence_number == jon->sequence_number) {
00105         val = grossie->length;
00106         break;
00107       }
00108     }
00109 
00110     /* add on for control fields */
00111     val += 4; /* for forward control */
00112     if (blevel(which->backward_arq))
00113       val+=4;
00114     if (i == blevel(which->rcpcs)) {
00115       printf("al_requested_size() - ERROR trying to send arq for sequence");
00116       printf(" number not in rcpcs buffer\n"); 
00117     }
00118   }
00119   else
00120     val = 0;
00121  
00122   return val;
00123 }
00124 
00125 int al_buffer_level(al_sending_entity *which)
00126      /*
00127       * This function is called by the MUX to see how much NEW data this channel
00128       * has waiting to send so that it can devise an appropriate multiplex 
00129       * code that assigns a block of data to the channel associated with this
00130       * al_sending_entity.
00131       *
00132       * Also can be called by the al-user (sender) to perform rate control.
00133       * The H.263 encoder does this to control its frame rate. 
00134       */
00135 {
00136   return blevel(which->al_sdus);  /* returns number of BYTEs in buffer */
00137 }
00138 
00139 
00140 void al_arq_request(al_sending_entity *which, arq_message *clone)
00141      /*
00142       * This function is called by the corresponding al_receiving entity
00143       * when it wants to request a retransmission of a particular AL_SDU
00144       * 
00145       */
00146 {
00147   bwrite(which->backward_arq,clone);
00148 }
00149 
00150 void al_arq_received(al_sending_entity *which, arq_message *clone)
00151      /*
00152       * This function is called by the corresponding al_receiving entity
00153       * when it wants to report that a retransmission request has been
00154       * received.  The al_sending_entity saves the incoming arq_message
00155       *   
00156       */
00157 {
00158   bwrite(which->forward_arq,clone);  
00159 }
00160 
00161 
00162 al_sending_entity *new_al_sending_entity( channel_info *nfo)
00163      /*
00164       * Makes a new AL-Sending Entity.  Is passed a struct of channel parameters.
00165       */
00166 
00167 { 
00168   al_sending_entity *new_al;
00169   
00170   new_al = (al_sending_entity *) malloc(sizeof(al_sending_entity));
00171   /*  printf("New al sending entity has address %x\n",new_al); */
00172   if (new_al == NULL) {
00173     error("new_al_sending_entity","can't malloc al_sending entity");
00174   }
00175   else {
00176     new_al->al_sdus = mkbuffer(MAX_AL_BUFFER_SIZE,sizeof(byte));
00177     new_al->rcpcs = mkbuffer(32,sizeof(buf_rcpc));
00178     new_al->forward_arq = mkbuffer(MAX_ARQ_BUFFER_SIZE,sizeof(arq_message));
00179     new_al->backward_arq = mkbuffer(MAX_ARQ_BUFFER_SIZE,sizeof(arq_message));
00180     new_al->vs = 0;
00181 
00182     /* Copy parameters from channel_info *nfo */
00183     new_al->type = nfo->type;
00184     new_al->framed = nfo->framed;
00185     new_al->seq_num = nfo->seq_num;
00186     new_al->rcpc_code = nfo->rcpc_code;
00187     new_al->rcpc_rate = nfo->rcpc_rate;
00188     new_al->arq_type = nfo->arq_type;
00189     new_al->crc_bytes = nfo->crc_bytes;
00190   }
00191   return new_al;
00192 }
00193 
00194 void make_forward_control(bytes *forward_control,unsigned int snf, 
00195                           unsigned int pt,unsigned int rn)
00196      /*
00197       * Makes a (31,11) BCH encoded forward control field with:
00198       *   sequence number forward snf,
00199       *   payload type pt,
00200       *   retransmission number rn,
00201       *  and determines CRCf field.
00202       *
00203       * Returns in forward_control (which will be a pointer to a bytes structure 
00204       * of length 4.  It should just be an empty bytes pointer when passed in) 
00205       *
00206       * (only used in old H.223/Annex A)
00207       */
00208 {
00209   int i;
00210   unsigned int *field;
00211   byte crc;
00212   
00213   field = (unsigned int *) malloc(sizeof(unsigned int));
00214   *field = 0;
00215 
00216     if (field == NULL) error("make_forward_control","can't allocate field");
00217   /* set the snf part of field */
00218   for(i=6;i<=10;i++)
00219     setbitint(field,i,getbitint(snf,i+6));
00220   
00221   /* set the pt part of field */
00222   setbitint(field,11,pt);
00223   
00224   /* set the rn part of field */
00225   setbitint(field,12,rn);
00226   
00227   /* figure out 4 bit CRC and append here */
00228   crc = makecrc4(*field);
00229   *field = *field | crc;
00230   
00231   /* perform (31,11) BCH on it */
00232   encode_bch(*field,forward_control->block,2);
00233   free(field);
00234 }
00235 
00236 void make_backward_control(bytes* backward_control,unsigned int snb,
00237                            unsigned int sm)
00238      /*
00239       * Makes a (31,11) BCH encoded backward control field with:
00240       *   sequence number backward snb,
00241       *   supervisory message sm,
00242       *  and determines CRCb field.
00243       *
00244       * Returns in backward_control (which should be a pointer to an empty 
00245       * bytes structure (ie not initialized))
00246       *
00247       * (only used in old H.223/Annex A)
00248       */
00249 {
00250   int i;
00251   unsigned int *field;
00252   byte *block;
00253   byte crc;
00254   
00255   field = (unsigned int *) malloc(sizeof(unsigned int));
00256   *field = 0;
00257   if (field == NULL)
00258     error("make_backward_control","can't malloc field");
00259   block = (byte *) calloc(4, sizeof(byte));
00260   if (field == NULL)
00261     error("make_backward_control","can't malloc block");
00262   
00263   /* set snb part of field */
00264   for(i=6;i<=10;i++)
00265     setbitint(field,i,getbitint(snb,i+6));
00266   
00267   /* set sm part of field */
00268   for(i=11;i<=12;i++)
00269     setbitint(field,i,getbitint(sm,i+4));
00270   
00271   /* figure out 4 bit CRC and append here */
00272   crc = makecrc4(*field);
00273   printf("al_sending field %x crc %x\n",*field,crc);
00274   *field = *field | crc;
00275   printf("al_sending resulting field %x\n",*field);
00276   
00277   /* perform (31,11) BCH on it */
00278   encode_bch(*field,block,2);
00279   backward_control->block = block;
00280   backward_control->length = 4;
00281   free(field);
00282 }
00283 
00284 
00285 int inc_sn(al_sending_entity *which)
00286      /*
00287       * returns the current sequence number available from which, and
00288       * then increments it.
00289       */
00290 {
00291   int returnval = which->vs;
00292   which->vs = (which->vs + 1) % 32;
00293   return returnval;
00294 }
00295 
00296 
00297 bytes *get_al_pdu(al_sending_entity *which, int size)
00298      /*   
00299       * Constructs an AL-PDU of total size size (including headers, 
00300       * FEC, CRC if appropriate).
00301       * 
00302       * If there is a forward retransmission request to send (and the size 
00303       * compatible) it shall send it.
00304       * If there is a backward_arq message for one or more AL sending entities, 
00305       * it shall include a backward control field.
00306       * (old h.223/a only)
00307       *
00308       */  
00309 {
00310   int i;
00311   bytes *al_pdu=NULL;
00312   byte b;
00313   byte crc8val = 0;
00314   unsigned short crc16val = 0; 
00315 
00316   al_pdu = new_bytes(size);
00317   
00318   if (which->type == AL1) {
00319     /* no crc */
00320     for(i=0; i<size;i++) {
00321       bread(which->al_sdus, &b);
00322       set_byte(al_pdu, i, b);
00323     }
00324   }
00325   else if (which->type == AL2) {
00326     /* add a one byte crc */
00327     for(i=0; i<size-1;i++) {
00328       bread(which->al_sdus, &b);
00329       crc8(&crc8val,b);
00330       set_byte(al_pdu, i, b);
00331     }
00332     set_byte(al_pdu, size - 1, crc8val);
00333   }
00334   else if (which->type == AL3) {
00335     /* add a two byte crc */
00336     for(i=0; i<size-2;i++) {
00337       bread(which->al_sdus, &b);
00338       crc16(&crc16val,b);
00339       set_byte(al_pdu, i, b);
00340     }
00341     set_byte(al_pdu, size - 2, (byte) (crc16val >> 8));
00342     set_byte(al_pdu, size - 1, (byte) crc16val & 0x00FF);
00343   }
00344 
00345   return al_pdu;
00346 }

Generated on Sun Jul 16 16:27:45 2006 by  doxygen 1.3.9.1