//========================================================================================== // // Reads UDP telegrams in NMEA format, parse and send to stdout and to shared memory area // // Assumed format: $GPRMC,213429,A,6613.28,N,00630.76,E,05.4,103.,310503,00.,E*72 // Also assumes UDP telegram comes from EIVA "serial-to-UDP" program; have to correct for // a) there is a x0a (\n) at the start, // b) x00 and x0d at the end, after recvfrom routine // // Rev. Date By Description // ----------------------------------------------- // 0.1 6 Jun 2003 OM Test version // // Compilation: cc -o read-udp read-udp.c -lm -lpthread // // Code GPL from Sean Walton and Macmillan Publishers // Original file: connectionless-receiver.c // Also code (shared memory stuff) from WROX "Beginning Linux Programming" //========================================================================================= #include #include #include #include #include #include #include #define BUFSIZE 1024 #define PORT_NUMBER 5679 #include #include #include #include #include #include "shared_memory_common.h" #include int running = 1; void *shared_memory = (void *)0; struct shared_use_st *shared_stuff; int shmid; char buffer[BUFSIZE]; struct sockaddr_in addr; int sd, addr_size, bytes_read; //------------------------------------------------------------------ // CTRL-C handler. Program can then stop in an orderly way. //------------------------------------------------------------------ void ctrl_c_handler(int sig) // Executed on first ctrl-c { running = 0; // Program should now stop in orderly way (void) signal(SIGINT, SIG_DFL); // Next ctrl-c will act as usual close(sd); //------------------------------------ // Detach shared memory and delete it //------------------------------------ if (shmdt(shared_memory) == -1) { fprintf(stderr, "shmdt failed\n"); exit(EXIT_FAILURE); } if (shmctl(shmid, IPC_RMID, 0) == -1) { fprintf(stderr, "shmctl(IPC_RMID) failed\n"); exit(EXIT_FAILURE); } fprintf(stderr, "Detached and deleted shared memory\n"); exit(EXIT_SUCCESS); } void alltoupper(char* s) { while ( *s != 0 ) *s++ = toupper(*s); } int main() { (void) signal(SIGINT, ctrl_c_handler); // At first ctrl-c, execute handler // Get SHARED MEMORY area srand((unsigned int)getpid()); shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT); if (shmid == -1) { fprintf(stderr, "shmget feiled\n"); exit(EXIT_FAILURE); } //--------------------------------------------------- // Now make shared memory accessible to the program //--------------------------------------------------- shared_memory = shmat(shmid, (void *)0, 0); if (shared_memory == (void *)-1) { fprintf(stderr, "shmat failed\n"); exit(EXIT_FAILURE); } fprintf(stderr, "Memory attached at %X\n", (int)shared_memory); shared_stuff = (struct shared_use_st *)shared_memory; shared_stuff->DW_1 = 0; // Data written shared_stuff->DW_2 = 0; shared_stuff->DW_3 = 0; shared_stuff->DW_4 = 0; shared_stuff->DW_5 = 0; shared_stuff->DR_1 = 0; // Data read shared_stuff->DR_2 = 0; shared_stuff->DR_3 = 0; shared_stuff->DR_4 = 0; shared_stuff->DR_5 = 0; shared_stuff->quit = 0; shared_stuff->GPRMC_ready = 0; shared_stuff->GPHDT_ready = 0; /* while (running) { if (shared_stuff->DW_1 == 0) { strcpy(shared_stuff->UDP_telegram, "$GPRMC,1234,5678\n\x00"); shared_stuff->DW_1 = 1; // Tell consumer it can read printf("Hi consumer, there is data for you\n"); } if (shared_stuff->quit == 1) running=0; sleep(1); }*/ //------------------------------------ // Detach shared memory and delete it //------------------------------------ /* if (shmdt(shared_memory) == -1) { fprintf(stderr, "shmdt failed\n"); exit(EXIT_FAILURE); } if (shmctl(shmid, IPC_RMID, 0) == -1) { fprintf(stderr, "shmctl(IPC_RMID) failed\n"); exit(EXIT_FAILURE); } printf("Detached and deleted shared memory\n"); exit(EXIT_SUCCESS);*/ //---------------------------------- // Socket stuff: Read UDP telegram //---------------------------------- sd = socket(PF_INET, SOCK_DGRAM, 0); if ( sd < 0 ) { perror("socket"); abort(); } addr.sin_family = AF_INET; addr.sin_port = htons(PORT_NUMBER); addr.sin_addr.s_addr = INADDR_ANY; /// NB NB NB blir tull hvis udp telegram leses i annet program ogsaa if ( bind(sd, (struct sockaddr*)&addr, sizeof(addr)) < 0 ) { perror("bind"); abort(); } do { bzero(buffer, BUFSIZE); addr_size = BUFSIZE; bytes_read = recvfrom(sd, buffer, BUFSIZE, 0, (struct sockaddr*)&addr, &addr_size); if ( bytes_read > 0 ) { //printf(buffer); //printf("\n%i\n", bytes_read); //buffer[0] = "-"; //buffer[bytes_read-1]="/n"; buffer[bytes_read-2] = '\n'; // add newline buffer[bytes_read-1] = '\0'; // add zero terminator if (buffer[4] == 'R') { write(1, (buffer+1), (bytes_read-2)); // Write to standard output, skip '\n' at the beginning, 00 and 0xOD strncpy(shared_stuff->UDP_GPRMC, (buffer+1), (bytes_read-1)); // Write to shared memory. shared_stuff->GPRMC_ready = 1; // Tell consumer it can read fprintf(stderr,"+"); } if (buffer[4] == 'H') { strncpy(shared_stuff->UDP_GPHDT, (buffer+1), (bytes_read-1)); // Write to shared memory. shared_stuff->GPHDT_ready = 1; // Tell consumer it can read fprintf(stderr,"-"); } } else perror("recvfrom"); } while ( (bytes_read > 0) && (running == 1) ); close(sd); //------------------------------------ // Detach shared memory and delete it //------------------------------------ if (shmdt(shared_memory) == -1) { fprintf(stderr, "shmdt failed\n"); exit(EXIT_FAILURE); } if (shmctl(shmid, IPC_RMID, 0) == -1) { fprintf(stderr, "shmctl(IPC_RMID) failed\n"); exit(EXIT_FAILURE); } fprintf(stderr, "EXIT: Detached and deleted shared memory\n"); exit(EXIT_SUCCESS); }