📄 garmin_application.cp
字号:
voidapplication_layer::send_track_logs(track_list_t *tracks) throw (not_possible, timeout){ check_init(); // how many track points? sint16 num_recs = 0; track_list_t::const_iterator llti; for (llti = tracks->begin(); llti != tracks->end(); llti++) { num_recs += llti->size(); } sint16 *sbuf16 = (sint16 *) m_buf; sbuf16[0] = host2garmin16(num_recs); m_ll->put_packet(pid_records, m_buf, 2); for (llti = tracks->begin(); llti != tracks->end(); llti++) { track_t::const_iterator lti; bool first = true; m_buf[8 + 4] = 1; for (lti = llti->begin(); lti != llti->end(); lti++, first = false) { uint32 *buf32 = (uint32 *) m_buf; buf32[0] = host2garmin32(lti->pos.lat); buf32[1] = host2garmin32(lti->pos.lon); // GPS ignores time field, leave it as 0 m_ll->put_packet(pid_trk_data, m_buf, 16); // set new_track element at first point of each segment, but not for other // points in track segment if (first) { m_buf[8 + 4] = 0; } } } sbuf16[0] = host2garmin16(cmnd_transfer_trk); m_ll->put_packet(pid_xfer_cmplt, m_buf, 2);}/////////////////////track_list_t *application_layer::get_track_logs(void) throw (not_possible, timeout){ check_init(); uint8 sz; sint16 *buf16 = (sint16 *) m_buf; buf16[0] = host2garmin16((sint16) cmnd_transfer_trk); 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 track log data"); } if (sz != 2) { throw not_possible("Track log data start of records packet is wrong size"); } sint16 num_recs = garmin2host16(buf16[0]); track_list_t *tracks = new track_list_t(0); for (sint16 i = 0; i < num_recs; i++) { pid = m_ll->get_packet(m_buf, sz); if (pid != pid_trk_data) { delete tracks; throw not_possible("GPS did not send track point data packet"); } if (sz < (8 + 4 + 1)) { delete tracks; throw not_possible("Track point data packet is too small"); } bool new_trk = m_buf[8 + 4]; if (new_trk || i == 0) { tracks->push_back(list<track_point_type>()); } semicircle_type *sp = (semicircle_type *) m_buf; sp->lat = garmin2host32(sp->lat); sp->lon = garmin2host32(sp->lon); track_point_type track_point; track_point.pos = *sp; track_point.new_track = new_trk; uint32 *buf32 = (uint32 *) m_buf; struct tm my_tm; memset(&my_tm, 0, sizeof(struct tm)); my_tm.tm_sec = garmin2host32(buf32[2]); my_tm.tm_year = 90; my_tm.tm_mday = 1; // 1 based counting my_tm.tm_isdst = -1; // unknown track_point.time = mktime(&my_tm); tracks->back().push_back(track_point); } pid = m_ll->get_packet(m_buf, sz); if (pid != pid_xfer_cmplt) { delete tracks; throw not_possible("GPS did not terminate track log data with end of records packet"); } if (garmin2host16(buf16[0]) != cmnd_transfer_trk) { delete tracks; throw not_possible("End of records packet does not match original track log transfer command"); } return tracks;}/////////////////prox_waypt_vec_t *application_layer::get_proximity_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_prx); 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 proximity waypoint data"); } if (sz != 2) { throw not_possible("Proximity waypoint data start of records packet is wrong size"); } sint16 num_recs = garmin2host16(buf16[0]); prox_waypt_vec_t *waypts = new prox_waypt_vec_t(num_recs); for (sint16 i = 0; i < num_recs; i++) { proximity_waypt_type &waypt = (*waypts)[i]; pid = m_ll->get_packet(m_buf, sz); if (pid != pid_prx_wpt_data) { delete waypts; throw not_possible("GPS did not send proximity waypoint data packet"); } if (sz < (6 + 8 + 4 + 40 + 2 + 4)) { delete waypts; throw not_possible("Proximity waypoint data packet is too small"); } uint32 *buf32 = (uint32 *) (m_buf + 6); waypt.waypt.pos.lat = garmin2host32(buf32[0]); waypt.waypt.pos.lon = garmin2host32(buf32[1]); strncpy(ident, (char *) m_buf, 6); waypt.waypt.id = string(ident); strncpy(cmnt, (char *) m_buf + 18, 40); waypt.waypt.comment = string(cmnt); buf32 = (uint32 *) (m_buf + sz - 4); *buf32 = garmin2host32(buf32[0]); float32 *dist = (float32 *) buf32; waypt.dist = *dist; } pid = m_ll->get_packet(m_buf, sz); if (pid != pid_xfer_cmplt) { delete waypts; throw not_possible("GPS did not terminate proximity waypoint data with end of records packet"); } if (garmin2host16(buf16[0]) != cmnd_transfer_prx) { delete waypts; throw not_possible("End of records packet does not match original proximity waypoint transfer command"); } return waypts; }/////////////////////voidapplication_layer::send_proximity_waypoints(prox_waypt_vec_t *prx_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("Proximity waypoint download not supported for this GPS"); } sint16 *buf16 = (sint16 *) m_buf; buf16[0] = host2garmin16(prx_waypts->size()); m_ll->put_packet(pid_records, m_buf, 2); for (unsigned int i = 0; i < prx_waypts->size(); i++) { basic_waypt_type &w = (*prx_waypts)[i].waypt; // clear all fields memset(m_buf, 0, d103_sz + 4); // 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); // copy in proximity distance buf32 = (uint32 *) (m_buf + d103_sz); float32 d = (*prx_waypts)[i].dist; uint32 *t32 = (uint32 *) &d; *buf32 = host2garmin32(*t32); m_ll->put_packet(pid_prx_wpt_data, m_buf, d103_sz + 4); } buf16[0] = host2garmin16(cmnd_transfer_prx); m_ll->put_packet(pid_xfer_cmplt, m_buf, 2);}/////////////////////voidapplication_layer::turn_off_gps(void) throw (not_possible, timeout){ check_init(); sint16 *buf16 = (sint16 *) m_buf; buf16[0] = host2garmin16((sint16) cmnd_turn_off_pwr); m_ll->put_packet(pid_command_data, m_buf, 2); }/////////////////time_t application_layer::get_date_time(void) throw (not_possible, timeout){ check_init(); sint16 *sbuf16 = (sint16 *) m_buf; sbuf16[0] = host2garmin16((sint16) cmnd_transfer_time); 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_date_time_data) { throw not_possible("GPS did not respond with date and time packet"); } if (sz != 8) { throw not_possible("Date and time packet is the wrong size"); } struct tm my_tm; memset(&my_tm, 0, sizeof(struct tm)); my_tm.tm_mon = m_buf[0] - 1; my_tm.tm_mday = m_buf[1]; uint16 *ubuf16 = (uint16 *) m_buf; my_tm.tm_year = garmin2host16(ubuf16[1]) - 1900; my_tm.tm_hour = garmin2host16(sbuf16[2]); my_tm.tm_min = m_buf[6]; my_tm.tm_sec = m_buf[7]; my_tm.tm_isdst = -1; return mktime(&my_tm);}/////////////////////void application_layer::send_date_time(time_t t) throw (bad_time, not_possible, timeout){ check_init(); struct tm my_tm = *gmtime(&t); if (my_tm.tm_year < 90) { throw bad_time(); } m_buf[0] = my_tm.tm_mon + 1; m_buf[1] = my_tm.tm_mday; uint16 *buf16 = (uint16 *) m_buf;; buf16[1] = host2garmin16(my_tm.tm_year + 1900); sint16 *sbuf16 = (sint16 *) buf16; sbuf16[2] = host2garmin16(my_tm.tm_hour); m_buf[6] = my_tm.tm_min; m_buf[8] = my_tm.tm_sec; m_ll->put_packet(pid_date_time_data, m_buf, 8);}//////////////////radian_typeapplication_layer::get_position(void) throw (not_possible, timeout){ check_init(); sint16 *sbuf16 = (sint16 *) m_buf; sbuf16[0] = host2garmin16((sint16) cmnd_transfer_posn); 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_position_data) { throw not_possible("GPS did not respond with position packet"); } if (sz != 16) { throw not_possible("Position packet is the wrong size"); } double64 *dbuf = (double64 *) m_buf; radian_type retval; retval.lat = garmin2host64(dbuf[0]); retval.lon = garmin2host64(dbuf[1]); return retval;}/////////////////////void application_layer::send_position(radian_type pos) throw (not_possible, timeout){ check_init(); double64 *dbuf = (double64 *) m_buf; dbuf[0] = host2garmin64(pos.lat); dbuf[1] = host2garmin64(pos.lon); m_ll->put_packet(pid_position_data, m_buf, 16);}//////////////////} // namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -