diff options
author | rikky <rikky@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2010-09-01 17:17:28 +0000 |
---|---|---|
committer | rikky <rikky@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2010-09-01 17:17:28 +0000 |
commit | 27b8a54e8b66839d9ff9d3114d5717910e133d17 (patch) | |
tree | 1fcde8cc8d6ebba942ce5f783c36bd14cf996160 /navit/vehicle | |
parent | 64b3d989706cde554551a32e6bbf492d61c5f1fd (diff) | |
download | navit-svn-27b8a54e8b66839d9ff9d3114d5717910e133d17.tar.gz |
Fix:vehicle_wince:Update of vehicle_wince with improvements from vehicle_file. Enables sat data and improves error handling.
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@3544 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/vehicle')
-rw-r--r-- | navit/vehicle/wince/vehicle_wince.c | 255 |
1 files changed, 162 insertions, 93 deletions
diff --git a/navit/vehicle/wince/vehicle_wince.c b/navit/vehicle/wince/vehicle_wince.c index 38ecce62..e8ce0a3b 100644 --- a/navit/vehicle/wince/vehicle_wince.c +++ b/navit/vehicle/wince/vehicle_wince.c @@ -64,6 +64,13 @@ static void vehicle_wince_close(struct vehicle_priv *priv); static const int buffer_size = 256; +struct gps_sat { + int prn; + int elevation; + int azimuth; + int snr; +}; + struct vehicle_priv { char *source; struct callback_list *cbl; @@ -91,14 +98,23 @@ struct vehicle_priv { int status; int sats_used; int sats_visible; + int sats_signal; int time; int on_eof; int baudrate; struct attr ** attrs; char fixiso8601[128]; int checksum_ignore; + int use_file; HMODULE hBthDll; PFN_BthSetMode BthSetMode; + 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; }; static void initBth(struct vehicle_priv *priv) @@ -345,24 +361,25 @@ vehicle_wince_close(struct vehicle_priv *priv) static int vehicle_wince_parse(struct vehicle_priv *priv, char *buffer) { - char *nmea_data_buf, *p, *item[16]; + char *nmea_data_buf, *p, *item[32]; double lat, lng; - int i, bcsum; - int len; + int i, j, bcsum; + int len = strlen(buffer); unsigned char csum = 0; + int valid=0; int ret = 0; - int valid = 0; - len = strlen(buffer); - //dbg(0, "buffer='%s'\n", buffer); + dbg(2, "enter: buffer='%s'\n", buffer); for (;;) { if (len < 4) { dbg(0, "'%s' too short\n", buffer); return ret; } - if (buffer[len - 1] == '\r' || buffer[len - 1] == '\n') + if (buffer[len - 1] == '\r' || buffer[len - 1] == '\n') { buffer[--len] = '\0'; - else + if (buffer[len - 1] == '\r') + buffer[--len] = '\0'; + } else break; } if (buffer[0] != '$') { @@ -376,17 +393,15 @@ vehicle_wince_parse(struct vehicle_priv *priv, char *buffer) for (i = 1; i < len - 3; i++) { csum ^= (unsigned char) (buffer[i]); } - if (!sscanf(buffer + len - 2, "%x", &bcsum)&& priv->checksum_ignore != 2) { + if (!sscanf(buffer + len - 2, "%x", &bcsum) && priv->checksum_ignore != 2) { dbg(0, "no checksum in '%s'\n", buffer); return ret; } if (bcsum != csum && priv->checksum_ignore == 0) { - dbg(0, "wrong checksum in '%s' %x vs %x\n", buffer, bcsum, csum); + dbg(0, "wrong checksum in '%s'\n", buffer); return ret; } -// RMC, RMB, VTG, and GLL in nmea 2.3 have status -// A=autonomous, D=differential, E=Estimated, N=not valid, S=Simulator. -// Only A and D are valid + 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); @@ -396,19 +411,14 @@ vehicle_wince_parse(struct vehicle_priv *priv, char *buffer) } i = 0; p = buffer; - while (i < 16) { + while (i < 31) { item[i++] = p; - while (*p && *p != ',' && *p != '\r') + while (*p && *p != ',') p++; if (!*p) break; *p++ = '\0'; } - if (0) { - int j = 0; - for (j=0; j < i; j++) - dbg(0,"[%d] = %s\n", j, item[j]); - } if (!strncmp(buffer, "$GPGGA", 6)) { /* 1 1111 @@ -417,36 +427,43 @@ vehicle_wince_parse(struct vehicle_priv *priv, char *buffer) 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] */ - lat = strtod(item[2], NULL); - priv->geo.lat = floor(lat / 100); - lat -= priv->geo.lat * 100; - priv->geo.lat += lat / 60; - - if (!strcasecmp(item[3],"S")) - priv->geo.lat=-priv->geo.lat; - - lng = strtod(item[4], NULL); - priv->geo.lng = floor(lng / 100); - lng -= priv->geo.lng * 100; - priv->geo.lng += lng / 60; - - if (!strcasecmp(item[5],"W")) - priv->geo.lng=-priv->geo.lng; - - sscanf(item[6], "%d", &priv->status); + 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 (!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 (!strcasecmp(item[5],"W")) + priv->geo.lng=-priv->geo.lng; + priv->valid=attr_position_valid_valid; + dbg(2, "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); - sscanf(item[8], "%lf", &priv->hdop); - strcpy(priv->fixtime, item[1]); - sscanf(item[9], "%lf", &priv->height); + 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; - - // callback_list_call_0(priv->cbl); - return 1; } if (!strncmp(buffer, "$GPVTG", 6)) { - /* 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], @@ -454,17 +471,12 @@ vehicle_wince_parse(struct vehicle_priv *priv, char *buffer) */ if (item[1] && item[7]) valid = 1; - if (i == 9 && (*item[9] == 'A' || *item[9] == 'D')) + 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 ); - } - else { - dbg(0, "GPVTG is invalid\n"); - int dbgItemIndex; - for (dbgItemIndex=0; dbgItemIndex < i; dbgItemIndex++) - dbg(1,"[%d] = %s\n", dbgItemIndex, item[dbgItemIndex]); + dbg(2,"direction %lf, speed %2.1lf\n", priv->direction, priv->speed); } } if (!strncmp(buffer, "$GPRMC", 6)) { @@ -473,10 +485,10 @@ vehicle_wince_parse(struct vehicle_priv *priv, char *buffer) $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')) + if (i >= 13 && (*item[12] == 'A' || *item[12] == 'D')) valid = 1; if (valid) { priv->direction = g_ascii_strtod( item[8], NULL ); @@ -488,28 +500,9 @@ vehicle_wince_parse(struct vehicle_priv *priv, char *buffer) &priv->fixyear); priv->fixyear += 2000; } - else { - dbg(0, "GPMRC is invalid\n"); - int dbgItemIndex; - for (dbgItemIndex=0; dbgItemIndex < i; dbgItemIndex++) - dbg(1,"[%d] = %s\n", dbgItemIndex, item[dbgItemIndex]); - } - } - if (!strncmp(buffer, "$GPGSA", 6)) { - /* - GSA Satellite status - A Auto selection of 2D or 3D fix (M = manual) - 3 3D fix - values include: 1 = no fix - 2 = 2D fix - 3 = 3D fix - 04,05... PRNs of satellites used for fix (space for 12) - 2.5 PDOP (dilution of precision) - 1.3 Horizontal dilution of precision (HDOP) - 2.1 Vertical dilution of precision (VDOP) - *39 the checksum data, always begins with * - */ + ret = 1; } - if (!strncmp(buffer, "$GPGSV", 6)) { + if (!strncmp(buffer, "$GPGSV", 6) && i >= 4) { /* 0 GSV Satellites in view 1 2 Number of sentences for full data @@ -526,6 +519,25 @@ vehicle_wince_parse(struct vehicle_priv *priv, char *buffer) 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, "$GPZDA", 6)) { /* @@ -537,14 +549,26 @@ vehicle_wince_parse(struct vehicle_priv *priv, char *buffer) yy local zone minutes 0..59 */ if (item[1] && item[2] && item[3] && item[4]) { - // priv->fixtime = atof(item[1]); - strcpy(priv->fixtime, item[1]); + strncpy(priv->fixtime, item[1], strlen(priv->fixtime)); priv->fixday = atoi(item[2]); priv->fixmonth = atoi(item[3]); priv->fixyear = atoi(item[4]); } } - dbg(1,"returning %d\n",ret); + 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(1,"magnetic %d\n", priv->magnetic_direction); + } + } return ret; } @@ -593,41 +617,40 @@ static int vehicle_wince_position_attr_get(struct vehicle_priv *priv, enum attr_type type, struct attr *attr) { - struct attr * active=NULL; - int check_status = 0; - switch (type) { case attr_position_fix_type: attr->u.num = priv->status; break; case attr_position_height: - check_status = 1; attr->u.numd = &priv->height; break; case attr_position_speed: - check_status = 1; attr->u.numd = &priv->speed; break; case attr_position_direction: - check_status = 1; 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: - check_status = 1; attr->u.coord_geo = &priv->geo; break; case attr_position_nmea: attr->u.str=priv->nmea_data; - if (!attr->u.str) + if (! attr->u.str) return 0; break; case attr_position_time_iso8601: @@ -635,24 +658,66 @@ vehicle_wince_position_attr_get(struct vehicle_priv *priv, 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)); + priv->fixtime, (priv->fixtime+2), (priv->fixtime+4)); attr->u.str=priv->fixiso8601; break; - case attr_active: - if (active != NULL && active->u.num == 1) - return 1; - else + case attr_position_sat_item: + dbg(0,"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; - if (check_status && 0 == priv->status) + return 1; +} + +static int +vehicle_wince_sat_attr_get(void *priv_data, enum attr_type type, struct attr *attr) +{ + 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; + struct gps_sat *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_wince_sat_methods = { + NULL, + NULL, + NULL, + vehicle_wince_sat_attr_get, +}; + struct vehicle_methods vehicle_wince_methods = { vehicle_wince_destroy, vehicle_wince_position_attr_get, @@ -694,23 +759,27 @@ vehicle_wince_new(struct vehicle_methods if (baudrate) { ret->baudrate = baudrate->u.num; } - ret->attrs = attrs; 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 && !strcasecmp(on_eof->u.str, "stop")) ret->on_eof=1; if (on_eof && !strcasecmp(on_eof->u.str, "exit")) ret->on_eof=2; dbg(0,"on_eof=%d\n", ret->on_eof); + *meth = vehicle_wince_methods; + 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_wince_sat_methods; handle_bluetooth = attr_search(attrs, NULL, attr_bluetooth); if ( handle_bluetooth && handle_bluetooth->u.num == 1 ) initBth(ret); - *meth = vehicle_wince_methods; if (vehicle_wince_open(ret)) { vehicle_wince_enable_watch(ret); return ret; |