Пример #1
0
static void
psp_write(void)
{
        short int s;
	unsigned char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

        /* the header: */
        /* 31 6E 69 50 20 00 00 00 08 00 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 */
        /* offset 0x0C - 0x0D = 2 byte pin count */

        s = waypt_count();
        
        if (global_opts.synthesize_shortnames) {
            setshort_length(mkshort_handle, 32);
            setshort_whitespace_ok(mkshort_handle, 1);
        }

        if (s > MAXPSPOUTPUTPINS) {
            fatal(MYNAME ": attempt to output too many pushpins (%d).  The max is %d.  Sorry.\n", s, MAXPSPOUTPUTPINS);
        }

        /* insert waypoint count into header */
	le_write16(&header_bytes[12], s);

        gbfwrite(header_bytes, 1,  32, psp_file_out);

        waypt_disp_all(psp_waypt_pr);
}
Пример #2
0
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");
}
void CPocketStreetPushPinsWriter::Open(const TCHAR* pFilename)
{
	CGPSWriter::Open(pFilename);

	unsigned char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

    /* the header: */
    /* 31 6E 69 50 20 00 00 00 08 00 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 */
    /* offset 0x0C - 0x0D = 2 byte pin count */

	/* insert waypoint count into header */
	le_write16(&header_bytes[12], m_TotalPushPins);

	fwrite(header_bytes, 1, 32, m_fd);
}
Пример #4
0
int32
GPS_Write_Packet_usb(gpsdevh *dh, GPS_PPacket packet)
{
	garmin_usb_packet gp;
	memset(&gp, 0, sizeof(gp));


	/*
	 * Take the "portable" GPS_Packet data and put them into
	 * the USB packet that we will put on the wire.
	 */
	gp.gusb_pkt.type = 0x14;
    	le_write16(&gp.gusb_pkt.pkt_id, packet->type);
	le_write32(&gp.gusb_pkt.datasz, packet->n );
	memcpy(&gp.gusb_pkt.databuf, packet->data, packet->n);

	return  gusb_cmd_send(&gp, packet->n + 12);
}
Пример #5
0
/*
 * 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;
}
// Called for each cache to write out the corresponding waypoint to be used by the GPS
void CPocketStreetPushPinsWriter::OnCache(CGeoCache& Cache)
{
#ifndef M_PI
	#define M_PI 3.14159265358979323846
#endif

	AW_CONVERSION;

	char tbuf[64];
	int i;

	/* convert lat/long back to radians */
	double lat = (Cache.m_Lat * M_PI) / 180.0;
    double lon = (Cache.m_Long * M_PI) / 180.0;
        
	m_PIndex++;

	le_write16(tbuf, m_PIndex);
        
	/* 2 bytes - pin index */
    fwrite(tbuf, 1, 2, m_fd);
        
    /* 2 bytes - null bytes */
    memset(tbuf, '\0', sizeof(tbuf));
    fwrite(tbuf, 1, 2, m_fd);
        
	/* set the grid byte */
	char c = grid_byte(Cache.m_Lat, Cache.m_Long);

	/* since the grid byte matches with what pocketstreets does to   */
	/* input files, our output appears identical to a pin file that  */
    /* has already been processed and corrected by pocketstreets.    */
    /* Due to the grid and signs, it'll look different than one that */
    /* comes straight from S&T.                                      */
	
    /* the grid byte */
    fwrite(&c, 1, 1, m_fd);

    /* 8 bytes - latitude/radians */
	psp_fwrite_double(lat, m_fd);

    /* 8 bytes - longitude/radians */
	psp_fwrite_double(lon, m_fd);

    /* 1 byte - pin properties */
    c = 0x14; /* display pin name on, display notes on. 0x04 = no notes */
    fwrite(&c, 1, 1, m_fd);

    memset(tbuf, '\0', sizeof(tbuf));

    /* 3 unknown bytes */
    fwrite(tbuf, 1, 3, m_fd);

	char Icon[2] = {0,0};

	/*
	Traditional is a red box with a flag
	Mystery Cache is the pushpin.
	Multi is the Flags
	Event is the bubble text icon.
	Virtual is the arrow pointing right.
	*/

	#define	IconPin				0
	#define	IconBubble			1
	#define	IconRedBoxFlag		4
	#define	IconArrowToLeft		8
	#define	IconArrowToRight	9
	#define	IconArrowDown		10
	#define	IconFlags			18
	#define	IconLetter			29

	switch (Cache.TypeLookup())
	{
	case GT_Traditional:
		Icon[0] = IconRedBoxFlag;
		break;
	case GT_Multi:
		Icon[0] = IconFlags;
		break;
	case GT_Virtual:
		Icon[0] = IconArrowToRight;
		break;
	case GT_Webcam:
		Icon[0] = IconArrowDown;
		break;
	case GT_Unknown:
		Icon[0] = IconPin;
		break;
	case GT_LetterboxHybrid:
		Icon[0] = IconLetter;
		break;
	case GT_Event:
		Icon[0] = IconBubble;
		break;
	case GT_ProjectAPE:
		Icon[0] = IconRedBoxFlag;
		break;
	case GT_Locationless:
		Icon[0] = IconArrowToLeft;
		break;
	case GT_CITO:
		Icon[0] = IconBubble;
		break;
	case GT_Earthcache:
		Icon[0] = IconArrowToRight;
		break;
	}

    /* 1 icon byte 0x00 = PIN */
    fwrite(&Icon, 1, 1, m_fd);

    /* 3 unknown bytes */
    fwrite(tbuf, 1, 3, m_fd); /* 3 junk */

	//---------------------------------

	String Desc;

	Desc = Cache.m_Shortname;

	char* pDesc = w2a((TCHAR*) Desc.c_str());

    c = strlen(pDesc);

    /* 1 string size */
    fwrite(&c, 1, 1, m_fd);

    for (i = 0; pDesc[i]; i++) 
	{
		fwrite(&pDesc[i], 1, 1, m_fd);	/* char */
		fwrite(&tbuf[0], 1, 1, m_fd);		/* null */
    }

	//---------------------------------

	Desc = Cache.m_GsCacheType;
	Desc += _T(". ");
	Desc += Cache.m_GsCacheName;
	Desc += _T(" by ");
	Desc += Cache.m_GsCacheOwnerName;
	Desc += _T(". Rating: ");
	Desc += RatingToStringW(Cache.m_GsCacheDifficulty);
	Desc += _T("/");
	Desc += RatingToStringW(Cache.m_GsCacheTerrain);

	TCHAR		Buffer[20];

	Cache.LastFoundText(Buffer);

	Desc += _T(". Last found: ");
	Desc += Buffer;

	pDesc = w2a((TCHAR*) Desc.c_str());

	c = strlen(pDesc);

    /*  1 byte string size */
    fwrite(&c, 1, 1, m_fd);

    for (i = 0; pDesc[i]; i++)
	{
		fwrite(&pDesc[i], 1, 1, m_fd);	/* char */
        fwrite(&tbuf[0], 1, 1, m_fd);	/* null */
    }

	//---------------------------------

	// Scrap the last string

    c = strlen(tbuf);

    /* 1 byte string size */
    fwrite(&c, 1, 1, m_fd);

	for (i = 0; tbuf[i]; i++) 
	{
		fwrite(&tbuf[i], 1, 1, m_fd);              /* char */
		fwrite(&tbuf[0], 1, 1, m_fd);              /* null */
	}
}