コード例 #1
0
ファイル: gpsusbcommon.c プロジェクト: dongmingdmdm/OpenCPN
void
gusb_syncup(void)
{
	static int unit_number;
	static const char  oinit[12] =
		{0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0};
	garmin_usb_packet iresp;
	int i;

	/*
	 * This is our first communication with the unit.
	 */
	receive_state = rs_fromintr;

	for(i = 0; i < 25; i++) {
		le_write16(&iresp.gusb_pkt.pkt_id, 0);
		le_write32(&iresp.gusb_pkt.datasz, 0);
		le_write32(&iresp.gusb_pkt.databuf, 0);

		gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit));
		gusb_cmd_get(&iresp, sizeof(iresp));

		if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) &&
			(le_read32(iresp.gusb_pkt.datasz) == 4)) {
			unsigned serial_number = le_read32(iresp.gusb_pkt.databuf);
			garmin_unit_info[unit_number].serial_number = serial_number;
			gusb_id_unit(&garmin_unit_info[unit_number]);

			unit_number++;

			return;
		}
	}
	fatal("Unable to establish USB syncup\n");
}
コード例 #2
0
/*
 * Return values are:
 * Negative on error.
 * 1 if read success - even if empty packet.
 */
int32 GPS_Packet_Read_usb(gpsdevh *dh, GPS_PPacket *packet, int eat_bulk)
{
	int32  n;
	int32 payload_size;

	garmin_usb_packet pkt;

	memset(&pkt, 0, sizeof(pkt));
do_over:
	n = gusb_cmd_get(&pkt, sizeof(pkt));

	if ( n < 0 ) {
		/*
		 * We (probably) used to have a GPS and it went away 
	 	 * while we were speaking with it.  Perhaps batteries 
		 * died or it was unplugged or something.
		 */
		gps_errno = PROTOCOL_ERROR;
		return n;
	}

	/*
	 * This is a horrible hack for 276/296.   This family sometimes 
	 * switches between bulk and interrupt on EVERY packet.   Rather 
	 * than bother all the callers with that bit of unpleasantness, 
	 * silently consume zero byte "switch back to intr"  packets here.
	 *
	 * The one caller that doesn't want this hidden is device discovery
	 * in the A000 handler.
	 */
	if ((n == 0) && eat_bulk)  {
		goto do_over;
	}
	
	/* 
	 * Populate members of serial packet from USB packet.   The
	 * copy here seems wasteful, but teaching all the callers about
	 * a structure with the "data" member being in a different place 
	 * (Since the protocol packets was badly exposed in the core
	 * design of jeeps) is even more painful.
	 */
	(*packet)->type = le_read16(&pkt.gusb_pkt.pkt_id);
	payload_size = le_read32(&pkt.gusb_pkt.datasz);
	if (payload_size<0 || payload_size>MAX_GPS_PACKET_SIZE)
	{
		GPS_Error("GPS_Packet_Read_usb: Bad payload size %d", payload_size);
		gps_errno = FRAMING_ERROR;
		return 0;
	}
	(*packet)->n = payload_size;
	memcpy((*packet)->data, &pkt.gusb_pkt.databuf, payload_size);
	
	return 1;
}
コード例 #3
0
ファイル: mmo.c プロジェクト: idaohang/gpsbabel-flytec
static void
mmo_end_of_route(mmo_data_t *data)
{
#ifdef MMO_DBG
	const char *sobj = "CObjRoute";
#endif
	route_head *rte = data->data;
	int rtept = rte->rte_waypt_ct;
	int i;
	char buf[64];
		
	if (data->visible && data->loop) {
		DBG((sobj, "route \"%s\" is a loop.\n", data->name));
		(void) mmo_read_object(NULL);
		rtept--;
	}

	if (mmo_version >= 0x12) {
		mmo_fillbuf(buf, 7, 1);
		DBG((sobj, "route data (since 0x12): "));
		mmo_printbuf(buf, 7, "");
		
		rte->line_color.bbggrr = le_read32(&buf[0]);
		rte->line_color.opacity = 255 - (buf[6] * 51);
		DBG((sobj, "color = 0x%06X\n", rte->line_color.bbggrr));
		DBG((sobj, "transparency = %d (-> %d)\n", buf[6], rte->line_color.opacity));
	}

	if (data->visible) {
		for (i = 0; i < rtept; i++) (void) mmo_read_object(NULL);
	}
	if (data->loop && (data->done > 1)) {
		queue *elem;
					
		elem = QUEUE_FIRST(&rte->waypoint_list);
		dequeue(elem);
		ENQUEUE_TAIL(&rte->waypoint_list, elem);
	}

	if (rte->rte_waypt_ct == 0) {	/* don't keep empty routes */
		route_del_head(rte);
		data->data = NULL;
	}
}
コード例 #4
0
ファイル: gpslibusb.c プロジェクト: idaohang/gpsbabel-flytec
/*
 * This was a function of great joy to discover...and even greater to maintain.
 *
 * It turns out that as of 5/2006, every Garmin USB product has a problem
 * where the device does not reset the data toggles after a configuration
 * set.   After a reset, the toggles both match.  So we tear through the
 * conversation and life is good.  Unfortunately, the second time through,
 * if we had an odd number of transactions in the previous conversation,
 * we send a configuration set and reset the toggle on the HCI but the 
 * toggle on the device's end of the pipe is now out of whack which means
 * that the subsequent transaction will hang.
 * 
 * This isn't a problem in Windows since the configuration set is done only
 * once there.
 * 
 * This code has been tested in loops of 1000 cycles on Linux and OS/X and
 * it seems to cure this at a mere cost of complexity and startup time.  I'll
 * be delighted when all the firmware gets revved and updated and we can
 * remove this.
 *
 * 9/2008 But wait, there's more.   The very toggle reset that we *had* to 
 * implement in 2006 to make non-Windows OSes work actually locks up verion
 * 2.70 of the Venture HC.   On that model, the second product request 
 * (you know, the one that we *use*, locks that device's protocol stack
 * after the RET2INTR that immediately follows the REQBLK (and why is it
 * telling us to go into bulk mode followed by an immeidate EOF, anyway?)
 * that follows the request for product ID.   100% reproducible on Mac and
 * Linux.    Of course, we don't see this on the Windows system becuase
 * we don't have to jump through hooops to clear the spec-violating out
 * of state toggles there becuase those systems see only one configuration
 * set ever.
 *
 * Grrrr!
 */
