/** * Eugene Marinelli * 18549 Healthnet GPS daemon * 3/3/08 */ #include #include #include #include #include #include #include #include #include #include #include static void exit_handler(int servSock); static void sigint_handler(int a); static void* monitor_gps(void* arg); static void get_cur_gps_data(char* buf, char* req); static int serial_fd; static GpsData cur_data; static pthread_mutex_t cur_data_lock; static int servSock; static int time_available, location_available; int main(int argc, char** argv) { // Initialization. signal(SIGINT, sigint_handler); pthread_mutex_init(&cur_data_lock, NULL); // Spawn a separate thread for communicating with the gps. pthread_t gps_thread; pthread_attr_t pattr; pthread_attr_init(&pattr); pthread_create(&gps_thread, &pattr, monitor_gps, NULL); // Run server, doesn't return unless an error occurs. printf("Starting GPS data server...\n"); server(get_cur_gps_data, &servSock, GPS_ADDRESS); exit_handler(servSock); return 0; } static void get_cur_gps_data(char* buf, char* req) { pthread_mutex_lock(&cur_data_lock); buf[0] = 1 | (time_available << 1) | (location_available << 2); // Flag indicates what is present. if (location_available && time_available) { sprintf(buf+1, "%s,%lf,%f,%d,%f,%d", cur_data.time.date, cur_data.time.seconds, cur_data.location.latitude, cur_data.location.latitude_dir, cur_data.location.longitude, cur_data.location.longitude_dir); } else if (location_available) { sprintf(buf+1, "%f,%d,%f,%d", cur_data.location.latitude, cur_data.location.latitude_dir, cur_data.location.longitude, cur_data.location.longitude_dir); } else if (time_available) { sprintf(buf+1, "%s,%lf", cur_data.time.date, cur_data.time.seconds); } else { sprintf(buf+1, ""); } pthread_mutex_unlock(&cur_data_lock); } static void sigint_handler(int a) { exit_handler(servSock); } static void exit_handler(int servSock) { if (servSock) { if (close(servSock) == -1) { perror("close"); } } unlink(GPS_ADDRESS); printf("Closing gps serial connection...\n"); close(serial_fd); exit(1); } static int gpsdata_eq(GpsData a, GpsData b) { return (a.time.seconds == b.time.seconds) && (strcmp(a.time.date, b.time.date) == 0) && (a.location.latitude == b.location.latitude) && (a.location.longitude == b.location.longitude) && (a.location.latitude_dir == b.location.latitude_dir) && (a.location.longitude_dir == b.location.longitude_dir); } /* Thread which communicates with GPS device. */ static void* monitor_gps(void* arg) { printf("Connecting to GPS device (%s)...\n", GPS_SERIAL); serial_fd = init_serial(GPS_SERIAL, B4800, O_RDONLY); if (serial_fd == -1) { exit_handler(servSock); } while (1) { char buf[80]; int nrecv = read(serial_fd, buf, 80); if (nrecv > 0) { buf[nrecv] = 0; // Read does not append a 0!!! parser_feed(buf); pthread_mutex_lock(&cur_data_lock); GpsData tmpdata; int ret; if ((ret = parser_get_data(&tmpdata)) != -1) { if (ret == 0) { location_available = time_available = 1; } else if (ret == 1) { location_available = 1; time_available = 0; } else { time_available = 1; location_available = 0; } if (!gpsdata_eq(tmpdata, cur_data)) { cur_data = tmpdata; printf("New data: time: %f, latitude: %f, longitude: %f.\n", cur_data.time.seconds, cur_data.location.latitude, cur_data.location.longitude); } } pthread_mutex_unlock(&cur_data_lock); } } close(serial_fd); return NULL; }