//talk to DGPS to get logfiles - WITH TPS // log events in a logfile // KM July 2003 // version 1.1 #include #include #include #include #include #include #define BYTE unsigned char /* #define INT16 unsigned short #define INTS16 short #define INT32 unsigned int #define INTS32 int */ #define SERIALPORT "/dev/ttyS0" #define LOGFILE "/home/km/incoming/gps.log" /* struct Block { BYTE type; union { INT16 number; INTS16 count; }; BYTE data[512]; INT16 cs; BYTE eob; } TPSblock; */ // GLOBAL variables for simplicity int serialport; // serial port int outfile; // where we write log files to FILE *logfd; // log file BYTE tps_data[512]; unsigned char crcbuffer[1 + 2 + 512]; // make a brainless copy of the data char mesg[512]; // somewhere to make logfile strings! //---------------------- HELPERS------------------------- BYTE getbyte () { BYTE byte; read (serialport, &byte, 1); return byte; } // write a byte BYTE putbyte(BYTE b) { return(write(serialport, &b, 1)); } // write a string int putstring(char *s) { int l = strlen(s); //log(s); if ( write(serialport, s, l) != l) return(-1); else return(0); } // print message to log file void logfile(char *str) { fprintf(logfd, str); fflush(logfd); } // print error message to log file and exit erexit(char *str) { fprintf(logfd, str); // exit is a bit severe - means we'd have to restart externally exit(1); } //----------- TPS protocol------------- #define BLOCKTYPE_ORDINAL 0x02 #define BLOCKTYPE_LAST 0x04 #define BLOCKTYPE_ABORT 0x23 // send this after checking block to get next block void tps_ack() { putbyte(0x06); } // send this to get first block OR to ask for a resend void tps_nack() { putbyte(0x15); } // CRC CHECK typedef unsigned short Crc16; enum { WIDTH = 16, POLY = 0x1021, BYTE_BITS = 8, TABLE_SIZE = 1 << BYTE_BITS, MSB_MASK = 1 << (WIDTH - 1) }; static Crc16 table[TABLE_SIZE]; void crc16init() { Crc16 i; for(i = 0; i < TABLE_SIZE; ++i) { Crc16 val = i << (WIDTH - BYTE_BITS); int j; for(j = 0; j < BYTE_BITS; ++j) val = (val << 1) ^ ((val & MSB_MASK) ? POLY : 0); table[i] = val; } } Crc16 crc16(Crc16 crc, void const* src, int cnt) { unsigned char const* s = (unsigned char const*)src; while(cnt--) crc = (crc << BYTE_BITS) ^ table[(crc >> (WIDTH - BYTE_BITS)) ^ *s++]; return(crc); } Crc16 crc = 0; crc_check(unsigned short checksum) { crc = crc16(crc, crcbuffer, 1 + 2 + 512); if(checksum != crc){ logfile("CRC error\n"); } } // GET A BLOCK OF DATA FROM GPS // returns the number of bytes copied into the 512b buffer int tps_getblock(unsigned short *returned_bytecount) { BYTE type, lsb, msb, eob; int counter; unsigned short blocknum, checksum, bytecount; type = getbyte(); crcbuffer[0] = type; switch(type) { case BLOCKTYPE_ORDINAL: lsb = getbyte(); msb = getbyte(); crcbuffer[1] = lsb; crcbuffer[2] = msb; blocknum = (((unsigned short)msb) << 8) | (unsigned short)lsb; for(counter=0; counter<512; counter++){ tps_data[counter] = getbyte(); crcbuffer[counter + 3] = tps_data[counter]; } lsb = getbyte(); msb = getbyte(); checksum = (((unsigned short)msb) << 8) | (unsigned short)lsb; // should check it! crc_check(checksum); eob = getbyte(); // DEBUG sprintf(mesg,"block number %d\n",blocknum); logfile(mesg); *returned_bytecount = 512; return(type); case BLOCKTYPE_LAST: lsb = getbyte(); msb = getbyte(); bytecount = (((unsigned short)msb) << 8) | (unsigned short)lsb; for(counter=0; counter