unsigned 
gusb_reset_toggles(void)
{
	static const char  oinit[12] = 
		{0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0};
	static const char  oid[12] = 
		{20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0};
	garmin_usb_packet iresp;
	int t;
	unsigned rv = 0;

	/* Start off with three session starts.
	 * #1 resets the bulk out toggle.  It may not make it to the device.
	 * #2 resets the the intr in toggle.  It will make it to the device
	 *	since #1 reset the the bulk out toggle.   The device will
	 *      respond on the intr in pipe which will clear its toggle.
	 * #3 actually starts the session now that the above are both clear.
 	 */

	gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit));
	gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit));
	gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit));

	t = 10;
	while(1) {
		le_write16(&iresp.gusb_pkt.pkt_id, 0);
		le_write32(&iresp.gusb_pkt.datasz, 0);
		le_write32(&iresp.gusb_pkt.databuf, 0);

		gusb_cmd_get(&iresp, sizeof(iresp));

		if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) &&
                        (le_read32(iresp.gusb_pkt.datasz) == 4)) {
				break;
		}
		if (t-- <= 0) {
			fatal("Could not start session in a reasonable number of tries.\n");
		}
	}

	/*
	 * Now that the bulk out and intr in packets are good, we send
	 * a product ID.    On devices that respond totally on the intr
	 * pipe, this does nothing interesting, but on devices that respon
	 * on the bulk pipe this will reset the toggles on the bulk in.
 	 */

	t = 10;
	gusb_cmd_send((const garmin_usb_packet *) oid, sizeof(oid));
	while(1) {
		le_write16(&iresp.gusb_pkt.pkt_id, 0);
		le_write32(&iresp.gusb_pkt.datasz, 0);
		le_write32(&iresp.gusb_pkt.databuf, 0);

		gusb_cmd_get(&iresp, sizeof(iresp));

		if (le_read16(iresp.gusb_pkt.pkt_id) == 0xff) {
			rv = le_read16(iresp.gusb_pkt.databuf+0);
		}

		if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) return rv;
		if (t-- <= 0) {
			fatal("Could not start session in a reasonable number of tries.\n");
		}
	}
	return 0;
}
コード例 #5
0
ファイル: mmo.c プロジェクト: idaohang/gpsbabel-flytec
static void
mmo_read_CObjWaypoint(mmo_data_t *data)
{
#ifdef MMO_DBG
	const char *sobj = "CObjWaypoint";
#endif
	waypoint *wpt;
	time_t time;
	int rtelinks;
	mmo_data_t **rtelink = NULL;
	char *str;
	char buf[16];
	int i, ux;
	
	DBG((sobj, ":-----------------------------------------------------\n"));
	DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", 
		data->name, data->visible ? "yes" : "NO", data->objid));

	wpt = waypt_new();
	wpt->shortname = xstrdup(data->name);

	time = data->mtime;
	if (! time) time = data->ctime;
	if (time > 0) wpt->creation_time = time;

	wpt->latitude = gbfgetdbl(fin);
	wpt->longitude = gbfgetdbl(fin);

	DBG((sobj, "coordinates = %f / %f\n", wpt->latitude, wpt->longitude));

	rtelinks = gbfgetuint16(fin);
	if (rtelinks > 0) {

		rtelink = xcalloc(sizeof(*rtelink), rtelinks);
		DBG((sobj, "rtelinks = %d\n", rtelinks));

		for (i = 0; i < rtelinks; i++) {
			mmo_data_t *tmp;
			int objid;			

			DBG((sobj, "read rtelink number %d\n", i + 1));

			objid = gbfgetuint16(fin);
			gbfseek(fin, -2, SEEK_CUR);

			rtelink[i] = tmp = mmo_read_object(wpt);
			
			if ((objid < 0x8000) && (tmp != NULL) && (tmp->type == rtedata)) {
				route_head *rte = tmp->data;

				tmp->left--;
				route_add_wpt(rte, waypt_dupe(wpt));

				DBG((sobj, "\"%s\" Added to route \"%s\"\n", wpt->shortname, rte->rte_name));
			}
		}

	}
	
	str = mmo_readstr();	/* descr + url */
	if (strncmp(str, "_FILE_ ", 7) == 0) {
		char *cx, *cend;
		
		cx = lrtrim(str + 7);
		cend = strchr(cx, '\n');
		if (cend == NULL) cend = cx + strlen(cx);
		
		cx = lrtrim(xstrndup(cx, cend - cx));
		if (*cx) wpt->url = cx;
		else xfree(cx);

		if (*cend++) wpt->notes = xstrdup(cend);
		
		if (wpt->url) DBG((sobj, "url = \"%s\"\n", wpt->url));
	}
	else
		if (*str) wpt->notes = xstrdup(str);
	xfree(str);

	if (wpt->notes) DBG((sobj, "notes = \"%s\"\n", wpt->notes));

	mmo_fillbuf(buf, 12, 1);
	i = le_read32(&buf[8]);		/* icon */
	if (i != -1) {
		char key[16];
		char *name;
		
		snprintf(key, sizeof(key), "%d", i);
		if (avltree_find(icons, key, (void *)&name)) {
			wpt->icon_descr = xstrdup(name);
			wpt->wpt_flags.icon_descr_is_dynamic = 1;
			DBG((sobj, "icon = \"%s\"\n", wpt->icon_descr));
		}
	}

	wpt->proximity = le_read_float(&buf[4]);
	if (wpt->proximity) {
		wpt->wpt_flags.proximity = 1;
		DBG((sobj, "proximity = %f\n", wpt->proximity));
	}

	str = mmo_readstr();	/* name on gps ??? option ??? */
	if (*str) {
		wpt->description = wpt->shortname;
		wpt->shortname = str;
		DBG((sobj, "name on gps = %s\n", str));
	}
	else xfree(str);

	ux = gbfgetuint32(fin);
	DBG((sobj, "proximity type = %d\n", ux));

	if (rtelinks) {
		int i;

		for (i = 0; i < rtelinks; i++) {
			int j;
			route_head *rte = rtelink[i]->data;

			for (j = 0; j < rtelinks; j++) {
				if ((i != j) && (rtelink[i] == rtelink[j])) {
					rtelink[i]->loop = 1;
					break;
				}
			}
			rtelink[i]->done++;
			if ((rtelink[i]->left == 0) && (rtelink[i]->done == rte->rte_waypt_ct)) {
				if (mmo_version <= 0x11) mmo_end_of_route(rtelink[i]);
			}
		}
	}

	if (rtelink) {
		xfree(rtelink);
		waypt_free(wpt);
		data->data = NULL;
	}
	else waypt_add(wpt);
}
コード例 #6
0
ファイル: gpsusbread.c プロジェクト: alexbirkett/GPSBabel
/*
 * Return values are:
 * Negative on error.
 * 1 if read success - even if empty packet.
 */
int32 GPS_Packet_Read_usb(gpsdevh *dh, GPS_PPacket *packet, int eat_bulk)
{
	int32  n;
	int32 payload_size;

	garmin_usb_packet pkt;

	memset(&pkt, 0, sizeof(pkt));
do_over:
	n = gusb_cmd_get(&pkt, sizeof(pkt));

	if ( n < 0 ) {
		/*
		 * We (probably) used to have a GPS and it went away 
	 	 * while we were speaking with it.  Perhaps batteries 
		 * died or it was unplugged or something.
		 */
		gps_errno = PROTOCOL_ERROR;
		return n;
	}

	/*
	 * This is a horrible hack for 276/296.   This family sometimes 
	 * switches between bulk and interrupt on EVERY packet.   Rather 
	 * than bother all the callers with that bit of unpleasantness, 
	 * silently consume zero byte "switch back to intr"  packets here.
	 *
	 * The one caller that doesn't want this hidden is device discovery
	 * in the A000 handler.
	 */
	if ((n == 0) && eat_bulk)  {
		goto do_over;
	}
	
	/* We sometimes get corrupted packets during a track log transfer
	 * where the first byte in a packet is lost, causing all remaining
	 * bytes in this packet to be shifted. So far, this has only been
	 * observed on a Forerunner 305 (both on Linux and Windows). The
	 * cause is unknown, but it seems to be timing dependent.
	 * We try to detect the corruption mainly by checking reserved bytes
	 * 3 and 7 which normally should be 0, the remaining comparisons are
	 * only sanity checks and they alone could also trigger in case of
	 * valid packets. Note: We can't detect corrupted packets with an ID
	 * or length that's a multiple of 256, but such corrupted packets
	 * haven't been observed so far.
	 */
	if (gps_save_id == 484
	    && pkt.gusb_pkt.type == 0 && pkt.gusb_pkt.reserved1 == 0
	    && pkt.gusb_pkt.reserved2 == 0 && pkt.gusb_pkt.reserved3 != 0
	    && pkt.gusb_pkt.pkt_id[0] <= 4 && pkt.gusb_pkt.pkt_id[1] == 0
	    && pkt.gusb_pkt.reserved6 == 0 && pkt.gusb_pkt.reserved7 != 0) {
		memmove(&pkt.dbuf[1], &pkt.dbuf[0], sizeof(pkt) - 1);
		pkt.gusb_pkt.type = 20;
	}
	
	/* 
	 * Populate members of serial packet from USB packet.   The
	 * copy here seems wasteful, but teaching all the callers about
	 * a structure with the "data" member being in a different place 
	 * (Since the protocol packets was badly exposed in the core
	 * design of jeeps) is even more painful.
	 */
	(*packet)->type = le_read16(&pkt.gusb_pkt.pkt_id);
	payload_size = le_read32(&pkt.gusb_pkt.datasz);
	if (payload_size<0 || payload_size>MAX_GPS_PACKET_SIZE)
	{
		/* If you get this, the packet might have been corrupted
		 * by the unit. Have a look at the corruption detection
		 * code above.
		 */
		GPS_Error("GPS_Packet_Read_usb: Bad payload size %d", payload_size);
		gps_errno = FRAMING_ERROR;
		return 0;
	}
	(*packet)->n = payload_size;
	memcpy((*packet)->data, &pkt.gusb_pkt.databuf, payload_size);
	
	return 1;
}
コード例 #7
0
static void
lowranceusr_parse_waypt(waypoint *wpt_tmp)
{
	char buff[MAXUSRSTRINGSIZE + 1];
	int text_len;
	time_t waypt_time;
	short waypt_type;

	wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in));
	wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in));
	wpt_tmp->altitude = FEET_TO_METERS(gbfgetint32(file_in));
	if (wpt_tmp->altitude <= UNKNOWN_USR_ALTITUDE) {
		wpt_tmp->altitude = unknown_alt;
	}

	text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in);
	if (text_len) {
		buff[text_len] = '\0';
		wpt_tmp->shortname = xstrdup(buff);
	}

	if (global_opts.debug_level >= 1)
		printf(MYNAME " parse_waypt: Waypt name = %s Lat = %f Lon = %f alt = %f\n",wpt_tmp->shortname, wpt_tmp->latitude,
			wpt_tmp->longitude, wpt_tmp->altitude);

	text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in);
	if (text_len) {
		buff[text_len] = '\0';
		wpt_tmp->description = xstrdup(buff);
	}
	/* Time is number of seconds since Jan. 1, 2000 */
	waypt_time = gbfgetint32(file_in);
	if (waypt_time)
		wpt_tmp->creation_time = base_time_secs + waypt_time;

	if (global_opts.debug_level >= 2)
	{
		printf(MYNAME " parse_waypt: creation time %d\n", 
			(int)wpt_tmp->creation_time);
		printf(MYNAME " parse_waypt: base_time %d\n", (int)base_time_secs);
		printf(MYNAME " parse_waypt: waypt time %d\n", (int)waypt_time);
	}

	/* Symbol ID */
	wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(gbfgetint32(file_in));
	if (!wpt_tmp->icon_descr[0]) {
		char nbuf[10];
		snprintf(nbuf, sizeof(nbuf), "%d", le_read32(buff));
		wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1;
		wpt_tmp->icon_descr = xstrdup(nbuf);
	}

	/* Waypoint Type (USER, TEMPORARY, POINT_OF_INTEREST) */
	waypt_type = gbfgetint16(file_in);
	if (global_opts.debug_level >= 1)
		printf(MYNAME " parse_waypt: waypt_type = %d\n",waypt_type);

        // Version 3 has a depth field here.
        if (reading_version >= 3) {
          float depth_feet = gbfgetflt(file_in);
          if (abs(depth_feet - 99999.0)  > .1)
            WAYPT_SET(wpt_tmp, depth, FEET_TO_METERS(depth_feet));
        }

}