summaryrefslogtreecommitdiff
path: root/navit/vehicle
diff options
context:
space:
mode:
authorrikky <rikky@ffa7fe5e-494d-0410-b361-a75ebd5db220>2010-09-01 17:17:28 +0000
committerrikky <rikky@ffa7fe5e-494d-0410-b361-a75ebd5db220>2010-09-01 17:17:28 +0000
commit27b8a54e8b66839d9ff9d3114d5717910e133d17 (patch)
tree1fcde8cc8d6ebba942ce5f783c36bd14cf996160 /navit/vehicle
parent64b3d989706cde554551a32e6bbf492d61c5f1fd (diff)
downloadnavit-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.c255
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;