diff options
Diffstat (limited to 'navit/vehicle/file')
-rw-r--r-- | navit/vehicle/file/vehicle_file.c | 1699 | ||||
-rw-r--r-- | navit/vehicle/file/vehicle_pipe.c | 6 | ||||
-rw-r--r-- | navit/vehicle/file/vehicle_serial.c | 6 | ||||
-rw-r--r-- | navit/vehicle/file/vehicle_socket.c | 6 |
4 files changed, 853 insertions, 864 deletions
diff --git a/navit/vehicle/file/vehicle_file.c b/navit/vehicle/file/vehicle_file.c index 10bce942b..807d4998d 100644 --- a/navit/vehicle/file/vehicle_file.c +++ b/navit/vehicle/file/vehicle_file.c @@ -1,4 +1,4 @@ -/** +/* * Navit, a modular navigation system. * Copyright (C) 2005-2008 Navit Team * @@ -28,7 +28,7 @@ #include <glib.h> #include <sys/stat.h> #ifdef _WIN32 - #include <serial_io.h> +#include <serial_io.h> #else #include <termios.h> #endif @@ -51,14 +51,21 @@ #include <winsock2.h> int inet_aton(const char *cp, struct in_addr *inp); -int inet_aton(const char *cp, struct in_addr *inp) -{ - unsigned long addr = inet_addr(cp); - inp->S_un.S_addr = addr; - return addr!=-1; +int inet_aton(const char *cp, struct in_addr *inp) { + unsigned long addr = inet_addr(cp); + inp->S_un.S_addr = addr; + return addr!=-1; } #endif +/** + * @defgroup vehicle-file Vehicle File + * @ingroup vehicle-plugins + * @brief The Vehicle to gain position data from a file, pipe, serial interface or a socket + * + * @{ + */ + static void vehicle_file_disable_watch(struct vehicle_priv *priv); static void vehicle_file_enable_watch(struct vehicle_priv *priv); static int vehicle_file_parse(struct vehicle_priv *priv, char *buffer); @@ -67,91 +74,87 @@ static void vehicle_file_close(struct vehicle_priv *priv); enum file_type { - file_type_pipe = 1, file_type_device, file_type_file, file_type_socket, file_type_serial + file_type_pipe = 1, file_type_device, file_type_file, file_type_socket, file_type_serial }; static int buffer_size = 1024; struct gps_sat { - int prn; - int elevation; - int azimuth; - int snr; + int prn; + int elevation; + int azimuth; + int snr; }; struct vehicle_priv { - char *source; - struct callback_list *cbl; - int fd; - struct callback *cb,*cbt; - char *buffer; - int buffer_pos; - char *nmea_data; - char *nmea_data_buf; - - struct coord_geo geo; - double speed; - double direction; - double height; - double hdop; - double vdop; - char fixtime[20]; - int fixyear; - int fixmonth; - int fixday; - int status; - int sats_used; - int sats_visible; - int sats_signal; - int time; - int on_eof; + char *source; + struct callback_list *cbl; + int fd; + struct callback *cb,*cbt,*cb_fix_timeout; + char *buffer; + int buffer_pos; + char *nmea_data; + char *nmea_data_buf; + + struct coord_geo geo; + double speed; + double direction; + double height; + double hdop; + double vdop; + char fixtime[20]; + int fixyear; + int fixmonth; + int fixday; + int status; + int sats_used; + int sats_visible; + int sats_signal; + int time; + int on_eof; #ifdef _WIN32 - int no_data_count; - struct event_timeout * timeout; - struct callback *timeout_callback; + int no_data_count; + struct event_timeout * timeout; + struct callback *timeout_callback; #endif - enum file_type file_type; - FILE *file; - struct event_watch *watch; - speed_t baudrate; - struct attr ** attrs; - char fixiso8601[128]; - int checksum_ignore; - int magnetic_direction; - int current_count; - struct gps_sat current[24]; - int next_count; - struct gps_sat next[24]; - struct item sat_item; - int valid; - char *statefile; - int process_statefile; + enum file_type file_type; + FILE *file; + struct event_watch *watch; + struct event_timeout *ev_fix_timeout; + speed_t baudrate; + struct attr ** attrs; + char fixiso8601[128]; + int checksum_ignore; + int magnetic_direction; + int current_count; + struct gps_sat current[24]; + int next_count; + struct gps_sat next[24]; + struct item sat_item; + int valid; + char *statefile; + int process_statefile; }; -//*************************************************************************** -/** @fn static int vehicle_win32_serial_track(struct vehicle_priv *priv) -***************************************************************************** -* @b Description: Callback of the plugin -***************************************************************************** -* @param priv : pointer on the private data of the plugin -***************************************************************************** -* @return always 1 -***************************************************************************** -**/ +/** +* @brief Callback of the plugin +* +* @param priv Pointer on the private data of the plugin +* +* @return Always 1 +*/ #ifdef _WIN32 -static int vehicle_win32_serial_track(struct vehicle_priv *priv) -{ +static int vehicle_win32_serial_track(struct vehicle_priv *priv) { static char buffer[2048] = {0,}; static int current_index = 0; const int chunk_size = 1024; int rc = 0; int dwBytes; - dbg(lvl_debug, "enter, *priv='%x', priv->source='%s'\n", priv, priv->source); + dbg(lvl_debug, "enter, *priv='%x', priv->source='%s'", priv, priv->source); - if ( priv->no_data_count > 5 ) - { + if ( priv->no_data_count > 5 ) { vehicle_file_close( priv ); priv->no_data_count = 0; vehicle_file_open( priv ); @@ -163,21 +166,18 @@ static int vehicle_win32_serial_track(struct vehicle_priv *priv) // vehicle_file_open( priv ); //} - if ( current_index >= ( sizeof( buffer ) - chunk_size ) ) - { + if ( current_index >= ( sizeof( buffer ) - chunk_size ) ) { // discard current_index = 0; - memset( buffer, 0 , sizeof( buffer ) ); + memset( buffer, 0, sizeof( buffer ) ); } dwBytes = serial_io_read( priv->fd, &buffer[ current_index ], chunk_size ); - if ( dwBytes > 0 ) - { + if ( dwBytes > 0 ) { char* return_pos = NULL; current_index += dwBytes; - while ( ( return_pos = strchr( buffer, '\n' ) ) != NULL ) - { + while ( ( return_pos = strchr( buffer, '\n' ) ) != NULL ) { char return_buffer[1024]; int bytes_to_copy = return_pos - buffer + 1; memcpy( return_buffer, buffer, bytes_to_copy ); @@ -188,867 +188,862 @@ static int vehicle_win32_serial_track(struct vehicle_priv *priv) rc += vehicle_file_parse( priv, return_buffer ); current_index -= bytes_to_copy; - memmove( buffer, &buffer[ bytes_to_copy ] , sizeof( buffer ) - bytes_to_copy ); + memmove( buffer, &buffer[ bytes_to_copy ], sizeof( buffer ) - bytes_to_copy ); } if (rc) { priv->no_data_count = 0; callback_list_call_attr_0(priv->cbl, attr_position_coord_geo); if (rc > 1) - dbg(lvl_error, "Can not keep with gps data delay is %d seconds\n", rc - 1); + dbg(lvl_error, "Can not keep with gps data delay is %d seconds", rc - 1); } - } - else - { + } else { priv->no_data_count++; } - dbg(lvl_info, "leave, return '1', priv->no_data_count='%d'\n", priv->no_data_count); + dbg(lvl_info, "leave, return '1', priv->no_data_count='%d'", priv->no_data_count); return 1; } #endif -//*************************************************************************** -/** @fn static int vehicle_file_open(struct vehicle_priv *priv) -***************************************************************************** -* @b Description: open dialogue with the GPS -***************************************************************************** -* @param priv : pointer on the private data of the plugin -***************************************************************************** -* @return 1 if ok -* 0 if error -***************************************************************************** -**/ -static int -vehicle_file_open(struct vehicle_priv *priv) -{ - char *name; +/** +* @brief Open dialogue with the GPS +* +* @param priv Pointer on the private data of the plugin +* +* @return 1 if ok, 0 if error +*/ +static int vehicle_file_open(struct vehicle_priv *priv) { + char *name; #ifndef _WIN32 - struct termios tio; + struct termios tio; #else - #define O_NDELAY 0 +#define O_NDELAY 0 #endif - name = priv->source + 5; - if (!strncmp(priv->source, "file:", 5)) { - priv->fd = open(name, O_RDONLY | O_NDELAY); - if (priv->fd < 0) - return 0; - if (file_is_reg(name)) { - priv->file_type = file_type_file; - } + name = priv->source + 5; + if (!strncmp(priv->source, "file:", 5)) { + priv->fd = open(name, O_RDONLY | O_NDELAY); + if (priv->fd < 0) + return 0; + if (file_is_reg(name)) { + priv->file_type = file_type_file; + } #ifndef _WIN32 - else { - tcgetattr(priv->fd, &tio); - cfmakeraw(&tio); - cfsetispeed(&tio, priv->baudrate); - cfsetospeed(&tio, priv->baudrate); - tio.c_cc[VMIN] = 0; - tio.c_cc[VTIME] = 200; - tcsetattr(priv->fd, TCSANOW, &tio); - priv->file_type = file_type_device; - } - } else if (!strncmp(priv->source,"pipe:", 5)) { - priv->file = popen(name, "r"); - if (!priv->file) - return 0; - priv->fd = fileno(priv->file); - priv->file_type = file_type_pipe; + else { + tcgetattr(priv->fd, &tio); + cfmakeraw(&tio); + cfsetispeed(&tio, priv->baudrate); + cfsetospeed(&tio, priv->baudrate); + tio.c_cc[VMIN] = 0; + tio.c_cc[VTIME] = 200; + tcsetattr(priv->fd, TCSANOW, &tio); + priv->file_type = file_type_device; + } + } else if (!strncmp(priv->source,"pipe:", 5)) { + priv->file = popen(name, "r"); + if (!priv->file) + return 0; + priv->fd = fileno(priv->file); + priv->file_type = file_type_pipe; #endif //!_WIN32 -#if defined(HAVE_SOCKET) || defined(HAVE_WINSOCK) - } else if (!strncmp(priv->source,"socket:", 7)) { - #ifdef _WIN32 - WSADATA wsi; - WSAStartup(0x00020002,&wsi); - #endif - char *p,*s=g_strdup(priv->source+7); - struct sockaddr_in sin; - p=strchr(s,':'); - if (!p) { - dbg(lvl_error,"port number missing in %s\n",s); - g_free(s); - return 0; - } - *p++='\0'; - sin.sin_family=AF_INET; - sin.sin_port=ntohs(atoi(p)); - if (!inet_aton(s, &sin.sin_addr)) { - dbg(lvl_error,"failed to parse %s\n",s); - g_free(s); - return 0; - } - priv->fd = socket(PF_INET, SOCK_STREAM, 0); - if (priv->fd != -1) { - if (connect(priv->fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - dbg(lvl_error,"failed to connect to %s:%s\n",s,p); - g_free(s); - return 0; - } - } - p=strchr(p,':'); - if (p) { - p++; - write(priv->fd, p, strlen(p)); - } - priv->file_type = file_type_socket; +#if defined(HAVE_SOCKET) || defined(HAVE_WINSOCK) + } else if (!strncmp(priv->source,"socket:", 7)) { +#ifdef _WIN32 + WSADATA wsi; + WSAStartup(0x00020002,&wsi); +#endif + char *p,*s=g_strdup(priv->source+7); + struct sockaddr_in sin; + p=strchr(s,':'); + if (!p) { + dbg(lvl_error,"port number missing in %s",s); + g_free(s); + return 0; + } + *p++='\0'; + sin.sin_family=AF_INET; + sin.sin_port=ntohs(atoi(p)); + if (!inet_aton(s, &sin.sin_addr)) { + dbg(lvl_error,"failed to parse %s",s); + g_free(s); + return 0; + } + priv->fd = socket(PF_INET, SOCK_STREAM, 0); + if (priv->fd != -1) { + if (connect(priv->fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + dbg(lvl_error,"failed to connect to %s:%s",s,p); + g_free(s); + return 0; + } + } + p=strchr(p,':'); + if (p) { + p++; + int write_result; + write_result = write(priv->fd, p, strlen(p)); + if (write_result == -1) { + dbg(lvl_warning, "write failed."); + } + } + priv->file_type = file_type_socket; #endif //HAVE_SOCKET - } else if (!strncmp(priv->source,"serial:",7)) { + } else if (!strncmp(priv->source,"serial:",7)) { #ifdef _WIN32 - char* raw_setting_str = g_strdup( priv->source ); - - char* strport = strchr(raw_setting_str, ':' ); - char* strsettings = strchr(raw_setting_str, ' ' ); - - if ( strport && strsettings ) - { - strport++; - *strsettings = '\0'; - strsettings++; - - priv->fd=serial_io_init( strport, strsettings ); - } - g_free( raw_setting_str ); - priv->file_type = file_type_serial; - // Add the callback - dbg(lvl_info, "Add the callback ...\n", priv->source); - priv->timeout_callback=callback_new_1(callback_cast(vehicle_win32_serial_track), priv); + char* raw_setting_str = g_strdup( priv->source ); + + char* strport = strchr(raw_setting_str, ':' ); + char* strsettings = strchr(raw_setting_str, ' ' ); + + if ( strport && strsettings ) { + strport++; + *strsettings = '\0'; + strsettings++; + + priv->fd=serial_io_init( strport, strsettings ); + } + g_free( raw_setting_str ); + priv->file_type = file_type_serial; + // Add the callback + dbg(lvl_info, "Add the callback ...", priv->source); + priv->timeout_callback=callback_new_1(callback_cast(vehicle_win32_serial_track), priv); #else - //TODO - add linux serial + //TODO - add linux serial #endif //!_WIN32 } return(priv->fd != -1); } -//*************************************************************************** -/** @fn static void vehicle_file_close(struct vehicle_priv *priv) -***************************************************************************** -* @b Description: close dialogue with the GPS -***************************************************************************** -* @param priv : pointer on the private data of the plugin -***************************************************************************** -**/ -static void -vehicle_file_close(struct vehicle_priv *priv) -{ - dbg(lvl_debug, "enter, priv->fd='%d'\n", priv->fd); - vehicle_file_disable_watch(priv); +/** +* @brief Close dialogue with the GPS +* +* @param priv Pointer on the private data of the plugin +*/ +static void vehicle_file_close(struct vehicle_priv *priv) { + dbg(lvl_debug, "enter, priv->fd='%d'", priv->fd); + vehicle_file_disable_watch(priv); #ifdef _WIN32 - if(priv->file_type == file_type_serial) - { + if(priv->file_type == file_type_serial) { if (priv->timeout_callback) { - callback_destroy(priv->timeout_callback); - priv->timeout_callback=NULL; // dangling pointer! prevent double freeing. + callback_destroy(priv->timeout_callback); + priv->timeout_callback=NULL; // dangling pointer! prevent double freeing. } - serial_io_shutdown( priv->fd ); - } - else + serial_io_shutdown( priv->fd ); + } else #endif { - if (priv->file) { + if (priv->file) { #ifndef _MSC_VER - pclose(priv->file); + pclose(priv->file); #endif /* _MSC_VER */ + } else if (priv->fd >= 0) { + close(priv->fd); + } + priv->file = NULL; + priv->fd = -1; } - else if (priv->fd >= 0) { - close(priv->fd); - } - priv->file = NULL; - priv->fd = -1; - } } -//*************************************************************************** -/** @fn static int vehicle_file_enable_watch_timer(struct vehicle_priv *priv) -***************************************************************************** -* @b Description: Enable watch timer to get GPS data -***************************************************************************** -* @param priv : pointer on the private data of the plugin -***************************************************************************** -* @return always 0 -***************************************************************************** -**/ -static int -vehicle_file_enable_watch_timer(struct vehicle_priv *priv) -{ - dbg(lvl_debug, "enter\n"); - vehicle_file_enable_watch(priv); - - return FALSE; +/** +* @brief Enable watch timer to get GPS data +* +* @param priv Pointer on the private data of the plugin +* +* @return Always 0 +*/ +static int vehicle_file_enable_watch_timer(struct vehicle_priv *priv) { + dbg(lvl_debug, "enter"); + vehicle_file_enable_watch(priv); + + return FALSE; +} + + +/** +* @brief This is a callback function, called when the fix timeout +* is done. Set the position to invalid. +* +* @param priv Pointer on the private data of the plugin +*/ +static void vehicle_file_fix_timeout_cb(struct vehicle_priv *priv) { + priv->valid = attr_position_valid_invalid; + priv->ev_fix_timeout = NULL; + callback_list_call_attr_0(priv->cbl, attr_position_coord_geo); } -//*************************************************************************** -/** @fn static int vehicle_file_parse( struct vehicle_priv *priv, -* char *buffer) -***************************************************************************** -* @b Description: Parse the buffer -***************************************************************************** -* @param priv : pointer on the private data of the plugin -* @param buffer : data buffer (null terminated) -***************************************************************************** -* @return 1 if The GPRMC Sentence is found -* 0 if not found -***************************************************************************** -**/ -static int -vehicle_file_parse(struct vehicle_priv *priv, char *buffer) -{ - char *nmea_data_buf, *p, *item[32]; - double lat, lng; - int i, j, bcsum; - int len = strlen(buffer); - unsigned char csum = 0; - int valid=0; - int ret = 0; - - dbg(lvl_info, "enter: buffer='%s'\n", buffer); - for (;;) { - if (len < 4) { - dbg(lvl_error, "'%s' too short\n", buffer); - return ret; - } - if (buffer[len - 1] == '\r' || buffer[len - 1] == '\n') { - buffer[--len] = '\0'; +/** +* @brief Cancel previous fix timeout event and add a new one +* +* @param priv Pointer on the private data of the plugin +*/ +static void vehicle_file_restart_fix_timeout(struct vehicle_priv *priv) { + if (priv->ev_fix_timeout != NULL) + event_remove_timeout(priv->ev_fix_timeout); + priv->ev_fix_timeout = event_add_timeout(10000, 0, priv->cb_fix_timeout); +} + + +/** +* @brief Parse the buffer +* +* @param priv Pointer on the private data of the plugin +* @param buffer Data buffer (null terminated) +* +* @return 1 if new coords were received (fixtime changed) or changed to invalid, +* 0 if not found +*/ +static int vehicle_file_parse(struct vehicle_priv *priv, char *buffer) { + char *nmea_data_buf, *p, *item[32]; + double lat, lng; + int i, j, bcsum; + int len = strlen(buffer); + unsigned char csum = 0; + int valid=0; + int ret = 0; + + dbg(lvl_info, "enter: buffer='%s'", buffer); + for (;;) { + if (len < 4) { + dbg(lvl_error, "'%s' too short", buffer); + return ret; + } + if (buffer[len - 1] == '\r' || buffer[len - 1] == '\n') { + buffer[--len] = '\0'; if (buffer[len - 1] == '\r') buffer[--len] = '\0'; } else - break; - } - if (buffer[0] != '$') { - dbg(lvl_error, "no leading $ in '%s'\n", buffer); - return ret; - } - if (buffer[len - 3] != '*') { - dbg(lvl_error, "no *XX in '%s'\n", buffer); - return ret; - } - for (i = 1; i < len - 3; i++) { - csum ^= (unsigned char) (buffer[i]); - } - if (!sscanf(buffer + len - 2, "%x", &bcsum) && priv->checksum_ignore != 2) { - dbg(lvl_error, "no checksum in '%s'\n", buffer); - return ret; - } - if (bcsum != csum && priv->checksum_ignore == 0) { - dbg(lvl_error, "wrong checksum in '%s was %x should be %x'\n", buffer,bcsum,csum); - return ret; - } - - if (!priv->nmea_data_buf || strlen(priv->nmea_data_buf) < 65536) { - nmea_data_buf=g_strconcat(priv->nmea_data_buf ? priv->nmea_data_buf : "", buffer, "\n", NULL); - g_free(priv->nmea_data_buf); - priv->nmea_data_buf=nmea_data_buf; - } else { - dbg(lvl_error, "nmea buffer overflow (len %zu), discarding '%s'\n", priv->nmea_data_buf?strlen(priv->nmea_data_buf):-1,buffer); - } - i = 0; - p = buffer; - while (i < 31) { - item[i++] = p; - while (*p && *p != ',') - p++; - if (!*p) - break; - *p++ = '\0'; - } - - if (!strncmp(&buffer[3], "GGA", 3)) { - /* 1 1111 - 0 1 2 3 4 5 6 7 8 9 0 1234 - $GPGGA,184424.505,4924.2811,N,01107.8846,E,1,05,2.5,408.6,M,,,,0000*0C - UTC of Fix[1],Latitude[2],N/S[3],Longitude[4],E/W[5],Quality(0=inv,1=gps,2=dgps)[6],Satelites used[7], - HDOP[8],Altitude[9],"M"[10],height of geoid[11], "M"[12], time since dgps update[13], dgps ref station [14] - */ - if (*item[2] && *item[3] && *item[4] && *item[5]) { - lat = g_ascii_strtod(item[2], NULL); - priv->geo.lat = floor(lat / 100); - lat -= priv->geo.lat * 100; - priv->geo.lat += lat / 60; - - if (!g_ascii_strcasecmp(item[3],"S")) - priv->geo.lat=-priv->geo.lat; - - lng = g_ascii_strtod(item[4], NULL); - priv->geo.lng = floor(lng / 100); - lng -= priv->geo.lng * 100; - priv->geo.lng += lng / 60; - - if (!g_ascii_strcasecmp(item[5],"W")) - priv->geo.lng=-priv->geo.lng; - priv->valid=attr_position_valid_valid; - - dbg(lvl_info, "latitude '%2.4f' longitude %2.4f\n", priv->geo.lat, priv->geo.lng); - - } else - priv->valid=attr_position_valid_invalid; - if (*item[6]) - sscanf(item[6], "%d", &priv->status); - if (*item[7]) - sscanf(item[7], "%d", &priv->sats_used); - if (*item[8]) - sscanf(item[8], "%lf", &priv->hdop); - if (*item[1]) - strncpy(priv->fixtime, item[1], sizeof(priv->fixtime)); - if (*item[9]) - sscanf(item[9], "%lf", &priv->height); - - g_free(priv->nmea_data); - priv->nmea_data=priv->nmea_data_buf; - priv->nmea_data_buf=NULL; - if (priv->file_type == file_type_file) { - if (priv->watch) { - vehicle_file_disable_watch(priv); - event_add_timeout(priv->time, 0, priv->cbt); - } - } - } - if (!strncmp(&buffer[3], "VTG", 3)) { - /* 0 1 2 34 5 6 7 8 - $GPVTG,143.58,T,,M,0.26,N,0.5,K*6A - Course Over Ground Degrees True[1],"T"[2],Course Over Ground Degrees Magnetic[3],"M"[4], - Speed in Knots[5],"N"[6],"Speed in KM/H"[7],"K"[8] - */ - if (item[1] && item[7]) - valid = 1; - if (i >= 10 && (*item[9] == 'A' || *item[9] == 'D')) - valid = 1; - if (valid) { - priv->direction = g_ascii_strtod( item[1], NULL ); - priv->speed = g_ascii_strtod( item[7], NULL ); - dbg(lvl_info,"direction %lf, speed %2.1lf\n", priv->direction, priv->speed); - } - } - if (!strncmp(&buffer[3], "RMC", 3)) { - /* 1 1 - 0 1 2 3 4 5 6 7 8 9 0 1 - $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A - Time[1],Active/Void[2],lat[3],N/S[4],long[5],W/E[6],speed in knots[7],track angle[8],date[9], - magnetic variation[10],magnetic variation direction[11] - */ - if (*item[2] == 'A') - valid = 1; - if (i >= 13 && (*item[12] == 'A' || *item[12] == 'D')) - valid = 1; - if (valid) { - priv->direction = g_ascii_strtod( item[8], NULL ); - priv->speed = g_ascii_strtod( item[7], NULL ); - priv->speed *= 1.852; - sscanf(item[9], "%02d%02d%02d", - &priv->fixday, - &priv->fixmonth, - &priv->fixyear); - priv->fixyear += 2000; - } - ret = 1; - } - if (!strncmp(buffer, "$GPGSV", 6) && i >= 4) { - /* - 0 GSV Satellites in view - 1 2 Number of sentences for full data - 2 1 sentence 1 of 2 - 3 08 Number of satellites in view - - 4 01 Satellite PRN number - 5 40 Elevation, degrees - 6 083 Azimuth, degrees - 7 46 SNR - higher is better - for up to 4 satellites per sentence - *75 the checksum data, always begins with * - */ - if (item[3]) { - sscanf(item[3], "%d", &priv->sats_visible); - } - j=4; - while (j+4 <= i && priv->current_count < 24) { - struct gps_sat *sat=&priv->next[priv->next_count++]; - sat->prn=atoi(item[j]); - sat->elevation=atoi(item[j+1]); - sat->azimuth=atoi(item[j+2]); - sat->snr=atoi(item[j+3]); - j+=4; - } - if (!strcmp(item[1], item[2])) { - priv->sats_signal=0; - for (i = 0 ; i < priv->next_count ; i++) { - priv->current[i]=priv->next[i]; - if (priv->current[i].snr) - priv->sats_signal++; - } - priv->current_count=priv->next_count; - priv->next_count=0; - } - } - if (!strncmp(&buffer[3], "ZDA", 3)) { - /* - 0 1 2 3 4 5 6 - $GPZDA,hhmmss.ss,dd,mm,yyyy,xx,yy*CC - hhmmss HrMinSec(UTC) - dd,mm,yyy Day,Month,Year - xx local zone hours -13..13 - yy local zone minutes 0..59 - */ - if (item[1] && item[2] && item[3] && item[4]) { - strncpy(priv->fixtime, item[1], strlen(priv->fixtime)); - priv->fixday = atoi(item[2]); - priv->fixmonth = atoi(item[3]); - priv->fixyear = atoi(item[4]); - } - } - if (!strncmp(buffer, "$IISMD", 6)) { - /* - 0 1 2 3 4 - $IISMD,dir,press,height,temp*CC" - dir Direction (0-359) - press Pressure (hpa, i.e. 1032) - height Barometric height above ground (meter) - temp Temperature (Degree Celsius) - */ - if (item[1]) { - priv->magnetic_direction = g_ascii_strtod( item[1], NULL ); - dbg(lvl_debug,"magnetic %d\n", priv->magnetic_direction); - } - } - return ret; + break; + } + if (buffer[0] != '$') { + dbg(lvl_error, "no leading $ in '%s'", buffer); + return ret; + } + if (buffer[len - 3] != '*') { + dbg(lvl_error, "no *XX in '%s'", buffer); + return ret; + } + for (i = 1; i < len - 3; i++) { + csum ^= (unsigned char) (buffer[i]); + } + if (!sscanf(buffer + len - 2, "%x", &bcsum) && priv->checksum_ignore != 2) { + dbg(lvl_error, "no checksum in '%s'", buffer); + return ret; + } + if (bcsum != csum && priv->checksum_ignore == 0) { + dbg(lvl_error, "wrong checksum in '%s was %x should be %x'", buffer,bcsum,csum); + return ret; + } + + if (!priv->nmea_data_buf || strlen(priv->nmea_data_buf) < 65536) { + nmea_data_buf=g_strconcat(priv->nmea_data_buf ? priv->nmea_data_buf : "", buffer, "\n", NULL); + g_free(priv->nmea_data_buf); + priv->nmea_data_buf=nmea_data_buf; + } else { + dbg(lvl_error, "nmea buffer overflow (len %zu), discarding '%s'", priv->nmea_data_buf?strlen(priv->nmea_data_buf):-1, + buffer); + } + i = 0; + p = buffer; + while (i < 31) { + item[i++] = p; + while (*p && *p != ',') + p++; + if (!*p) + break; + *p++ = '\0'; + } + + if (!strncmp(&buffer[3], "GGA", 3)) { + /* 1 1111 + 0 1 2 3 4 5 6 7 8 9 0 1234 + $GPGGA,184424.505,4924.2811,N,01107.8846,E,1,05,2.5,408.6,M,,,,0000*0C + UTC of Fix[1],Latitude[2],N/S[3],Longitude[4],E/W[5],Quality(0=inv,1=gps,2=dgps)[6],Satelites used[7], + HDOP[8],Altitude[9],"M"[10],height of geoid[11], "M"[12], time since dgps update[13], dgps ref station [14] + */ + if (*item[2] && *item[3] && *item[4] && *item[5] && *item[6] > 0) { + lat = g_ascii_strtod(item[2], NULL); + priv->geo.lat = floor(lat / 100); + lat -= priv->geo.lat * 100; + priv->geo.lat += lat / 60; + + if (!g_ascii_strcasecmp(item[3],"S")) + priv->geo.lat=-priv->geo.lat; + + lng = g_ascii_strtod(item[4], NULL); + priv->geo.lng = floor(lng / 100); + lng -= priv->geo.lng * 100; + priv->geo.lng += lng / 60; + + if (!g_ascii_strcasecmp(item[5],"W")) + priv->geo.lng=-priv->geo.lng; + + if (priv->valid == attr_position_valid_invalid) + ret = 1; + priv->valid = attr_position_valid_valid; + vehicle_file_restart_fix_timeout(priv); + + if (*item[1] && strncmp(priv->fixtime, item[1], sizeof(priv->fixtime))) { + ret = 1; + strncpy(priv->fixtime, item[1], sizeof(priv->fixtime)); + } + + dbg(lvl_info, "latitude '%2.4f' longitude %2.4f", priv->geo.lat, priv->geo.lng); + + } else { + if (priv->valid == attr_position_valid_valid) + ret = 1; + priv->valid=attr_position_valid_invalid; + } + + if (*item[6]) + sscanf(item[6], "%d", &priv->status); + if (*item[7]) + sscanf(item[7], "%d", &priv->sats_used); + if (*item[8]) + sscanf(item[8], "%lf", &priv->hdop); + if (*item[9]) + sscanf(item[9], "%lf", &priv->height); + + g_free(priv->nmea_data); + priv->nmea_data=priv->nmea_data_buf; + priv->nmea_data_buf=NULL; + if (priv->file_type == file_type_file) { + if (priv->watch) { + vehicle_file_disable_watch(priv); + event_add_timeout(priv->time, 0, priv->cbt); + } + } + } + if (!strncmp(&buffer[3], "VTG", 3)) { + /* 0 1 2 34 5 6 7 8 + $GPVTG,143.58,T,,M,0.26,N,0.5,K*6A + Course Over Ground Degrees True[1],"T"[2],Course Over Ground Degrees Magnetic[3],"M"[4], + Speed in Knots[5],"N"[6],"Speed in KM/H"[7],"K"[8] + */ + if (item[1] && item[7]) + valid = 1; + if (i >= 10 && (*item[9] == 'A' || *item[9] == 'D')) + valid = 1; + if (valid) { + priv->direction = g_ascii_strtod( item[1], NULL ); + priv->speed = g_ascii_strtod( item[7], NULL ); + dbg(lvl_info,"direction %lf, speed %2.1lf", priv->direction, priv->speed); + } + } + if (!strncmp(&buffer[3], "RMC", 3)) { + /* 1 1 + 0 1 2 3 4 5 6 7 8 9 0 1 + $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A + Time[1],Active/Void[2],lat[3],N/S[4],long[5],W/E[6],speed in knots[7],track angle[8],date[9], + magnetic variation[10],magnetic variation direction[11] + */ + if (*item[2] == 'A') + valid = 1; + if (i >= 13 && (*item[12] == 'A' || *item[12] == 'D')) + valid = 1; + if (valid) { + priv->direction = g_ascii_strtod( item[8], NULL ); + priv->speed = g_ascii_strtod( item[7], NULL ); + priv->speed *= 1.852; + sscanf(item[9], "%02d%02d%02d", + &priv->fixday, + &priv->fixmonth, + &priv->fixyear); + priv->fixyear += 2000; + + lat = g_ascii_strtod(item[3], NULL); + priv->geo.lat = floor(lat / 100); + lat -= priv->geo.lat * 100; + priv->geo.lat += lat / 60; + + if (!g_ascii_strcasecmp(item[4],"S")) + priv->geo.lat=-priv->geo.lat; + + lng = g_ascii_strtod(item[5], NULL); + priv->geo.lng = floor(lng / 100); + lng -= priv->geo.lng * 100; + priv->geo.lng += lng / 60; + + if (!g_ascii_strcasecmp(item[6],"W")) + priv->geo.lng=-priv->geo.lng; + + if (priv->valid == attr_position_valid_invalid) + ret = 1; + priv->valid=attr_position_valid_valid; + vehicle_file_restart_fix_timeout(priv); + + if (*item[1] && strncmp(priv->fixtime, item[1], sizeof(priv->fixtime))) { + ret = 1; + strncpy(priv->fixtime, item[1], sizeof(priv->fixtime)); + } + + dbg(lvl_info, "latitude '%2.4f' longitude %2.4f", priv->geo.lat, priv->geo.lng); + + } else { + if (priv->valid == attr_position_valid_valid) + ret = 1; + priv->valid=attr_position_valid_invalid; + } + } + if (!strncmp(buffer, "$GPGSV", 6) && i >= 4) { + /* + 0 GSV Satellites in view + 1 2 Number of sentences for full data + 2 1 sentence 1 of 2 + 3 08 Number of satellites in view + + 4 01 Satellite PRN number + 5 40 Elevation, degrees + 6 083 Azimuth, degrees + 7 46 SNR - higher is better + for up to 4 satellites per sentence + *75 the checksum data, always begins with * + */ + if (item[3]) { + sscanf(item[3], "%d", &priv->sats_visible); + } + j=4; + while (j+4 <= i && priv->current_count < 24) { + struct gps_sat *sat=&priv->next[priv->next_count++]; + sat->prn=atoi(item[j]); + sat->elevation=atoi(item[j+1]); + sat->azimuth=atoi(item[j+2]); + sat->snr=atoi(item[j+3]); + j+=4; + } + if (!strcmp(item[1], item[2])) { + priv->sats_signal=0; + for (i = 0 ; i < priv->next_count ; i++) { + priv->current[i]=priv->next[i]; + if (priv->current[i].snr) + priv->sats_signal++; + } + priv->current_count=priv->next_count; + priv->next_count=0; + } + } + if (!strncmp(&buffer[3], "ZDA", 3)) { + /* + 0 1 2 3 4 5 6 + $GPZDA,hhmmss.ss,dd,mm,yyyy,xx,yy*CC + hhmmss HrMinSec(UTC) + dd,mm,yyy Day,Month,Year + xx local zone hours -13..13 + yy local zone minutes 0..59 + */ + if (item[1] && item[2] && item[3] && item[4]) { + strncpy(priv->fixtime, item[1], strlen(priv->fixtime)); + priv->fixday = atoi(item[2]); + priv->fixmonth = atoi(item[3]); + priv->fixyear = atoi(item[4]); + } + } + if (!strncmp(buffer, "$IISMD", 6)) { + /* + 0 1 2 3 4 + $IISMD,dir,press,height,temp*CC" + dir Direction (0-359) + press Pressure (hpa, i.e. 1032) + height Barometric height above ground (meter) + temp Temperature (Degree Celsius) + */ + if (item[1]) { + priv->magnetic_direction = g_ascii_strtod( item[1], NULL ); + dbg(lvl_debug,"magnetic %d", priv->magnetic_direction); + } + } + return ret; } -//*************************************************************************** -/** @fn static void vehicle_file_io(struct vehicle_priv *priv) -***************************************************************************** -* @b Description: function to get data from GPS -***************************************************************************** -* @param priv : pointer on the private data of the plugin -***************************************************************************** -* @remarks -***************************************************************************** -**/ -static void -vehicle_file_io(struct vehicle_priv *priv) -{ - int size, rc = 0; - char *str, *tok; - dbg(lvl_debug, "vehicle_file_io : enter\n"); - - if (priv->process_statefile) { - unsigned char *data; - priv->process_statefile=0; - if (file_get_contents(priv->statefile, &data, &size)) { - if (size > buffer_size) - size=buffer_size; - memcpy(priv->buffer, data, size); - priv->buffer_pos=0; - g_free(data); - } else - return; - } else { - size = read(priv->fd, priv->buffer + priv->buffer_pos, buffer_size - priv->buffer_pos - 1); - } - if (size <= 0) { - switch (priv->on_eof) { - case 0: - vehicle_file_close(priv); - vehicle_file_open(priv); - break; - case 1: - vehicle_file_disable_watch(priv); - break; - case 2: - exit(0); - break; - } - return; - } - priv->buffer_pos += size; - priv->buffer[priv->buffer_pos] = '\0'; - dbg(lvl_debug, "size=%d pos=%d buffer='%s'\n", size, - priv->buffer_pos, priv->buffer); - str = priv->buffer; - while ((tok = strchr(str, '\n'))) { - *tok++ = '\0'; - dbg(lvl_debug, "line='%s'\n", str); - rc +=vehicle_file_parse(priv, str); - str = tok; - if (priv->file_type == file_type_file && rc) - break; - } - - if (str != priv->buffer) { - size = priv->buffer + priv->buffer_pos - str; - memmove(priv->buffer, str, size + 1); - priv->buffer_pos = size; - dbg(lvl_debug, "now pos=%d buffer='%s'\n", - priv->buffer_pos, priv->buffer); - } else if (priv->buffer_pos == buffer_size - 1) { - dbg(lvl_debug, - "Overflow. Most likely wrong baud rate or no nmea protocol\n"); - priv->buffer_pos = 0; - } - if (rc) - callback_list_call_attr_0(priv->cbl, attr_position_coord_geo); +/** +* @brief Function to get data from GPS +* +* @param priv Pointer on the private data of the plugin +*/ +static void vehicle_file_io(struct vehicle_priv *priv) { + int size, rc = 0; + char *str, *tok; + dbg(lvl_debug, "vehicle_file_io : enter"); + + if (priv->process_statefile) { + unsigned char *data; + priv->process_statefile=0; + if (file_get_contents(priv->statefile, &data, &size)) { + if (size > buffer_size) + size=buffer_size; + memcpy(priv->buffer, data, size); + priv->buffer_pos=0; + g_free(data); + } else + return; + } else { + size = read(priv->fd, priv->buffer + priv->buffer_pos, buffer_size - priv->buffer_pos - 1); + } + if (size <= 0) { + switch (priv->on_eof) { + case 0: + vehicle_file_close(priv); + vehicle_file_open(priv); + break; + case 1: + vehicle_file_disable_watch(priv); + break; + case 2: + exit(0); + break; + } + return; + } + priv->buffer_pos += size; + priv->buffer[priv->buffer_pos] = '\0'; + dbg(lvl_debug, "size=%d pos=%d buffer='%s'", size, + priv->buffer_pos, priv->buffer); + str = priv->buffer; + while ((tok = strchr(str, '\n'))) { + *tok++ = '\0'; + dbg(lvl_debug, "line='%s'", str); + rc +=vehicle_file_parse(priv, str); + str = tok; + if (priv->file_type == file_type_file && rc) + break; + } + + if (str != priv->buffer) { + size = priv->buffer + priv->buffer_pos - str; + memmove(priv->buffer, str, size + 1); + priv->buffer_pos = size; + dbg(lvl_debug, "now pos=%d buffer='%s'", + priv->buffer_pos, priv->buffer); + } else if (priv->buffer_pos == buffer_size - 1) { + dbg(lvl_debug, + "Overflow. Most likely wrong baud rate or no nmea protocol"); + priv->buffer_pos = 0; + } + if (rc) + callback_list_call_attr_0(priv->cbl, attr_position_coord_geo); } -//*************************************************************************** -/** @fn static void vehicle_file_enable_watch(struct vehicle_priv *priv) -***************************************************************************** -* @b Description: Enable watch -***************************************************************************** -* @param priv : pointer on the private data of the plugin -***************************************************************************** -**/ -static void -vehicle_file_enable_watch(struct vehicle_priv *priv) -{ - dbg(lvl_debug, "enter\n"); +/** +* @brief Enable watch +* +* @param priv Pointer on the private data of the plugin +*/ +static void vehicle_file_enable_watch(struct vehicle_priv *priv) { + dbg(lvl_debug, "enter"); #ifdef _WIN32 - // add an event : don't use glib timers and g_timeout_add - if (priv->file_type == file_type_serial) - { - if (priv->timeout_callback != NULL) + // add an event : don't use glib timers and g_timeout_add + if (priv->file_type == file_type_serial) { + if (priv->timeout_callback != NULL) priv->timeout = event_add_timeout(500, 1, priv->timeout_callback); else - dbg(lvl_warning, "error : watch not enabled : priv->timeout_callback is null\n"); } - else + dbg(lvl_warning, "error : watch not enabled : priv->timeout_callback is null"); + } else #endif { - if (! priv->watch) - priv->watch = event_add_watch(priv->fd, event_watch_cond_read, priv->cb); + if (! priv->watch) + priv->watch = event_add_watch(priv->fd, event_watch_cond_read, priv->cb); } } -//*************************************************************************** -/** @fn static void vehicle_file_disable_watch(struct vehicle_priv *priv) -***************************************************************************** -* @b Description: Disable watch -***************************************************************************** -* @param priv : pointer on the private data of the plugin -***************************************************************************** -**/ -static void -vehicle_file_disable_watch(struct vehicle_priv *priv) -{ - dbg(lvl_debug, "vehicle_file_disable_watch : enter\n"); +/** +* @brief Disable watch +* +* @param priv Pointer on the private data of the plugin +*/ +static void vehicle_file_disable_watch(struct vehicle_priv *priv) { + dbg(lvl_debug, "vehicle_file_disable_watch : enter"); #ifdef _WIN32 - if(priv->file_type == file_type_serial) - { - if (priv->timeout) { - event_remove_timeout(priv->timeout); - priv->timeout=NULL; // dangling pointer! prevent double freeing. + if(priv->file_type == file_type_serial) { + if (priv->timeout) { + event_remove_timeout(priv->timeout); + priv->timeout=NULL; // dangling pointer! prevent double freeing. } - } - else + } else #endif //!_WIN32 { - if (priv->watch) - event_remove_watch(priv->watch); - priv->watch = NULL; + if (priv->watch) + event_remove_watch(priv->watch); + priv->watch = NULL; } } -//*************************************************************************** -/** @fn static void vehicle_priv vehicle_file_destroy(struct vehicle_priv *priv) -***************************************************************************** -* @b Description: Function called to uninitialize the plugin -***************************************************************************** -* @param priv : pointer on the private data of the plugin -***************************************************************************** +/** +* @brief Function called to uninitialize the plugin +* +* @param priv Pointer on the private data of the plugin +* * @remarks private data is freed by this function (g_free) -***************************************************************************** -**/ -static void -vehicle_file_destroy(struct vehicle_priv *priv) -{ - if (priv->statefile && priv->nmea_data) { - struct attr readwrite={attr_readwrite}; - struct attr create={attr_create}; - struct attr *attrs[]={&readwrite,&create,NULL}; - struct file *f; - readwrite.u.num=1; - create.u.num=1; - f=file_create(priv->statefile, attrs); - if (f) { - file_data_write(f, 0, strlen(priv->nmea_data), priv->nmea_data); - file_fsync(f); - file_destroy(f); - } - } - vehicle_file_close(priv); - callback_destroy(priv->cb); - callback_destroy(priv->cbt); - if (priv->statefile) - g_free(priv->statefile); - if (priv->source) - g_free(priv->source); - if (priv->buffer) - g_free(priv->buffer); - g_free(priv); +*/ +static void vehicle_file_destroy(struct vehicle_priv *priv) { + if (priv->statefile && priv->nmea_data) { + struct attr readwrite= {attr_readwrite}; + struct attr create= {attr_create}; + struct attr *attrs[]= {&readwrite,&create,NULL}; + struct file *f; + readwrite.u.num=1; + create.u.num=1; + f=file_create(priv->statefile, attrs); + if (f) { + file_data_write(f, 0, strlen(priv->nmea_data), priv->nmea_data); + file_fsync(f); + file_destroy(f); + } + } + vehicle_file_close(priv); + callback_destroy(priv->cb); + callback_destroy(priv->cbt); + if (priv->statefile) + g_free(priv->statefile); + if (priv->source) + g_free(priv->source); + if (priv->buffer) + g_free(priv->buffer); + g_free(priv); } -//*************************************************************************** -/** @fn static int vehicle_file_position_attr_get(struct vehicle_priv *priv, -* enum attr_type type, -* struct attr *attr) -***************************************************************************** -* @b Description: Function called to get attribute -***************************************************************************** -* @param priv : pointer on the private data of the plugin -* @param type : attribute type called -* @param attr : structure to return the attribute value -***************************************************************************** -* @return 1 if ok -* 0 for unkown or invalid attribute -***************************************************************************** -**/ -static int -vehicle_file_position_attr_get(struct vehicle_priv *priv, - enum attr_type type, struct attr *attr) -{ - switch (type) { - case attr_position_fix_type: - attr->u.num = priv->status; - break; - case attr_position_height: - attr->u.numd = &priv->height; - break; - case attr_position_speed: - attr->u.numd = &priv->speed; - break; - case attr_position_direction: - attr->u.numd = &priv->direction; - break; - case attr_position_magnetic_direction: - attr->u.num = priv->magnetic_direction; - break; - case attr_position_hdop: - attr->u.numd = &priv->hdop; - break; - case attr_position_qual: - attr->u.num = priv->sats_visible; - break; - case attr_position_sats_signal: - attr->u.num = priv->sats_signal; - break; - case attr_position_sats_used: - attr->u.num = priv->sats_used; - break; - case attr_position_coord_geo: - attr->u.coord_geo = &priv->geo; - break; - case attr_position_nmea: - attr->u.str=priv->nmea_data; - if (! attr->u.str) - return 0; - break; - case attr_position_time_iso8601: - if (!priv->fixyear || !priv->fixtime[0]) - return 0; - sprintf(priv->fixiso8601, "%04d-%02d-%02dT%.2s:%.2s:%sZ", - priv->fixyear, priv->fixmonth, priv->fixday, - priv->fixtime, (priv->fixtime+2), (priv->fixtime+4)); - attr->u.str=priv->fixiso8601; - break; - case attr_position_sat_item: - dbg(lvl_debug,"at here\n"); - priv->sat_item.id_lo++; - if (priv->sat_item.id_lo > priv->current_count) { - priv->sat_item.id_lo=0; - return 0; - } - attr->u.item=&priv->sat_item; - break; - case attr_position_valid: - attr->u.num=priv->valid; - break; - default: - return 0; - } - if (type != attr_position_sat_item) - priv->sat_item.id_lo=0; - attr->type = type; - return 1; +/** +* @brief Function called to get attribute +* +* @param priv Pointer on the private data of the plugin +* @param type Attribute type called +* @param attr Structure to return the attribute value +* +* @return 1 if ok, 0 for unknown or invalid attribute +*/ +static int vehicle_file_position_attr_get(struct vehicle_priv *priv, + enum attr_type type, struct attr *attr) { + switch (type) { + case attr_position_fix_type: + attr->u.num = priv->status; + break; + case attr_position_height: + attr->u.numd = &priv->height; + break; + case attr_position_speed: + attr->u.numd = &priv->speed; + break; + case attr_position_direction: + attr->u.numd = &priv->direction; + break; + case attr_position_magnetic_direction: + attr->u.num = priv->magnetic_direction; + break; + case attr_position_hdop: + attr->u.numd = &priv->hdop; + break; + case attr_position_qual: + attr->u.num = priv->sats_visible; + break; + case attr_position_sats_signal: + attr->u.num = priv->sats_signal; + break; + case attr_position_sats_used: + attr->u.num = priv->sats_used; + break; + case attr_position_coord_geo: + attr->u.coord_geo = &priv->geo; + break; + case attr_position_nmea: + attr->u.str=priv->nmea_data; + if (! attr->u.str) + return 0; + break; + case attr_position_time_iso8601: + if (!priv->fixyear || !priv->fixtime[0]) + return 0; + sprintf(priv->fixiso8601, "%04d-%02d-%02dT%.2s:%.2s:%sZ", + priv->fixyear, priv->fixmonth, priv->fixday, + priv->fixtime, (priv->fixtime+2), (priv->fixtime+4)); + attr->u.str=priv->fixiso8601; + break; + case attr_position_sat_item: + dbg(lvl_debug,"at here"); + priv->sat_item.id_lo++; + if (priv->sat_item.id_lo > priv->current_count) { + priv->sat_item.id_lo=0; + return 0; + } + attr->u.item=&priv->sat_item; + break; + case attr_position_valid: + attr->u.num=priv->valid; + break; + default: + return 0; + } + if (type != attr_position_sat_item) + priv->sat_item.id_lo=0; + attr->type = type; + return 1; } -//*************************************************************************** -/** @fn static int vehicle_file_sat_attr_get(struct vehicle_priv *priv, -* enum attr_type type, -* struct attr *attr) -***************************************************************************** -* @b Description: Function called to get satellite attribute -***************************************************************************** -* @param priv : pointer on the private data of the plugin -* @param type : attribute type called -* @param attr : structure to return the attribute value -***************************************************************************** -* @return 1 if ok -* 0 for unkown attribute -***************************************************************************** -**/ -static int -vehicle_file_sat_attr_get(void *priv_data, enum attr_type type, struct attr *attr) -{ +/** +* @brief Function called to get satellite attribute +* +* @param priv Pointer on the private data of the plugin +* @param type Attribute type called +* @param attr Structure to return the attribute value +* +* @return 1 if ok, 0 for unknown attribute +*/ +static int vehicle_file_sat_attr_get(void *priv_data, enum attr_type type, struct attr *attr) { struct gps_sat *sat; - struct vehicle_priv *priv=priv_data; - if (priv->sat_item.id_lo < 1) - return 0; - if (priv->sat_item.id_lo > priv->current_count) - return 0; - sat=&priv->current[priv->sat_item.id_lo-1]; - switch (type) { - case attr_sat_prn: - attr->u.num=sat->prn; - break; - case attr_sat_elevation: - attr->u.num=sat->elevation; - break; - case attr_sat_azimuth: - attr->u.num=sat->azimuth; - break; - case attr_sat_snr: - attr->u.num=sat->snr; - break; - default: - return 0; - } - attr->type = type; - return 1; + struct vehicle_priv *priv=priv_data; + if (priv->sat_item.id_lo < 1) + return 0; + if (priv->sat_item.id_lo > priv->current_count) + return 0; + sat=&priv->current[priv->sat_item.id_lo-1]; + switch (type) { + case attr_sat_prn: + attr->u.num=sat->prn; + break; + case attr_sat_elevation: + attr->u.num=sat->elevation; + break; + case attr_sat_azimuth: + attr->u.num=sat->azimuth; + break; + case attr_sat_snr: + attr->u.num=sat->snr; + break; + default: + return 0; + } + attr->type = type; + return 1; } static struct item_methods vehicle_file_sat_methods = { - NULL, - NULL, - NULL, - vehicle_file_sat_attr_get, + NULL, + NULL, + NULL, + vehicle_file_sat_attr_get, }; static struct vehicle_methods vehicle_file_methods = { - vehicle_file_destroy, - vehicle_file_position_attr_get, + vehicle_file_destroy, + vehicle_file_position_attr_get, }; -//*************************************************************************** -/** @fn static struct vehicle_priv * vehicle_file_new_file( -* struct vehicle_methods *meth, -* struct callback_list *cbl, -* struct attr **attrs) -***************************************************************************** -* @b Description: Function called to initialize the plugin -***************************************************************************** -* @param meth : ? -* @param cbl : ? -* @param attrs : ? -***************************************************************************** -* @return pointer on the private data of the plugin -***************************************************************************** -* @remarks private data is allocated by this function (g_new0) -***************************************************************************** -**/ -static struct vehicle_priv * -vehicle_file_new_file(struct vehicle_methods - *meth, struct callback_list - *cbl, struct attr **attrs) -{ - struct vehicle_priv *ret; - struct attr *source; - struct attr *time; - struct attr *on_eof; - struct attr *baudrate; - struct attr *checksum_ignore; - struct attr *state_file; - - dbg(lvl_debug, "enter\n"); - - source = attr_search(attrs, NULL, attr_source); - if(source == NULL){ - dbg(lvl_error,"Missing source attribute"); - return NULL; +/** +* @brief Function called to initialize the plugin +* +* @param meth ? +* @param cbl ? +* @param attrs ? +* +* @return Pointer on the private data of the plugin +* +* @remarks Private data is allocated by this function (g_new0) +*/ +static struct vehicle_priv *vehicle_file_new_file(struct vehicle_methods + *meth, struct callback_list + *cbl, struct attr **attrs) { + struct vehicle_priv *ret; + struct attr *source; + struct attr *time; + struct attr *on_eof; + struct attr *baudrate; + struct attr *checksum_ignore; + struct attr *state_file; + + dbg(lvl_debug, "enter"); + + source = attr_search(attrs, NULL, attr_source); + if(source == NULL) { + dbg(lvl_error,"Missing source attribute"); + return NULL; } - ret = g_new0(struct vehicle_priv, 1); // allocate and initialize to 0 - ret->fd = -1; - ret->cbl = cbl; - ret->source = g_strdup(source->u.str); - ret->buffer = g_malloc(buffer_size); - ret->time=1000; - ret->baudrate=B4800; - state_file=attr_search(attrs, NULL, attr_state_file); - if (state_file) - ret->statefile=g_strdup(state_file->u.str); - time = attr_search(attrs, NULL, attr_time); - if (time) - ret->time=time->u.num; - baudrate = attr_search(attrs, NULL, attr_baudrate); - if (baudrate) { - switch (baudrate->u.num) { - case 4800: - ret->baudrate=B4800; - break; - case 9600: - ret->baudrate=B9600; - break; - case 19200: - ret->baudrate=B19200; - break; + ret = g_new0(struct vehicle_priv, 1); // allocate and initialize to 0 + ret->fd = -1; + ret->cbl = cbl; + ret->source = g_strdup(source->u.str); + ret->buffer = g_malloc(buffer_size); + ret->time=1000; + ret->baudrate=B4800; + ret->fixtime[0] = '\0'; + ret->ev_fix_timeout = NULL; + state_file=attr_search(attrs, NULL, attr_state_file); + if (state_file) + ret->statefile=g_strdup(state_file->u.str); + time = attr_search(attrs, NULL, attr_time); + if (time) + ret->time=time->u.num; + baudrate = attr_search(attrs, NULL, attr_baudrate); + if (baudrate) { + switch (baudrate->u.num) { + case 4800: + ret->baudrate=B4800; + break; + case 9600: + ret->baudrate=B9600; + break; + case 19200: + ret->baudrate=B19200; + break; #ifdef B38400 - case 38400: - ret->baudrate=B38400; - break; + case 38400: + ret->baudrate=B38400; + break; #endif #ifdef B57600 - case 57600: - ret->baudrate=B57600; - break; + case 57600: + ret->baudrate=B57600; + break; #endif #ifdef B115200 - case 115200: - ret->baudrate=B115200; - break; + case 115200: + ret->baudrate=B115200; + break; #endif - } - } - checksum_ignore = attr_search(attrs, NULL, attr_checksum_ignore); - if (checksum_ignore) - ret->checksum_ignore=checksum_ignore->u.num; - ret->attrs = attrs; - on_eof = attr_search(attrs, NULL, attr_on_eof); - if (on_eof && !g_ascii_strcasecmp(on_eof->u.str, "stop")) - ret->on_eof=1; - if (on_eof && !g_ascii_strcasecmp(on_eof->u.str, "exit")) - ret->on_eof=2; - dbg(lvl_debug,"on_eof=%d\n", ret->on_eof); - *meth = vehicle_file_methods; - ret->cb=callback_new_1(callback_cast(vehicle_file_io), ret); - ret->cbt=callback_new_1(callback_cast(vehicle_file_enable_watch_timer), ret); - if (ret->statefile && file_exists(ret->statefile)) { - ret->process_statefile=1; - event_add_timeout(1000, 0, ret->cb); - } - ret->sat_item.type=type_position_sat; - ret->sat_item.id_hi=ret->sat_item.id_lo=0; - ret->sat_item.priv_data=ret; - ret->sat_item.meth=&vehicle_file_sat_methods; + } + } + checksum_ignore = attr_search(attrs, NULL, attr_checksum_ignore); + if (checksum_ignore) + ret->checksum_ignore=checksum_ignore->u.num; + ret->attrs = attrs; + on_eof = attr_search(attrs, NULL, attr_on_eof); + if (on_eof && !g_ascii_strcasecmp(on_eof->u.str, "stop")) + ret->on_eof=1; + if (on_eof && !g_ascii_strcasecmp(on_eof->u.str, "exit")) + ret->on_eof=2; + dbg(lvl_debug,"on_eof=%d", ret->on_eof); + *meth = vehicle_file_methods; + ret->cb=callback_new_1(callback_cast(vehicle_file_io), ret); + ret->cbt=callback_new_1(callback_cast(vehicle_file_enable_watch_timer), ret); + ret->cb_fix_timeout=callback_new_1(callback_cast(vehicle_file_fix_timeout_cb), ret); + if (ret->statefile && file_exists(ret->statefile)) { + ret->process_statefile=1; + event_add_timeout(1000, 0, ret->cb); + } + ret->sat_item.type=type_position_sat; + ret->sat_item.id_hi=ret->sat_item.id_lo=0; + ret->sat_item.priv_data=ret; + ret->sat_item.meth=&vehicle_file_sat_methods; #ifdef _WIN32 - ret->no_data_count = 0; + ret->no_data_count = 0; #endif - dbg(lvl_debug, "vehicle_file_new_file:open\n"); - if (!vehicle_file_open(ret)) { - dbg(lvl_error, "Failed to open '%s'\n", ret->source); - } + dbg(lvl_debug, "vehicle_file_new_file:open"); + if (!vehicle_file_open(ret)) { + dbg(lvl_error, "Failed to open '%s'", ret->source); + } - vehicle_file_enable_watch(ret); - // vehicle_file_destroy(ret); - // return NULL; - dbg(lvl_debug, "leave\n"); - return ret; + vehicle_file_enable_watch(ret); + // vehicle_file_destroy(ret); + // return NULL; + dbg(lvl_debug, "leave"); + return ret; } -//*************************************************************************** -/** @fn void plugin_init(void) -***************************************************************************** -* @b Description: Initialisation of vehicle_file plugin -***************************************************************************** -**/ -void plugin_init(void) -{ - dbg(lvl_debug, "vehicle_file:plugin_init:enter\n"); - plugin_register_category_vehicle("file", vehicle_file_new_file); - plugin_register_category_vehicle("pipe", vehicle_file_new_file); - plugin_register_category_vehicle("socket", vehicle_file_new_file); - plugin_register_category_vehicle("serial", vehicle_file_new_file); +/** +* @brief Initialisation of vehicle_file plugin +*/ +void plugin_init(void) { + dbg(lvl_debug, "vehicle_file:plugin_init:enter"); + plugin_register_category_vehicle("file", vehicle_file_new_file); + plugin_register_category_vehicle("pipe", vehicle_file_new_file); + plugin_register_category_vehicle("socket", vehicle_file_new_file); + plugin_register_category_vehicle("serial", vehicle_file_new_file); } diff --git a/navit/vehicle/file/vehicle_pipe.c b/navit/vehicle/file/vehicle_pipe.c index 420390d4e..2f9f6c227 100644 --- a/navit/vehicle/file/vehicle_pipe.c +++ b/navit/vehicle/file/vehicle_pipe.c @@ -20,8 +20,6 @@ #include "config.h" #include "plugin.h" -void -plugin_init(void) -{ - plugin_get_category_vehicle("file"); +void plugin_init(void) { + plugin_get_category_vehicle("file"); } diff --git a/navit/vehicle/file/vehicle_serial.c b/navit/vehicle/file/vehicle_serial.c index 420390d4e..2f9f6c227 100644 --- a/navit/vehicle/file/vehicle_serial.c +++ b/navit/vehicle/file/vehicle_serial.c @@ -20,8 +20,6 @@ #include "config.h" #include "plugin.h" -void -plugin_init(void) -{ - plugin_get_category_vehicle("file"); +void plugin_init(void) { + plugin_get_category_vehicle("file"); } diff --git a/navit/vehicle/file/vehicle_socket.c b/navit/vehicle/file/vehicle_socket.c index 420390d4e..2f9f6c227 100644 --- a/navit/vehicle/file/vehicle_socket.c +++ b/navit/vehicle/file/vehicle_socket.c @@ -20,8 +20,6 @@ #include "config.h" #include "plugin.h" -void -plugin_init(void) -{ - plugin_get_category_vehicle("file"); +void plugin_init(void) { + plugin_get_category_vehicle("file"); } |