src/vfer_datagram.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 2005, 2006, Internet2
00003  * Legal conditions are in file LICENSE
00004  * (MD5 = c434f2e53b8089d8b4d0172c7ce07360).
00005  */
00006 /**
00007  *
00008  * @file   vfer_datagram.c
00009  * @author Ivan Beschastnikh
00010  * @brief  Implements datagrams that are defined in datagram.h
00011  *
00012  * -     02/19/06        ivan            added function Datagram_Insert_Phantom
00013  * -     02/18/06        ivan            created
00014  */
00015 
00016 #include "vfer_datagram.h"
00017 #include "vfer.h"
00018 
00019 /**
00020  * Creates a new datagram entry, copies the buffer data into the entry
00021  * and enqueues the datagram into the datagram list.
00022  *
00023  * @param frames datagram list pointer
00024  * @param buffer buffer to include into this datagram (unchanged by this function)
00025  * @param len length of buffer
00026  * @param frame_num frame number to assign to this frame (used in control.c)
00027  *
00028  * @return -1 on error, if allocation of new datagram failed
00029  * @return 0 on succes
00030  */
00031 inline int Datagram_Enqueue(frame_list* frames, const void* buffer, int len, int frame_num) {
00032         frame_link* frame_l;
00033         interval_t* interval_ptr;
00034         
00035         /* create a new frame structure and add it to the frame list passed as argument */
00036         if (ALLOC(frame_l,frame_link*,frame_link,1) == 0)
00037                 return -1;
00038         if (ALLOC(frame_l->frame.data, void*, char, len) == 0) {
00039                 RELEASE(frame_l, sizeof(frame_link));
00040                 return -1;
00041         }
00042         if (ALLOC(interval_ptr, interval_t*, interval_t, 1) == 0) {
00043                 RELEASE(frame_l->frame.data, sizeof(frame_link));
00044                 RELEASE(frame_l, sizeof(frame_link));
00045                 return -1;
00046         }
00047 
00048         if (frames->num == 0)
00049                 frames->first = frame_l;
00050         if (frames->last != NULL)
00051                 frames->last->next = frame_l;
00052 
00053         frames->last = frame_l;
00054         frames->num++;
00055 
00056         /* data copying */
00057         memcpy(frame_l->frame.data, buffer, len);
00058         frame_l->frame.len              = len;
00059         frame_l->frame.urgency          = -1;            /* implies this frame has not been attempted (to be sent) yet : used to send frame_len on first packets */
00060         frame_l->frame.frame_num        = frame_num;
00061         frame_l->next                   = NULL;
00062 
00063         frame_l->frame.missing_data.count = 1;
00064         frame_l->frame.missing_data.head = interval_ptr;
00065         interval_ptr->prev = interval_ptr->next = NULL;
00066         interval_ptr->start = 0;
00067         interval_ptr->end = len;
00068         
00069         frames->length += len; /* add size to total size of frame list */
00070 
00071 //      DEBUG_PRINT(DEBUG_CTL, "datagram.c", "Datagram_Enqueue", "frame_id[%d] frame_len[%d] num_frags[%d] frag_size[%u]; num_frames[%d]", 
00072 //                  frame_l->frame.frame_num, frame_l->frame.len, frame_l->frame.num_frags, frame_l->frame.frag_size, frames->num);
00073 
00074 //      printf("new datagram list:\n");
00075 //      Datagrams_Print(frames);
00076         return 0;
00077 } /* Datagram_Enqueue() */
00078 
00079 
00080 /**
00081  * Dequeues a frame from the frames list and fills in the buffer with
00082  * it's data. Returns -1 if the buffer is not large enough to hold the
00083  * frame's data.
00084  *
00085  * For now we assume that there are frames in the list (has to be
00086  * checked before the call)
00087  *
00088  * @param frames datagram list pointer
00089  * @param buffer buffer to fill with the datagram contents
00090  * @param len max length of buffer to fill
00091  * 
00092  * @return -1 on error, buffer is too small
00093  * @return size of the datagram written to buffer on success
00094  */
00095 inline int Datagram_Dequeue(frame_list* frames, void* buffer, int len) {
00096         int size;
00097         frame_link* frame_l;
00098         frame_l = frames->first;
00099 
00100         DEBUG_PRINT(DEBUG_CTL, "datagram.c", "Datagram_Dequeue", "Returning frame[%d] with len[%d] with recvd->len[%d]", frame_l->frame.frame_num, frame_l->frame.len, frames->num);
00101 
00102         if (frame_l->frame.len > len) {
00103                 return -1;
00104         }
00105 
00106         /* copy datagram into user supplied buffer */
00107         size = frame_l->frame.len;
00108         memcpy (buffer, frame_l->frame.data, size);
00109         frames->length -= size;
00110 
00111         /* remove this frame from the frame list & dealloc */
00112         Datagram_Remove (frames, NULL, frame_l);
00113         RELEASE(frame_l->frame.data, size);
00114         RELEASE(frame_l, sizeof(frame_link));
00115         return size;
00116 } /* Datagram_Dequeue() */
00117 
00118 
00119 /**
00120  * Remove a frame from a frame list
00121  *
00122  * Maintains the last_frame_num, first_frame_num, count, and data byte
00123  * length of frames in the frame list.
00124  *
00125  * @param list          frame list pointer to remove the frame from
00126  * @param prev          previous frame pointer
00127  * @param remove        the frame pointer to remove from the list
00128  */
00129 inline void Datagram_Remove(frame_list* list, frame_link* prev, frame_link* remove) {
00130         if (prev == NULL) {             /* remove from the beginning of the list */
00131                 if (remove != list->first) { /* double check that we are indeed removing first frame */
00132                         ERROR_PRINT("datagram.c", "Datagram_Remove", "removing from beginning of list but frame is not first");
00133                         return;
00134                 }
00135                 if (remove->next != NULL) {
00136                         list->first_frame_num = remove->next->frame.frame_num;
00137                         list->first = remove->next;
00138                 } else {
00139                         list->first = list->last = NULL;
00140                 }
00141         } else {
00142                 prev->next = remove->next;
00143                 if (list->last == remove) {
00144                         list->last_frame_num = prev->frame.frame_num;
00145                         list->last = prev;
00146                 }
00147         }
00148         list->length -= remove->frame.len;
00149         list->num--;
00150 } /* Datagram_Remove() */
00151 
00152 /**
00153  * Inserts a frame into a frame list
00154  * 
00155  * Maintains the last_frame_num, first_frame_num, count, and the data
00156  * byte length of frames in the frame list.
00157  *
00158  * @param list          frame list pointer to insert the new frame link into
00159  * @param prev          frame link before the one to insert
00160  * @param insert        frame link to insert
00161  */
00162 inline void Datagram_Insert(frame_list* list, frame_link* prev, frame_link* insert) {
00163         if (prev == NULL) {
00164                 /* insert at beginning of list */
00165                 insert->next = list->first;
00166                 list->first = insert;
00167                 if (list->last == NULL) {
00168                         list->last = insert;
00169                         list->last_frame_num = insert->frame.frame_num;;
00170                 }
00171                 list->first_frame_num = insert->frame.frame_num;
00172         } else {
00173                 insert->next = prev->next;
00174                 prev->next = insert;
00175                 if (list->last == prev) {
00176                         list->last_frame_num = insert->frame.frame_num;
00177                         list->last = insert;
00178                 }
00179         }
00180         list->length += insert->frame.len;
00181         list->num++;
00182 } /* Datagram_Insert() */
00183 
00184 /*
00185  * Inserts a phantom frame into a frame list
00186  * 
00187  * Maintains the last_frame_num, first_frame_num, count, and the data
00188  * byte length of frames in the frame list.
00189  *
00190  * @param list          frame list pointer to insert the new frame link into
00191  * @param prev          frame link before the one to insert
00192  * @param insert        frame link to insert
00193  *
00194  * @return NULL on error
00195  * @return frame_link pointer that was inserted into the frame list
00196  */
00197 inline frame_link* Datagram_Insert_Phantom(frame_list* list, frame_link* prev, int frame_num) {
00198         frame_link* insert;
00199         if (ALLOC(insert,frame_link*,frame_link,1) == 0) return NULL;
00200         insert->frame.len               = 0;
00201         insert->frame.frame_num         = frame_num;
00202         insert->frame.urgency           = -1; /* this will generate a nack_vec on this turn */
00203         insert->frame.done              = 0;
00204         insert->frame.missing_data.head = NULL;
00205         insert->frame.missing_data.count= 0;
00206         Datagram_Insert(list, prev, insert);
00207         return insert;
00208 } /* Datagram_Insert_Phantom() */
00209 
00210 
00211 /**
00212  * Useful internal function to print a frame_list to stdout
00213  *
00214  * @param list frame list
00215  */
00216 void Datagrams_Print(frame_list* list) {
00217         frame_link* frame_l;
00218         printf("--------------- len[%d]: \n", list->num);
00219         if (list->first != NULL) {
00220                 printf("[first] : [%d] %d\n", list->first->frame.frame_num, list->first->frame.len);
00221         }
00222 
00223         frame_l = list->first;
00224         while (frame_l != NULL) {
00225                 printf("[%d] : %d\n", frame_l->frame.frame_num, frame_l->frame.len);
00226                 frame_l = frame_l->next;
00227         }
00228         if (list->last != NULL) {
00229                 printf("[last] : [%d] %d\n", list->last->frame.frame_num, list->last->frame.len);
00230                 }
00231         printf("---------------\n");
00232 } /* Datagrams_Print() */
00233 
00234 
00235 /**
00236  * Clears out the datagrams from the frame list
00237  *
00238  * @param list frame list
00239  */
00240 inline void Datagrams_Clear(frame_list* list) {
00241         frame_link* frame_l;
00242         frame_link* frame_l2;
00243 
00244         /* free up all the allocated send frames */
00245         frame_l = list->first;
00246         while (frame_l != NULL) {
00247                 frame_l2 = frame_l;
00248                 frame_l = frame_l->next;
00249                 RELEASE(frame_l2->frame.data, frame_l2->frame.len);
00250                 RELEASE(frame_l2, sizeof(frame_link));
00251         }
00252 } /* Datagrams_Clear */

Generated on Tue Aug 8 16:07:19 2006 for VFER by  doxygen 1.4.7