#include #include #include #include #include #include #include #include "header.h" #include #define OVERHEAD 20 void send_packet(int transmit, struct packet * const foo, int build_md5sum); // 0 for good // -1 for bad md5sum // 1 for pipe done int read_packet(int recieve, struct packet* const foo, int check_md5sum); int ack_bad(int transmit, struct packet *, unsigned short signal_strength); int ack_good(int transmit, struct packet *, unsigned short signal_strength); void box_RX(int transmit, int recieve); void box_TX(int transmit, int recieve); char* build_md5(struct packet *bar, char* store); void print_md5(struct packet *foo); int main() { pid_t child; int TX[2]; int RX[2]; ssize_t rw_return; int pipe_return; assert((pipe_return = pipe(TX)) == 0); assert((pipe_return = pipe(RX)) == 0); if((child = fork()) == -1) { return -1; } else if(child == 0) { /* child RX side*/ /* close(TX[0]); close(RX[1]); */ box_RX(TX[1], RX[0]); } else { /* close(RX[0]); close(TX[1]); */ box_TX(RX[1], TX[0]); /* wait(NULL); */ /* parent TX side*/ } return 0; } void box_RX(int transmit, int recieve) { int read_return; unsigned short signal; struct packet got; while((read_return = read_packet(recieve, &got, 1)) != 1) { if(read_return == -1) { printf("ack_bad\n"); signal = rand()%0x3000; ack_bad(transmit, &got, signal); } else { printf("ack_good\n"); signal = rand()%0x80 + 0x7f; signal = 0xFFFF; printf("Good signal is %d\n", signal); ack_good(transmit, &got, signal); } } } void box_TX(int transmit, int recieve) { int md5sum_loop; unsigned char* buffer; struct packet go; struct packet forth; unsigned short packet_count = 65534; buffer = malloc(128); go.payload = buffer; forth.payload = NULL; printf("Payload to send: "); while(fgets(buffer, 128, stdin) && buffer[0] != '\0') { go.pack_id = packet_count++; go.pack_size = strlen(go.payload)+20; send_packet(transmit, &go, 1); printf("Sent packet\n"); printf("\tid = %d\n", go.pack_id); printf("\tsize = %d\n", go.pack_size); printf("\tpayload = %s\n", go.payload); printf("\tmd5sum = "); print_md5(&go); printf("\n\n"); read_packet(recieve, &forth, 0); // TODO handle when rx sends bad printf("ACK id of %d\n", forth.pack_id); printf("ACK MD5SUM of "); print_md5(&forth); printf("\nACK signal strength %d\n\n", (unsigned short)(*forth.payload)); assert(go.pack_id == forth.pack_id); assert(memcmp(go.md5sum, forth.md5sum, 16) == 0); printf("Payload to send: "); } close(transmit); } void send_packet(int transmit, struct packet * const foo, int build_md5sum) { unsigned char* buffer = NULL; static unsigned char md[16]; int rw; /* Send id and size */ rw = write(transmit, foo, 4); assert(rw == 4); /* Send payload */ rw = write(transmit, foo->payload, foo->pack_size- OVERHEAD); assert(rw == foo->pack_size-OVERHEAD); if(build_md5sum) build_md5(foo, foo->md5sum); rw = write(transmit, foo->md5sum, 16); assert(rw == 16); } // add support for sending 0 instead of aborting with the assert int read_packet(int recieve, struct packet* const foo, int check_md5) { static unsigned char md[16]; unsigned char* buffer = NULL; int rw; if(foo->payload) free(foo->payload); rw = read(recieve, foo, 4); assert(rw == 4); foo->payload = malloc(foo->pack_size - 20); rw = read(recieve, foo->payload, foo->pack_size-20); assert(rw == foo->pack_size-20); /* Read in md5sum, but store in md */ rw = read(recieve, foo->md5sum, 16); assert(rw == 16); build_md5(foo, md); rw = memcmp(md, foo->md5sum, 16); if(rw) return -1; return 0; } int ack_bad(int transmit, struct packet *blah, unsigned short signal_strength) { return ack_good(transmit, blah, signal_strength); } int ack_good(int transmit, struct packet *blah, unsigned short signal_strength) { if(blah->payload) free(blah->payload); assert(blah->payload = malloc(sizeof(signal_strength))); printf("alloc %d\n", sizeof(signal_strength)); blah->pack_size = sizeof(signal_strength) + OVERHEAD; (unsigned short)*(blah->payload) = signal_strength; printf("Got %d, set %d\n", signal_strength, (unsigned short)*(blah->payload)); send_packet(transmit, blah, 0); return 0; } char* build_md5(struct packet *foo, char* store) { static char blah[16]; unsigned char* buffer; buffer = malloc(foo->pack_size - 16); memcpy(buffer, &foo->pack_id, sizeof(foo->pack_id)); memcpy(buffer+sizeof(foo->pack_id), &foo->pack_size, sizeof(foo->pack_size)); memcpy(buffer+sizeof(foo->pack_id)+sizeof(foo->pack_size), foo->payload, foo->pack_size-20); if(store) MD5(buffer, foo->pack_size-16, store); else MD5(buffer, foo->pack_size-16,blah); free(buffer); if(store) return store; else return blah; } void print_md5(struct packet *foo) { int md5sum_loop; for(md5sum_loop = 0; md5sum_loop<16; md5sum_loop++) printf("%X", foo->md5sum[md5sum_loop]); }