// WAIT for a packet from base station via serial port over radio link // need to link with serials.c to get coms stuff and logfile // we usually talk to /dev/ttyS05 for the radio modem // and log to a file called /home/km/incoming/basecoms.log #include #include // need this to set the serial speed like B9600 #include #include #include // Royan's packets // HDR(1 nibble) // HDRSIZE(1 nibble) // SRC_ID(1) // CMD(1) // data[1-16] // checksum(1) #define CURRENT_ID 0xF0 //ID of this device #define CMD_HEADER_ID 0x30 //command message header (send or rcv) #define REPLY_HEADER_ID 0x50 //reply message header #define BROADCAST_ID 0xA0 //the ID boadcasting #define GROUP_ID 0xA3 //the ID for group response #define CMD_SYS_BAT_READ 0x12 // battery voltage #define CMD_SYS_I_AM_AWAKE 20 // to test if things are awake #define CMD_SYS_READ_STR_READINGS 0x15 // read stored readings #define CMD_GPS_TRANSFER_LOG 0xCC // ready to download rem GPS #define CMD_EEPROM_READ_16 0x5D // read eeprom // a load of ugly globals to store packet data in! unsigned char RX_STATE = 0; unsigned char RX_HEADER; // a copy of the packet header unsigned char RX_SIZE; //received data field size unsigned char RX_MODULE; //target or source module ID unsigned char RX_COMMAND; //received or sent command unsigned char RX_DATA[16]; //data unsigned char TX_HEADER; // out packet header unsigned char TX_SIZE; //out data field size unsigned char TX_MODULE; //out target or source module ID unsigned char TX_COMMAND; //out pkt type unsigned char TX_DATA[16]; //out data // CATCH SIGNALS and close us down nicely void sigcatch(int s) { extern FILE *logfd; //close(serialport); //fclose(logfd); // logging file used by serials.c logfile("waitforbase exiting due to HUP"); exit(0); } void COMINTInterpret (unsigned char c) { static unsigned int _checksum; //printf("got %x\n",c); if (RX_STATE == 0) //handle data in other conditions { //idle //read packet if valid header detected if (((c & 0xF0) == CMD_HEADER_ID) || ((c & 0xF0) == REPLY_HEADER_ID)) { _checksum = c; //checksum calculation RX_SIZE = c & 0x0F; //size of data field is lower nibble RX_HEADER = c & 0xF0; // Copy header type for later RX_STATE = 1; //goto next state } } else if (RX_STATE == 1) { //module RX_MODULE = c; //read module _checksum += RX_MODULE; //checksum RX_STATE = 2; //goto next state } else if (RX_STATE == 2) { //command RX_COMMAND = c; //read command _checksum += RX_COMMAND; //checksum RX_STATE = 3; //goto next state } else if (RX_STATE == (RX_SIZE + 4)) // Whole packet read, check & exec { if ((_checksum % 256) == c) if( RX_HEADER == CMD_HEADER_ID) { //checksum tallies with data if ((RX_MODULE == CURRENT_ID) || (RX_MODULE == BROADCAST_ID) || (RX_MODULE == GROUP_ID)) ExecuteCommand (); } else ExecuteReply(); RX_STATE = 0; //back to idle mode } else { //data RX_DATA[RX_STATE - 3] = c; //read data _checksum += RX_DATA[RX_STATE - 3]; //checksum RX_STATE++; //goto next state } } // tell them I am awake i_am_awake() { TX_HEADER = REPLY_HEADER_ID; TX_SIZE = 1; TX_MODULE = CURRENT_ID; TX_COMMAND = CMD_SYS_I_AM_AWAKE; TX_DATA[0] = 0; // just for fun SendPacket(); } // Write a packet from our global variables, to the serial port SendPacket() { unsigned char firstbyte; unsigned short checksum; int n; firstbyte = TX_HEADER + TX_SIZE -1; checksum = firstbyte; putbyte(firstbyte); putbyte(TX_MODULE); checksum += TX_MODULE; putbyte(TX_COMMAND); checksum += TX_COMMAND; for(n = 0; n < TX_SIZE; n++){ putbyte(TX_DATA[n]); checksum += TX_DATA[n]; } putbyte((unsigned char)(checksum & 0xFF) ); } ExecuteCommand () { switch(RX_COMMAND) { case CMD_GPS_TRANSFER_LOG: logfile("waitforbase got CMD_GPS_TRANSFER_LOG and exited\n"); exit(0); case CMD_SYS_I_AM_AWAKE: logfile("waitforbase got I am awake\n"); i_am_awake(); break; } } // we got something we need to reply to ExecuteReply() { int n; switch(RX_COMMAND) { case CMD_EEPROM_READ_16: break; } } main (int argc, char **argv) { int fd, n; unsigned char byte; int flushcounter=0; char tmpname[256]; // catch a signal and exit cleanly signal(SIGHUP, sigcatch); // open port initialise_coms("/dev/ttyS4", B9600, "/home/km/incoming/basecoms.log"); // WE EXIT HERE WHEN WE GET A PACKET TO SAY GO GPS while(1){ byte = getbyte(); COMINTInterpret (byte); } }