⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 garmin_application.cp

📁 Garble is a C++ program for transferring data to and from Garmin GPS
💻 CP
📖 第 1 页 / 共 2 页
字号:
// -*- mode: c++; c-basic-offset: 8; -*-// $Id: garmin_application.cp,v 1.1.1.1 2000/02/21 06:17:21 decouto Exp $// garmin_application.cp// Douglas S. J. De Couto// September 9, 1998// Copyright (C) 1998 Douglas S. J. De Couto// <decouto@lcs.mit.edu>//// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License// as published by the Free Software Foundation; either version 2// of the License, or (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.#include "garmin_application.h"#include "garmin_command.h"#include "garmin_util.h"#ifdef DBUG#include <iostream>#endif#include <cctype>#include <algorithm>namespace garmin {using namespace std;#define check_init() if (!m_init) throw not_possible("The garmin application layer is not initialized")//////////////////product_data_typeapplication_layer::get_product_data(void) throw (not_possible, timeout){	check_init();		uint8 sz;	packet_id pid;		m_ll->put_packet(pid_product_rqst, m_buf, 0);	pid = m_ll->get_packet(m_buf, sz);		if (pid != pid_product_data) {		throw not_possible("GPS did not reply with product data packet");	}		if (sz < 5) {		throw not_possible("Product data packet is too small");	}		product_data_type pd;	sint16 *buf16 = (sint16 *) m_buf;	pd.product_id = garmin2host16(buf16[0]);	pd.software_version = garmin2host16(buf16[1]);	pd.product_description = &((char *) m_buf)[4];		// get capability protocol info... (A001),	// but not supported on all units!	try {		pid = m_ll->get_packet(m_buf, sz);	}	catch (timeout &ex) {		// timeout indicates gps is not sending capability protocol info		m_got_protocol_info = false;		return pd;	}	m_got_protocol_info = true;	if (pid != pid_protocol_array) {		throw not_possible("Product data packet followed by some packet besides capability protocol");	}	if ((sz % 3) != 0) {		throw not_possible("Capability protocol packet is strange size");	}		for (sint16 i = 0; i < sz; i +=3) {		// char tag = (char) m_buf[i];		// uint16 *data = (uint16 *) (m_buf + i + 1);				//		cout << "tag: " << tag << "; data: " << garmin2host16(*data) << endl;	}		return pd;}/////////////////waypt_vec_t *application_layer::get_waypoints(void) throw (not_possible, timeout){	check_init();		uint8 sz;	sint16 *buf16 = (sint16 *) m_buf;	char ident[7];	char cmnt[41];	ident[6] = cmnt[40] = 0;		buf16[0] = host2garmin16((sint16) cmnd_transfer_wpt);	m_ll->put_packet(pid_command_data, m_buf, 2);		packet_id pid = m_ll->get_packet(m_buf, sz);		if (pid != pid_records) {		throw not_possible("GPS did not reply with start of records data packet for waypoint data");	}	if (sz != 2) {		throw not_possible("Waypoint data start of records packet is wrong size");	}		sint16 num_recs = garmin2host16(buf16[0]);	waypt_vec_t *waypts = new waypt_vec_t(num_recs);			for (sint16 i = 0; i < num_recs; i++) {		basic_waypt_type &waypt = (*waypts)[i];				pid = m_ll->get_packet(m_buf, sz);				if (pid != pid_wpt_data) {			delete waypts;			throw not_possible("GPS did not send waypoint data packet");		}		if (sz < (6 + 8 + 4 + 40)) {			delete waypts;			throw not_possible("Waypoint data packet is too small");		}				uint32 *buf32 = (uint32 *) (m_buf + 6);		waypt.pos.lat = garmin2host32(buf32[0]);		waypt.pos.lon = garmin2host32(buf32[1]);		strncpy(ident, (char *) m_buf, 6);		waypt.id = string(ident);			strncpy(cmnt, (char *) (m_buf + 18), 40);		waypt.comment = string(cmnt);	}		pid = m_ll->get_packet(m_buf, sz);	if (pid != pid_xfer_cmplt) {		delete waypts;		throw not_possible("GPS did not terminate waypoint data with end of records packet");	}	if (garmin2host16(buf16[0]) != cmnd_transfer_wpt) {		delete waypts;		throw not_possible("End of records packet does not match original waypoint transfer command");	}			return waypts;		}/////////////////////void application_layer::send_waypoints(waypt_vec_t *waypts) throw (not_possible, timeout){	check_init();		product_data_type pd = get_product_data();	sint16 valid_products[] = { 73, 77, 87, 95, 96, 97, 100, 105, 106, -1 };	const	int d103_sz = 6 + 8 + 4 + 40 + 2;		bool is_valid_product = false;	int i = 0;	while (valid_products[i] != -1) {		if (pd.product_id == valid_products[i]) {			is_valid_product = true;			break;		}		i++;	}		if (!is_valid_product) {		throw not_possible("Waypoint download not supported for this GPS");	}	sint16 *buf16 = (sint16 *) m_buf;	buf16[0] = host2garmin16(waypts->size());		m_ll->put_packet(pid_records, m_buf, 2);		for (unsigned int i = 0; i < waypts->size(); i++) {		basic_waypt_type &w = (*waypts)[i];				// clear all fields		memset(m_buf, 0, d103_sz);		// set all waypt strings to blank spaces		memset(m_buf, ' ', 6);		memset(m_buf + 18, ' ', 40);				// copy in strings, fixing up for GPS; leave bad characters as spaces		for (size_t j = 0; j < min<size_t>(6, w.id.size()); j++) {			char c = w.id[j];			if (isalnum(c)) {				m_buf[j] = toupper(c);			}		}		for (size_t j = 0; j < min<size_t>(40, w.comment.length()); j++) {			char c = w.comment[j];			if (isalnum(c) || c == '-') {				m_buf[j + 18] = toupper(c);			}		}				// copy in position data		uint32 *buf32 = (uint32 *) (m_buf + 6);		buf32[0] = host2garmin32(w.pos.lat);		buf32[1] = host2garmin32(w.pos.lon);				m_ll->put_packet(pid_wpt_data, m_buf, d103_sz);	}		buf16[0] = host2garmin16(cmnd_transfer_wpt);	m_ll->put_packet(pid_xfer_cmplt, m_buf, 2);}/////////////////////route_list_t *application_layer::get_routes(void) throw (not_possible, timeout){	check_init();		uint16 *buf16 = (uint16 *) m_buf;	buf16[0] = host2garmin16((sint16) cmnd_transfer_rte);	m_ll->put_packet(pid_command_data, m_buf, 2);	uint8 sz;	packet_id pid = m_ll->get_packet(m_buf, sz);	if (pid != pid_records) {		throw not_possible("GPS did not reply with start of records data packet for route data");	}	if (sz != 2) {		throw not_possible("Route data start of records packet is wrong size");	}	sint16 num_packets = garmin2host16(buf16[0]);	// create route list with no routes	route_list_t *retval = new route_list_t(0);		bool curr_rt_exists = false;	for (sint16 i = 0; i < num_packets; i++) {		pid = m_ll->get_packet(m_buf, sz);		if (pid == pid_rte_hdr) {			// start new route			retval->push_back(list<basic_waypt_type>());			curr_rt_exists = true;			continue;		}				if (pid != pid_rte_wpt_data) {			delete retval;			throw not_possible("Packet is not route waypoint data or route header");		}		if (!curr_rt_exists) {			delete retval;			throw not_possible("Route waypoint data packet was not preceded by a route header packet");		}		if (sz < (6 + 8 + 2 + 40)) {			delete retval;			throw not_possible("Route waypoint data packet is too small");		}				semicircle_type *sp = (semicircle_type *) (m_buf + 6);		sp->lat = garmin2host32(sp->lat);		sp->lon = garmin2host32(sp->lon);		basic_waypt_type waypt;		char ident[7], cmnt[41];		ident[6] = cmnt[40] = 0;		strncpy(ident, (char *) m_buf, 6);		waypt.id = string(ident);		waypt.pos = *sp;				strncpy(cmnt, (char *) m_buf + 14, 40);		waypt.comment = string(cmnt);				// add this waypoint to end of last route in route list.		retval->back().push_back(waypt);			}		pid = m_ll->get_packet(m_buf, sz);	if (pid != pid_xfer_cmplt) {		delete retval;		throw not_possible("GPS did not terminate route data with end of records packet");	}	if (garmin2host16(buf16[0]) != cmnd_transfer_rte) {		delete retval;		throw not_possible("End of records packet does not match original route transfer command");	}			return retval;		}/////////////////////void application_layer::send_routes(route_list_t *routes) throw (not_possible, timeout){	check_init();			product_data_type pd = get_product_data();	sint16 valid_products[] = { 73, 77, 87, 95, 96, 97, 100, 105, 106, -1 };	const	int d103_sz = 6 + 8 + 4 + 40 + 2;		bool is_valid_product = false;	int i = 0;	while (valid_products[i] != -1) {		if (pd.product_id == valid_products[i]) {			is_valid_product = true;			break;		}		i++;	}		if (!is_valid_product) {		throw not_possible("Route download not supported for this GPS");	}		// how many data packets?	sint16 num_recs = 0;	route_list_t::const_iterator llw;	for (llw = routes->begin(); llw != routes->end(); llw++) {		num_recs += llw->size();	}	num_recs += routes->size(); // plus 1 header packet for each route		sint16 *buf16 = (sint16 *) m_buf;	buf16[0] = host2garmin16(num_recs);		m_ll->put_packet(pid_records, m_buf, 2);		for (llw = routes->begin(); llw != routes->end(); llw++) {				// put route header		m_buf[0] = 10;		char *test = "TESTING COMMENT     "; 		for (int k = 0; k < 20; k++) {			m_buf[k + 1] = test[k];		}		m_ll->put_packet(pid_rte_hdr, m_buf, 21);				// put route waypoints		route_t::const_iterator lw;		for (lw = llw->begin(); lw != llw->end(); lw++) {			memset(m_buf, 0, d103_sz);			// set all waypt strings to blank spaces			memset(m_buf, ' ', 6);			memset(m_buf + 18, ' ', 40);					// copy in strings, fixing up for GPS; leave bad characters as spaces			for (size_t j = 0; j < min<size_t>(6, lw->id.size()); j++) {				char c = lw->id[j];				if (isalnum(c)) {					m_buf[j] = toupper(c);				}			}			for (size_t j = 0; j < min<size_t>(40, lw->comment.length()); j++) {				char c = lw->comment[j];				if (isalnum(c) || c == '-') {					m_buf[j + 18] = toupper(c);				}			}					// copy in position data			uint32 *buf32 = (uint32 *) (m_buf + 6);			buf32[0] = host2garmin32(lw->pos.lat);			buf32[1] = host2garmin32(lw->pos.lon);					m_ll->put_packet(pid_rte_wpt_data, m_buf, d103_sz);		}	}	buf16[0] = host2garmin16(cmnd_transfer_rte);	m_ll->put_packet(pid_xfer_cmplt, m_buf, 2);}	/////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -