/* These routines work together to send and receive data packets of */ /* any size between two systems. They can be turned into a file */ /* xfer protocol if need be. */ #define PROTOCOL_PACKET_MAX 10000 #define PROTOCOL_TIMEOUT 7 /* # of seconds gap in data that can occur after the 2 sync bytes start arriving. */ #define SYNC_CHAR 85 #include "crctable.h" unsigned char protocol_byte_to_xor_with; /* This is set in the send function */ /* and used in the receive function. It is gotten by time(NULL) % 256. */ /* Most all packet chars are XORd. This is supposed to be a random */ /* byte which kind of obscures the program's mechanism of operation. */ /*----------------------------------------------------------------------------*/ int protocol_send_packet(int modem_port_no,char the_packet[],unsigned short packet_length,int common_debug_level_current) { /* Max. packet length passed is restricted to PROTOCOL_PACKET_MAX, which is defined above. */ div_t result; /* For outputting "unsigned short"s in two separate bytes. */ unsigned short current_character_pointer=0; /* Position in packet data we're processing. */ long computed_crc=0; char char_to_send; computed_crc = modem_port_no; /* These 2 lines are to eliminate warning message. */ computed_crc = 0; if (!fossil_cd(fossil_current_port)) /* Lost carrier? */ return(2); /* common_debug_message(common_debug_level_current,"protocol_send_packet()"); */ if (packet_length > PROTOCOL_PACKET_MAX) { /* common_debug_message(common_debug_level_current,"Packet length > PROTOCOL_PACKET_MAX."); */ return(1); /* ...indicating failure to send as requested; too long. */ } port_out(SYNC_CHAR); /* Send two bytes which signal start of packet. */ port_out(SYNC_CHAR); protocol_byte_to_xor_with = (rand() % 256); /* More or less random. */ port_out((char)protocol_byte_to_xor_with); /* All packet chars after this are XORed with this one. */ /* common_debug_message_w_no(common_debug_level_current,"Outgoing packet length:",(long)packet_length); */ result = div(packet_length,256); /* Output the packet length, MSB, then LSB. */ port_out(result.quot ^ protocol_byte_to_xor_with); /* Send out the 2 length bytes. */ port_out(result.rem ^ protocol_byte_to_xor_with); while (current_character_pointer < packet_length) { char_to_send = the_packet[current_character_pointer]; computed_crc = update_crc32(char_to_send,computed_crc); /* common_debug_message_w_no(common_debug_level_current+1,"CRC is now:",computed_crc); */ /* common_debug_message_w_no(common_debug_level_current+1,"Character was:",(long)char_to_send); */ port_out(char_to_send ^ protocol_byte_to_xor_with); current_character_pointer++; } if (!fossil_cd(fossil_current_port)) /* Lost carrier? Catch that before completing packet. */ return(2); /* common_debug_message_w_no(common_debug_level_current+1,"CRC MSB: ",(computed_crc>>24)&255); */ port_out(((computed_crc >> 24) & 255) ^ protocol_byte_to_xor_with); /* common_debug_message_w_no(common_debug_level_current+1,"CRC MSB2:",(computed_crc>>16)&255); */ port_out(((computed_crc >> 16) & 255) ^ protocol_byte_to_xor_with); /* common_debug_message_w_no(common_debug_level_current+1,"CRC LSB2:",(computed_crc>>8)&255); */ port_out(((computed_crc >> 8) & 255) ^ protocol_byte_to_xor_with); /* common_debug_message_w_no(common_debug_level_current+1,"CRC LSB2:",computed_crc&255); */ port_out(( computed_crc & 255) ^ protocol_byte_to_xor_with); /* common_debug_message(common_debug_level_current,"Successful packet send."); */ return(0); /* Barring comm. errors, we have just sent a packet! */ } /*----------------------------------------------------------------------------*/ unsigned short protocol_get_packet(int modem_port_no,int timeout_seconds,char the_packet[],int common_debug_level_current) { /* Returns 0 for failure to receive a good packet within the timeout */ /* or length of received packet. */ unsigned short packet_length,current_character_pointer=0; long computed_crc=0,received_crc,crc_msb,crc_msb2,crc_lsb2,crc_lsb; int char_from_modem,timeout_seconds_left,temp_int; unsigned char temp_unsigned_char; time_t starting_time,ending_time; /* common_debug_message(common_debug_level_current,"protocol_get_packet()"); */ starting_time = time(NULL); /* Begin tracking the timeout period. */ ending_time = starting_time + timeout_seconds; sync_byte_loop: /* Keep coming back to here until we get a sync byte. */ timeout_seconds_left = ending_time - time(NULL); char_from_modem = get_char_from_modem_with_timeout(modem_port_no,timeout_seconds_left); if (char_from_modem == -1) { common_debug_message(common_debug_level_current,"Timeout on first sync (NULL) byte."); return(0); } if (char_from_modem != SYNC_CHAR) /* Did we receive a sync character? */ { printf("Skipping junk character while waiting for 1st sync character.\n"); goto sync_byte_loop; } timeout_seconds_left = ending_time - time(NULL); /* Get the next byte and check to see if IT's null. */ if (timeout_seconds_left < 0) timeout_seconds_left = 0; char_from_modem = get_char_from_modem_with_timeout(modem_port_no,timeout_seconds_left); if (char_from_modem == -1) { common_debug_message(common_debug_level_current,"Timeout on byte after first sync byte."); return(0); } if (char_from_modem != SYNC_CHAR) /* Did we receive correct byte? */ { printf("Skipping junk character while waiting for 2nd sync byte.\n"); goto sync_byte_loop; } timeout_seconds_left = ending_time - time(NULL); /* Start by getting the xor character. */ if (timeout_seconds_left < PROTOCOL_TIMEOUT) timeout_seconds_left = PROTOCOL_TIMEOUT; temp_int = get_char_from_modem_with_timeout(modem_port_no,timeout_seconds_left); if (temp_int == -1) { common_debug_message(common_debug_level_current,"Timeout on MSB of packet_length."); return(0); } protocol_byte_to_xor_with = temp_int; /* Figure this char out. */ if (time(NULL) > ending_time) { common_debug_message(common_debug_level_current,"Timeout after getting packet's XOR byte."); return(0); } timeout_seconds_left = ending_time - time(NULL); /* Get the packet length. */ if (timeout_seconds_left < PROTOCOL_TIMEOUT) timeout_seconds_left = PROTOCOL_TIMEOUT; char_from_modem = get_char_from_modem_with_timeout(modem_port_no,timeout_seconds_left) ^ protocol_byte_to_xor_with; /* MSB */ if (char_from_modem == -1) { common_debug_message(common_debug_level_current,"Timeout on MSB of packet_length."); return(0); } packet_length = char_from_modem * 256; if (time(NULL) > ending_time) { common_debug_message(common_debug_level_current,"Timeout after getting MSB of packet_length."); return(0); } timeout_seconds_left = ending_time - time(NULL); if (timeout_seconds_left < PROTOCOL_TIMEOUT) timeout_seconds_left = PROTOCOL_TIMEOUT; char_from_modem = get_char_from_modem_with_timeout(modem_port_no,timeout_seconds_left) ^ protocol_byte_to_xor_with; /* LSB */ if (char_from_modem == -1) { common_debug_message(common_debug_level_current,"Timeout on LSB of packet_length."); return(0); } packet_length += char_from_modem; /* common_debug_message_w_no(common_debug_level_current,"Packet length:",(long)packet_length); */ if (packet_length > PROTOCOL_PACKET_MAX) { common_debug_message(common_debug_level_current,"Packet length > PROTOCOL_PACKET_MAX."); goto sync_byte_loop; /* This shouldn't happen, so must be a bad packet. */ } if (time(NULL) > ending_time) { common_debug_message(common_debug_level_current,"Timeout after getting LSB of packet_length."); return(0); } while (current_character_pointer < packet_length) { if (time(NULL) > ending_time) /* Timeout? This is really the only place we need to check for this timeout up until now. */ { /* common_debug_message(common_debug_level_current,"Timeout while looping for packet data."); */ return(0); } timeout_seconds_left = ending_time - time(NULL); if (timeout_seconds_left < PROTOCOL_TIMEOUT) timeout_seconds_left = PROTOCOL_TIMEOUT; char_from_modem = get_char_from_modem_with_timeout(modem_port_no,timeout_seconds_left) ^ protocol_byte_to_xor_with; if (char_from_modem == -1) { common_debug_message_w_no(common_debug_level_current,"Timeout while waiting for packet data character ",current_character_pointer); return(0); } the_packet[current_character_pointer] = (char)char_from_modem; computed_crc = update_crc32(the_packet[current_character_pointer],computed_crc); /* common_debug_message_w_no(common_debug_level_current+1,"CRC is now:",computed_crc); */ /* common_debug_message_w_no(common_debug_level_current+1,"Character was:",the_packet[current_character_pointer]); */ current_character_pointer++; } if (time(NULL) > ending_time) { /* common_debug_message(common_debug_level_current,"Timeout after looping for packet data."); */ return(0); } timeout_seconds_left = ending_time - time(NULL); /* Get MSB of CRC. */ if (timeout_seconds_left < PROTOCOL_TIMEOUT) timeout_seconds_left = PROTOCOL_TIMEOUT; char_from_modem = get_char_from_modem_with_timeout(modem_port_no,timeout_seconds_left) ^ protocol_byte_to_xor_with; if (char_from_modem == -1) { common_debug_message(common_debug_level_current,"Timeout while waiting for MSB of CRC code."); return(0); } crc_msb = char_from_modem; /* common_debug_message_w_no(common_debug_level_current+1,"CRC MSB: ",crc_msb); */ if (time(NULL) > ending_time) { common_debug_message(common_debug_level_current,"Timeout after getting MSB of CRC code."); return(0); } timeout_seconds_left = ending_time - time(NULL); /* Get MSB2 of CRC. */ if (timeout_seconds_left < PROTOCOL_TIMEOUT) timeout_seconds_left = PROTOCOL_TIMEOUT; char_from_modem = get_char_from_modem_with_timeout(modem_port_no,timeout_seconds_left) ^ protocol_byte_to_xor_with; if (char_from_modem == -1) { common_debug_message(common_debug_level_current,"Timeout while waiting for MSB 2 of CRC code."); return(0); } crc_msb2 = char_from_modem; /* common_debug_message_w_no(common_debug_level_current+1,"CRC MSB2:",crc_msb2); */ if (time(NULL) > ending_time) { common_debug_message(common_debug_level_current,"Timeout after getting MSB 2 of CRC code."); return(0); } timeout_seconds_left = ending_time - time(NULL); /* Get LSB2 of CRC. */ if (timeout_seconds_left < PROTOCOL_TIMEOUT) timeout_seconds_left = PROTOCOL_TIMEOUT; char_from_modem = get_char_from_modem_with_timeout(modem_port_no,timeout_seconds_left) ^ protocol_byte_to_xor_with; if (char_from_modem == -1) { common_debug_message(common_debug_level_current,"Timeout while waiting for LSB 2 of CRC code."); return(0); } crc_lsb2 = char_from_modem; /* common_debug_message_w_no(common_debug_level_current+1,"CRC LSB2:",crc_lsb2); */ if (time(NULL) > ending_time) { common_debug_message(common_debug_level_current,"Timeout after getting LSB 2 of CRC code."); return(0); } timeout_seconds_left = ending_time - time(NULL); /* Get LSB of CRC. */ if (timeout_seconds_left < PROTOCOL_TIMEOUT) timeout_seconds_left = PROTOCOL_TIMEOUT; char_from_modem = get_char_from_modem_with_timeout(modem_port_no,timeout_seconds_left) ^ protocol_byte_to_xor_with; if (char_from_modem == -1) { common_debug_message(common_debug_level_current,"Timeout while waiting for LSB of CRC code."); return(0); } crc_lsb = char_from_modem; /* common_debug_message_w_no(common_debug_level_current+1,"CRC LSB: ",crc_lsb); */ received_crc = ((crc_msb & 255) << 24) | ((crc_msb2 & 255) << 16) | ((crc_lsb2 & 255) << 8) | (crc_lsb & 255); if (received_crc != computed_crc) { common_debug_message(common_debug_level_current,"CRC mismatch."); /* common_debug_message_w_no(common_debug_level_current+1,"Computed crc:",computed_crc); */ /* common_debug_message_w_no(common_debug_level_current+1,"Received crc:",received_crc); */ goto sync_byte_loop; /* Give it another chance. */ } return(packet_length); }