/* * UCSD CSE123a * (from Byer's BU CS555 assignment) * Winter 2005 * * A list that stored packets that have already been received * by the receiver. * * Version 1.0 */ #include #include #include #include #include "srmp.h" void sender_printList(srmp_send_ctrl_blk *info) { pktbuf *curPacket; curPacket = info->sendQueue; while(curPacket != NULL) { printf("%d\n", curPacket->seqno); curPacket = curPacket->next; } } /* * Adds a packet in the send queue so that in the * end the packets saved in the send queue are sorted * by the sequence number. * * Adjusts the last byte read (info->LBRead), which in fact happens to be * one less than the seqno of the first packet. */ void sender_add_packet(srmp_send_ctrl_blk *info, unsigned short seqno, time_t currTime, char *data, int len) { pktbuf *curPacket; curPacket = (pktbuf *)malloc(sizeof(pktbuf)); curPacket->seqno = seqno; curPacket->len = len; curPacket->pktTime = currTime; curPacket->dupcount = info->dupcount; memcpy(curPacket->data, data, len); /* Find the slot where the packet fits */ if (info->sendQueue == NULL) { /* First packet on the list */ curPacket->next = NULL; info->sendQueue = curPacket; } else if (greater(info->sendQueue->seqno, seqno)) { /* The packet which is added should become the first packet on the list, i.e. be inserted before the current first packet on the list */ curPacket->next = info->sendQueue; info->sendQueue = curPacket; } else { /* Walk across the list, find a place for the packet which would insert the packet between two packets: - the packet previous to the added packet should have a smaller seqno - the packet to the right of the added packet should either be NULL or a packet with greater seqno */ pktbuf *prev = info->sendQueue, *traverse = prev->next; if(prev->seqno == seqno) { free(curPacket); return; } while ((traverse != NULL) && greater(seqno, traverse->seqno)) { prev = traverse; traverse = traverse->next; } if (traverse == NULL) { /* Appending to the end of the list */ prev->next = curPacket; curPacket->next = NULL; } else { if(traverse->seqno == seqno) { free(curPacket); return; } /* Inserting into the middle of the list */ prev->next = curPacket; curPacket->next = traverse; } } } void free_packet(pktbuf *pbuf) { free(pbuf); } /* * Returns a packet whose sequence number equals to seqno. * If no such packet, returns NULL. * */ pktbuf *sender_get_packet(srmp_send_ctrl_blk *info, unsigned short seqno) { pktbuf *traverse = info->sendQueue, *prev = NULL; while(traverse) { if (traverse->seqno == seqno) { /* * Unlink the node from the list * */ if (prev == NULL) { /* The first node on the list */ info->sendQueue = traverse->next; } else { /* Some other node */ prev->next = traverse->next; } return traverse; } prev = traverse; traverse = traverse->next; } return NULL; } pktbuf * clear_prev_packets(srmp_send_ctrl_blk *info, unsigned short seqno) { pktbuf *traverse = info->sendQueue; while(traverse) { if (greater(seqno,traverse->seqno)) info->sendQueue = traverse->next; else return traverse; traverse = traverse->next; } return NULL; } pktbuf *sender_copy_packet(srmp_send_ctrl_blk *info, unsigned short seqno) { pktbuf *traverse = info->sendQueue; pktbuf *dest = (pktbuf *)malloc(sizeof(*traverse)); while(traverse) { if (traverse->seqno == seqno) { memcpy(dest,traverse,sizeof(*traverse)); return dest; } traverse = traverse->next; } return NULL; } int list_empty(srmp_send_ctrl_blk *info) { pktbuf *traverse = info->sendQueue; if (traverse) return 0; else return 1; } pktbuf *get_head_item(srmp_send_ctrl_blk *info) { return info->sendQueue; } int check_packet_time(srmp_send_ctrl_blk *info, long time) { pktbuf *traverse = info->sendQueue; while(traverse) { if (difftime(time,traverse->pktTime) > 2.0) { return traverse->seqno; } traverse = traverse->next; } return -1; }