void handle_timedout_frames(Sender * sender, LLnode ** outgoing_frames_head_ptr) { //TODO: Suggested steps for handling timed out datagrams // 1) Iterate through the sliding window protocol information you maintain for each receiver // 2) Locate frames that are timed out and add them to the outgoing frames // 3) Update the next timeout field on the outgoing frames int i = 0; struct timeval *time = malloc(sizeof(struct timeval)); gettimeofday(time, NULL); for (;i < SWS; i++) { if (sender->sendQ[i].inuse == 1) { long timediff = timeval_usecdiff(time, sender->sendQ[i].timeout); if (timediff < 0) { Frame * outgoing_frame = (Frame *) sender->sendQ[i].msg; char * outgoing_msg = convert_frame_to_char(outgoing_frame); //fprintf(stderr, "%d frame timing out\n", outgoing_frame->seqNum); append_crc(outgoing_msg,MAX_FRAME_SIZE); ll_append_node(outgoing_frames_head_ptr, outgoing_msg); setTimeOutTime(sender->sendQ[i].timeout); //free(outgoing_frame); } } } }
void handle_input_cmds(Sender * sender, LLnode ** outgoing_frames_head_ptr) { //TODO: Suggested steps for handling input cmd // 1) Dequeue the Cmd from sender->input_cmdlist_head // 2) Convert to Frame // 3) Set up the frame according to the sliding window protocol // 4) Compute CRC and add CRC to Frame int input_cmd_length = ll_get_length(sender->input_cmdlist_head); //Recheck the command queue length to see if stdin_thread dumped a command on us input_cmd_length = ll_get_length(sender->input_cmdlist_head); ll_split_head(&sender->input_cmdlist_head, FRAME_PAYLOAD_SIZE - 1); while (input_cmd_length > 0 && sender->sendQSize <= SWS) { // fprintf(stderr, "%d %d\n", input_cmd_length, ll_get_length(sender->input_cmdlist_head)); unsigned char upper = sender->LAR + SWS - 1; //printf("%d %d %d ", sender->LAR, upper, sender->seqNum); if (!((sender->LAR <= upper && sender->seqNum >= sender->LAR && sender->seqNum <= upper) || (sender->LAR > upper && (sender->seqNum >= sender->LAR || sender->seqNum <= upper)))) break; //Pop a node off and update the input_cmd_length LLnode * ll_input_cmd_node = ll_pop_node(&sender->input_cmdlist_head); input_cmd_length = ll_get_length(sender->input_cmdlist_head); //Cast to Cmd type and free up the memory for the node Cmd * outgoing_cmd = (Cmd *) ll_input_cmd_node->value; free(ll_input_cmd_node); //DUMMY CODE: Add the raw char buf to the outgoing_frames list //NOTE: You should not blindly send this message out! // Ask yourself: Is this message actually going to the right receiver (recall that default behavior of send is to broadcast to all receivers)? // Does the receiver have enough space in in it's input queue to handle this message? // Were the previous messages sent to this receiver ACTUALLY delivered to the receiver? int msg_length = strlen(outgoing_cmd->message); if (msg_length > MAX_FRAME_SIZE) { //Do something about messages that exceed the frame size printf("<SEND_%d>: sending messages of length greater than %d is not implemented\n", sender->send_id, MAX_FRAME_SIZE); } else { //This is probably ONLY one step you want Frame * outgoing_frame = (Frame *) malloc (sizeof(Frame)); strcpy(outgoing_frame->data, outgoing_cmd->message); outgoing_frame->src_id = outgoing_cmd->src_id; outgoing_frame->dst_id = outgoing_cmd->dst_id; outgoing_frame->seqNum = sender->seqNum; sender->seqNum++; //if (sender->seqNum >= SWS) // sender->seqNum = 0; //if (sender->seqNum == 5) // sender->seqNum++; //At this point, we don't need the outgoing_cmd free(outgoing_cmd->message); free(outgoing_cmd); //Convert the message to the outgoing_charbuf char * outgoing_charbuf = convert_frame_to_char(outgoing_frame); append_crc(outgoing_charbuf, MAX_FRAME_SIZE); //fprintf(stderr, "Sending %d with data %s\n", outgoing_frame->seqNum,outgoing_frame->data); ll_append_node(outgoing_frames_head_ptr, outgoing_charbuf); int i = 0; for (; i < SWS; i++) { if (sender->sendQ[i].inuse == 0) { sender->sendQSize++; struct timeval * timeout = malloc(sizeof(struct timeval)); setTimeOutTime(timeout); sender->sendQ[i].inuse = 1; sender->sendQ[i].timeout = timeout; sender->sendQ[i].msg =(Frame *)malloc(MAX_FRAME_SIZE); memcpy(sender->sendQ[i].msg,outgoing_frame,MAX_FRAME_SIZE); break; } } free(outgoing_frame); } } }
int pack_update(const char* srcdir, const char* dstfile) { struct update_header header; FILE *fp; int i; char buf[PATH_MAX]; printf("------ PACKAGE ------\n"); memset(&header, 0, sizeof(header)); snprintf(buf, sizeof(buf), "%s/%s", srcdir, "parameter"); if (parse_parameter(buf)) return -1; snprintf(buf, sizeof(buf), "%s/%s", srcdir, "package-file"); if (get_packages(buf)) return -1; fp = fopen(dstfile, "w"); if (!fp) return -1; fwrite(&header, sizeof(header), 1, fp); for (i = 0; i < package_image.num_package; ++i) { strcpy(header.parts[i].name, package_image.packages[i].name); strcpy(header.parts[i].filename, package_image.packages[i].filename); header.parts[i].nand_addr = package_image.packages[i].nand_addr; header.parts[i].nand_size = package_image.packages[i].nand_size; if (strcmp(package_image.packages[i].filename, "SELF") == 0) continue; snprintf(buf, sizeof(buf), "%s/%s", srcdir, header.parts[i].filename); printf("Add file: %s\n", buf); import_package(fp, &header.parts[i], buf); } strcpy(header.magic, "RKAF"); strcpy(header.manufacturer, package_image.manufacturer); strcpy(header.model, package_image.machine_model); strcpy(header.id, package_image.machine_id); header.length = ftell(fp); header.num_parts = package_image.num_package; header.version = package_image.version; for (i = header.num_parts - 1; i >= 0; --i) { if (strcmp(header.parts[i].filename, "SELF") == 0) { header.parts[i].size = header.length + 4; header.parts[i].padded_size = (header.parts[i].size + 511) / 512 *512; } } fseek(fp, 0, SEEK_SET); fwrite(&header, sizeof(header), 1, fp); fclose(fp); append_crc(dstfile); printf("------ OK ------\n"); return 0; }
int pack_update(const char* srcdir, const char* dstfile) { struct update_header header; FILE *fp = NULL; unsigned int i; printf("------ PACKAGE ------\n"); memset(&header, 0, sizeof(header)); fp = fopen(dstfile, "wb+"); if (!fp) { printf("Can't open destination file \"%s\": %s\n", dstfile, strerror(errno)); return -1; } if (chdir(srcdir)) return -1; if (parse_parameter("parameter")) return -1; if (get_packages("package-file")) return -1; fwrite(&header, sizeof(header), 1, fp); for (i = 0; i < package_image.num_package; ++i) { strcpy(header.parts[i].name, package_image.packages[i].name); strcpy(header.parts[i].filename, package_image.packages[i].filename); header.parts[i].nand_addr = package_image.packages[i].nand_addr; header.parts[i].nand_size = package_image.packages[i].nand_size; if (strcmp(package_image.packages[i].filename, "SELF") == 0) continue; printf("Add file: %s\n", header.parts[i].filename); import_package(fp, &header.parts[i], header.parts[i].filename); } memcpy(header.magic, RKAFP_MAGIC, sizeof(header.magic)); strcpy(header.manufacturer, package_image.manufacturer); strcpy(header.model, package_image.machine_model); strcpy(header.id, package_image.machine_id); header.length = ftell(fp); header.num_parts = package_image.num_package; header.version = package_image.version; for (i = 0; i < header.num_parts; i++) { if (strcmp(header.parts[i].filename, "SELF") == 0) { header.parts[i].size = header.length + 4; header.parts[i].padded_size = (header.parts[i].size + 511) / 512 *512; } } fseek(fp, 0, SEEK_SET); fwrite(&header, sizeof(header), 1, fp); append_crc(fp); fclose(fp); printf("------ OK ------\n"); return 0; }