PROGRAM 2
/****************************************************************************/ /* program: myuart2a.c */ /* author: anthony f. ortiz */ /* class: cs3590 */ /* date: febuary 25, 1999 */ /* description: serial chat program #2 (sender) */ /****************************************************************************/ #include #include #include #include #include #include #include "uart.h" /* frame structure: start of header is the beginning of the frame and is */ /* equal to 1. */ /* sequence number is the number of the frame and starts */ /* at 1 and ends at 255 */ /* length is the number of characters in the data */ /* portion of the frame. */ /* data payload is the data portion of the frame. */ /* checksum is the addition of all the array elements in */ /* the frame. */ struct frame { byte_t start_of_header; byte_t sequence_number; byte_t length; byte_t * data_payload; byte_t checksum; }; /* construct the frame. */ void construct_frame (struct frame *aframe, int file_descriptor, byte_t max_bytes) { /* for loop variable */ int i; /* read 255 or less characters from the data file and fill in */ /* frame's length, start of header, and sequence number. */ aframe -> length = _read (file_descriptor, aframe -> data_payload, max_bytes); aframe -> start_of_header = 0; aframe -> sequence_number = aframe -> sequence_number + 1; /* calculate the frame's checksum. */ aframe -> checksum = aframe -> start_of_header + aframe -> sequence_number + aframe -> length; for (i = 0; i < aframe -> length; i++) { aframe -> checksum = aframe -> checksum + aframe -> data_payload [i]; } } /* either corrupt the frame or don't corrupt the frame. */ void corrupt_bit (struct frame *aframe, int error_frequency) { /* if the frame count equals 2 * the error frequencey, */ /* corrupt the data by adding 1 to 1st element in data */ /* array. also, print out error message. otherwise, */ /* do nothing and print out a positive message. */ if (error_frequency == 0 || aframe -> sequence_number % error_frequency != 0) { printf ("there is no error in frame %i.\n", aframe -> sequence_number); } else { aframe -> data_payload [0] = aframe -> data_payload [0] + 1; printf ("there is an error in frame %i.\n", aframe -> sequence_number); } } /* send frame to receiver. */ void send_frame (struct frame aframe, int return_value, int port) { /* for loop variable */ int i; /* send frame over the serial line. */ return_value = com_out (port, aframe.start_of_header); return_value = com_out (port, aframe.sequence_number); return_value = com_out (port, aframe.length); for (i = 0; i < aframe.length; i++) { return_value = com_out (port, aframe.data_payload [i]); } return_value = com_out (port, aframe.checksum); } /* wait for some type of aknowledgement from receiver. */ void wait_aknowledgement (struct frame aframe, int return_value, int port, byte_t * mode) { /* initialize mode to -1 and wait for an acknowledgement. */ *mode = -1; do { return_value = com_in (port, mode); } while (*mode != aframe.sequence_number && *mode != aframe.sequence_number - 1); } /* either uncorrupt the frame or don't uncorrupt the frame. */ void uncorrupt_bit (struct frame *aframe, byte_t mode) { /* if it is a positive acknowledgement, print acknowledgement */ /* message. otherwise print acknowledgement wasn't received */ /* and uncorrupt the first bit of data. */ if (mode == aframe -> sequence_number) { printf ("acknowledgement was received. frame %i is ok.\n", aframe -> sequence_number); } else { printf ("acknowledgement wasn't received. send frame %i again.\n", aframe -> sequence_number); aframe -> data_payload [0] = aframe -> data_payload [0] - 1; } } /* this program will read a file from disk and transfer it over the serial */ /* line using arq algorithm to overcome errors. */ void main () { /* error frequency in the arq algorithm */ int error_frequency; /* data file that is sent over the serial line */ char * infile; /* file descriptor of data file */ int file_descriptor; /* return value of com_open, in, out, and close functions */ int return_value; /* port number for com_open, in, out, and close functions */ int port = 1; /* mode of com_open, in, and out functions */ byte_t mode = BAUD9600 | PARITY_NONE | STOP1 | WORD_8BIT; /* the frame being sent */ struct frame aframe; /* maximum possible bytes to read from data file */ byte_t max_bytes = 255; /* clear the screen. */ clrscr (); /* initialize the uart. */ return_value = com_open (port, mode); /* enter the frequency of errors and the name of the data file. */ printf ("enter frequency of errors (0 - 1000): "); scanf ("%i", &error_frequency); printf ("enter name of infile: "); scanf ("%s", infile); /* open the data file for reading. */ file_descriptor = open (infile, O_RDONLY); if (file_descriptor == -1) { exit (1); } /* initialize frame's sequence number to 0. */ aframe.sequence_number = 0; /* loop until frame length is less then maximum number of bytes. */ do { /* construct the frame. */ construct_frame (&aframe, file_descriptor, max_bytes); /* either corrupt the frame or don't corrupt the frame. */ corrupt_bit (&aframe, error_frequency); /* loop until there is a positive acknowledgement. */ do { /* send frame to receiver. */ send_frame (aframe, return_value, port); /* wait for some type of aknowledgement from receiver. */ wait_aknowledgement (aframe, return_value, port, &mode); /* either uncorrupt the frame or don't uncorrupt the frame. */ uncorrupt_bit (&aframe, mode); } while (mode != aframe.sequence_number); } while (aframe.length == max_bytes); /* close the data file. */ close (file_descriptor); /* close the uart. */ return_value = com_close (port); } /****************************************************************************/ /* program: myuart2b.c */ /* author: anthony f. ortiz */ /* class: cs3590 */ /* date: febuary 25, 1999 */ /* description: serial chat program #2 (receiver) */ /****************************************************************************/ #include #include #include #include #include #include #include "uart.h" /* frame structure: start of header is the beginning of the frame and is */ /* equal to 1. */ /* sequence number is the number of the frame and starts */ /* at 1 and ends at 255 */ /* length is the number of characters in the data */ /* portion of the frame. */ /* data payload is the data portion of the frame. */ /* checksum is the addition of all the array elements in */ /* the frame. */ struct frame { byte_t start_of_header; byte_t sequence_number; byte_t length; byte_t * data_payload; byte_t checksum; }; /* find start of header. */ void find_header (struct frame *aframe, int return_value, int port, byte_t *mode, int *count) { /* loop until start of header is found. */ do { return_value = com_in (port, mode); } while (*mode != 0); /* initialize count which will stand for the bytes in our frame. */ /* also, start of header equals mode since it is equal to 0. */ *count = 1; aframe -> start_of_header = *mode; } /* reconstruct frame (structure). */ void reconstruct_frame (struct frame *aframe, int *return_value, int port, byte_t *mode, int *count) { /* read uart. */ *return_value = com_in (port, mode); if (*return_value >= 0) { *count = *count + 1; } /* add 1 to the count if there is something in uart. */ /* recontruct frame (structure) depending on count. */ if (*return_value >= 0 && *count == 2) { aframe -> sequence_number = *mode; } else if (*return_value >= 0 && *count == 3) { aframe -> length = *mode; } else if (*return_value >= 0 && *count >= 4 && *count <= 3 + aframe -> length) { aframe -> data_payload [*count - 4] = *mode; } else if (return_value >= 0 && *count == 4 + aframe -> length) { aframe -> checksum = *mode; } } /* send some type of aknowledgement. */ void send_acknowledgement (struct frame aframe, int file_descriptor, int return_value, int port, int count, byte_t * checksum2) { /* for variable */ int i; /* size of file for write function */ int size; /* if count is equal to the last byte in the frame, then */ /* execute this if statement. */ if (return_value >= 0 && count > 3 && count == 4 + aframe.length) { /* calculate the frame's checksum. */ *checksum2 = aframe.start_of_header + aframe.sequence_number + aframe.length; for (i = 0; i < aframe.length; i++) { *checksum2 = *checksum2 + aframe.data_payload [i]; } /* if checksum is correct, then print acknowlegment sent */ /* to the screen, write frame's data to the outfile, and */ /* send a postive acknowledgement over the serial line. */ /* otherwise, print acknowledgement not sent and send a */ /* negative acknowledgement (current frame # - 1) over */ /* the serial line. */ if (aframe.checksum == *checksum2) { printf ("frame %i is ok. send acknowledgement.\n", aframe.sequence_number); size = _write (file_descriptor, aframe.data_payload, aframe.length); return_value = com_out (port, aframe.sequence_number); } else { printf ("frame %i is corrupted. don't send acknowledgement.\n", aframe.sequence_number); return_value = com_out (port, aframe.sequence_number - 1); } } } /* this program will read data from the serial port and write the file to */ /* disk. */ void main () { /* data file */ char * outfile; /* file descriptor of data file */ int file_descriptor; /* return value for com_open, in, out, and close functions */ int return_value; /* port number for com_open, in, out, and close functions */ int port = 1; /* mode for com_open, in, and out functions */ byte_t mode = BAUD9600 | PARITY_NONE | STOP1 | WORD_8BIT; /* frame (structure) being constructed from com_in */ struct frame aframe; /* maximum possible bytes for writing to data file */ byte_t max_bytes = 255; /* count used to reconstruct frame (structure) */ int count; /* checksum on receiver's side */ byte_t checksum2; /* clear the screen. */ clrscr (); /* initialize the uart. */ return_value = com_open (port, mode); /* enter the name of the data file. */ printf ("enter name of outfile: "); scanf ("%s", outfile); /* open the data file for writing. */ file_descriptor = open (outfile, O_CREAT | O_TEXT); if (file_descriptor == -1) { exit (1); } /* loop until frame's length is less then maximum number of bytes. */ do { /* find start of header. */ find_header (&aframe, return_value, port, &mode, &count); /* loop until the whole frame (structure) has been reconstructed. */ do { /* reconstruct frame (structure). */ reconstruct_frame (&aframe, &return_value, port, &mode, &count); /* send some type of aknowledgement. */ send_acknowledgement (aframe, file_descriptor, return_value, port, count, &checksum2); } while (count != 4 + aframe.length); } while (aframe.length == max_bytes || aframe.checksum != checksum2); /* close the data file. */ close (file_descriptor); /* close uart. */ return_value = com_close (port); } /* filename: uart.h, uart.c */ /* see program 1. */ /* data file: infile.dat */ hi, anthony. /* outfile: outfile.out */ hi, anthony. /* outfile: prog2.out */ /* computer 1 */ enter frequency of errors (0 - 1000): 1 enter name of infile: infile.dat there is an error in frame 1. acknowledgement wasn't received. send frame 1 again. acknowledgement was received. frame 1 is ok. /* computer 2 */ enter name of outfile: outfile.out frame 1 is corrupted. don't send acknowledgement. frame 1 is ok. send acknowledgement.
BACK TO CS3590 PAGE.