parse.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. /*
  2. *
  3. * NMEA library
  4. * URL: http://nmea.sourceforge.net
  5. * Author: Tim (xtimor@gmail.com)
  6. * Licence: http://www.gnu.org/licenses/lgpl.html
  7. * $Id: parse.c 17 2008-03-11 11:56:11Z xtimor $
  8. *
  9. */
  10. /**
  11. * \file parse.h
  12. * \brief Functions of a low level for analysis of
  13. * packages of NMEA stream.
  14. *
  15. * \code
  16. * ...
  17. * ptype = nmea_pack_type(
  18. * (const char *)parser->buffer + nparsed + 1,
  19. * parser->buff_use - nparsed - 1);
  20. *
  21. * if(0 == (node = malloc(sizeof(nmeaParserNODE))))
  22. * goto mem_fail;
  23. *
  24. * node->pack = 0;
  25. *
  26. * switch(ptype)
  27. * {
  28. * case GPGGA:
  29. * if(0 == (node->pack = malloc(sizeof(nmeaGPGGA))))
  30. * goto mem_fail;
  31. * node->packType = GPGGA;
  32. * if(!nmea_parse_GPGGA(
  33. * (const char *)parser->buffer + nparsed,
  34. * sen_sz, (nmeaGPGGA *)node->pack))
  35. * {
  36. * free(node);
  37. * node = 0;
  38. * }
  39. * break;
  40. * case GPGSA:
  41. * if(0 == (node->pack = malloc(sizeof(nmeaGPGSA))))
  42. * goto mem_fail;
  43. * node->packType = GPGSA;
  44. * if(!nmea_parse_GPGSA(
  45. * (const char *)parser->buffer + nparsed,
  46. * sen_sz, (nmeaGPGSA *)node->pack))
  47. * {
  48. * free(node);
  49. * node = 0;
  50. * }
  51. * break;
  52. * ...
  53. * \endcode
  54. */
  55. #include "nmea/tok.h"
  56. #include "nmea/parse.h"
  57. #include "nmea/context.h"
  58. #include "nmea/gmath.h"
  59. #include "nmea/units.h"
  60. #include <string.h>
  61. #include <stdio.h>
  62. int _nmea_parse_time(const char *buff, int buff_sz, nmeaTIME *res)
  63. {
  64. int success = 0;
  65. switch(buff_sz)
  66. {
  67. case sizeof("hhmmss") - 1:
  68. success = (3 == nmea_scanf(buff, buff_sz,
  69. "%2d%2d%2d", &(res->hour), &(res->min), &(res->sec)
  70. ));
  71. break;
  72. case sizeof("hhmmss.s") - 1:
  73. case sizeof("hhmmss.ss") - 1:
  74. case sizeof("hhmmss.sss") - 1:
  75. success = (4 == nmea_scanf(buff, buff_sz,
  76. "%2d%2d%2d.%d", &(res->hour), &(res->min), &(res->sec), &(res->hsec)
  77. ));
  78. break;
  79. default:
  80. nmea_error("Parse of time error (format error)!");
  81. success = 0;
  82. break;
  83. }
  84. return (success?0:-1);
  85. }
  86. /**
  87. * \brief Define packet type by header (nmeaPACKTYPE).
  88. * @param buff a constant character pointer of packet buffer.
  89. * @param buff_sz buffer size.
  90. * @return The defined packet type
  91. * @see nmeaPACKTYPE
  92. */
  93. int nmea_pack_type(const char *buff, int buff_sz)
  94. {
  95. static const char *pheads[] = {
  96. "GPGGA",
  97. "GPGSA",
  98. "GPGSV",
  99. "GPRMC",
  100. "GPVTG",
  101. "GNGGA",
  102. "GNGSA",
  103. "BDGSV",
  104. "GNRMC"
  105. };
  106. NMEA_ASSERT(buff);
  107. if(buff_sz < 5)
  108. return GPNON;
  109. else if(0 == memcmp(buff, pheads[0], 5))
  110. return GPGGA;
  111. else if(0 == memcmp(buff, pheads[1], 5))
  112. return GPGSA;
  113. else if(0 == memcmp(buff, pheads[2], 5))
  114. return GPGSV;
  115. else if(0 == memcmp(buff, pheads[3], 5))
  116. return GPRMC;
  117. else if(0 == memcmp(buff, pheads[4], 5))
  118. return GPVTG;
  119. else if(0 == memcmp(buff, pheads[5], 5))
  120. return GNGGA;
  121. else if(0 == memcmp(buff, pheads[6], 5))
  122. return GNGSA;
  123. else if(0 == memcmp(buff, pheads[7], 5))
  124. return BDGSV;
  125. else if(0 == memcmp(buff, pheads[8], 5))
  126. return GNRMC;
  127. return GPNON;
  128. }
  129. /**
  130. * \brief Find tail of packet ("\r\n") in buffer and check control sum (CRC).
  131. * @param buff a constant character pointer of packets buffer.
  132. * @param buff_sz buffer size.
  133. * @param res_crc a integer pointer for return CRC of packet (must be defined).
  134. * @return Number of bytes to packet tail.
  135. */
  136. int nmea_find_tail(const char *buff, int buff_sz, int *res_crc)
  137. {
  138. static const int tail_sz = 3 /* *[CRC] */ + 1 /* \n */;
  139. const char *end_buff = buff + buff_sz;
  140. int nread = 0;
  141. int crc = 0;
  142. NMEA_ASSERT(buff && res_crc);
  143. *res_crc = -1;
  144. for(;buff < end_buff; ++buff, ++nread)
  145. {
  146. if(('$' == *buff) && nread)
  147. {
  148. buff = 0;
  149. break;
  150. }
  151. else if('*' == *buff)
  152. {
  153. if(buff + tail_sz <= end_buff && ('\n' == buff[3] || ('\r' == buff[3] && '\n' == buff[4])))
  154. {
  155. *res_crc = nmea_atoi(buff + 1, 2, 16);
  156. nread = buff_sz - (int)(end_buff - (buff + tail_sz));
  157. if(*res_crc != crc)
  158. {
  159. *res_crc = -1;
  160. buff = 0;
  161. }
  162. }
  163. break;
  164. }
  165. else if(nread)
  166. crc ^= (int)*buff;
  167. }
  168. if(*res_crc < 0 && buff)
  169. nread = 0;
  170. return nread;
  171. }
  172. /**
  173. * \brief Parse GGA packet from buffer.
  174. * @param buff a constant character pointer of packet buffer.
  175. * @param buff_sz buffer size.
  176. * @param pack a pointer of packet which will filled by function.
  177. * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
  178. */
  179. int nmea_parse_GPGGA(const char *buff, int buff_sz, nmeaGPGGA *pack)
  180. {
  181. char time_buff[NMEA_TIMEPARSE_BUF];
  182. NMEA_ASSERT(buff && pack);
  183. memset(pack, 0, sizeof(nmeaGPGGA));
  184. nmea_trace_buff(buff, buff_sz);
  185. if(14 != nmea_scanf(buff, buff_sz,
  186. "$GPGGA,%s,%f,%C,%f,%C,%d,%d,%f,%f,%C,%f,%C,%f,%d*",
  187. &(time_buff[0]),
  188. &(pack->lat), &(pack->ns), &(pack->lon), &(pack->ew),
  189. &(pack->sig), &(pack->satinuse), &(pack->HDOP), &(pack->elv), &(pack->elv_units),
  190. &(pack->diff), &(pack->diff_units), &(pack->dgps_age), &(pack->dgps_sid)))
  191. {
  192. nmea_error("GPGGA parse error!");
  193. return 0;
  194. }
  195. if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc)))
  196. {
  197. nmea_error("GPGGA time parse error!");
  198. return 0;
  199. }
  200. return 1;
  201. }
  202. int nmea_parse_GNGGA(const char *buff, int buff_sz, nmeaGPGGA *pack)
  203. {
  204. char time_buff[NMEA_TIMEPARSE_BUF];
  205. NMEA_ASSERT(buff && pack);
  206. memset(pack, 0, sizeof(nmeaGPGGA));
  207. nmea_trace_buff(buff, buff_sz);
  208. if(14 != nmea_scanf(buff, buff_sz,
  209. "$GNGGA,%s,%f,%C,%f,%C,%d,%d,%f,%f,%C,%f,%C,%f,%d*",
  210. &(time_buff[0]),
  211. &(pack->lat), &(pack->ns), &(pack->lon), &(pack->ew),
  212. &(pack->sig), &(pack->satinuse), &(pack->HDOP), &(pack->elv), &(pack->elv_units),
  213. &(pack->diff), &(pack->diff_units), &(pack->dgps_age), &(pack->dgps_sid)))
  214. {
  215. nmea_error("GNGGA parse error!");
  216. return 0;
  217. }
  218. if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc)))
  219. {
  220. nmea_error("GNGGA time parse error!");
  221. return 0;
  222. }
  223. return 1;
  224. }
  225. /**
  226. * \brief Parse GSA packet from buffer.
  227. * @param buff a constant character pointer of packet buffer.
  228. * @param buff_sz buffer size.
  229. * @param pack a pointer of packet which will filled by function.
  230. * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
  231. */
  232. int nmea_parse_GPGSA(const char *buff, int buff_sz, nmeaGPGSA *pack)
  233. {
  234. NMEA_ASSERT(buff && pack);
  235. memset(pack, 0, sizeof(nmeaGPGSA));
  236. nmea_trace_buff(buff, buff_sz);
  237. if(17 != nmea_scanf(buff, buff_sz,
  238. "$GPGSA,%C,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%f,%f,%f*",
  239. &(pack->fix_mode), &(pack->fix_type),
  240. &(pack->sat_prn[0]), &(pack->sat_prn[1]), &(pack->sat_prn[2]), &(pack->sat_prn[3]), &(pack->sat_prn[4]), &(pack->sat_prn[5]),
  241. &(pack->sat_prn[6]), &(pack->sat_prn[7]), &(pack->sat_prn[8]), &(pack->sat_prn[9]), &(pack->sat_prn[10]), &(pack->sat_prn[11]),
  242. &(pack->PDOP), &(pack->HDOP), &(pack->VDOP)))
  243. {
  244. nmea_error("GPGSA parse error!");
  245. return 0;
  246. }
  247. return 1;
  248. }
  249. int nmea_parse_GNGSA(const char *buff, int buff_sz, nmeaGPGSA *pack)
  250. {
  251. NMEA_ASSERT(buff && pack);
  252. memset(pack, 0, sizeof(nmeaGPGSA));
  253. nmea_trace_buff(buff, buff_sz);
  254. int scanf_res = nmea_scanf(buff, buff_sz,
  255. "$GNGSA,%C,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%f,%f,%f,%d*%*X",
  256. &(pack->fix_mode), &(pack->fix_type),
  257. &(pack->sat_prn[0]), &(pack->sat_prn[1]), &(pack->sat_prn[2]), &(pack->sat_prn[3]), &(pack->sat_prn[4]), &(pack->sat_prn[5]),
  258. &(pack->sat_prn[6]), &(pack->sat_prn[7]), &(pack->sat_prn[8]), &(pack->sat_prn[9]), &(pack->sat_prn[10]), &(pack->sat_prn[11]),
  259. &(pack->PDOP), &(pack->HDOP), &(pack->VDOP),
  260. &(pack->selectedSatellites));
  261. //printf("\n解析到:nmea_parse_GNGSA:%d-%d\n",scanf_res,buff_sz);
  262. //printf("\n解析到:nmea_parse_GNGSA:%C\n",pack->fix_mode);
  263. if(19 != scanf_res)
  264. {
  265. //printf("\nGNGSA parse error\n");
  266. nmea_error("GPGSA parse error!");
  267. return 0;
  268. }
  269. return 1;
  270. }
  271. /**
  272. * \brief Parse GSV packet from buffer.
  273. * @param buff a constant character pointer of packet buffer.
  274. * @param buff_sz buffer size.
  275. * @param pack a pointer of packet which will filled by function.
  276. * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
  277. */
  278. //$GPGSV,3,1,09,10,46,320,39,12,20,121,26,15,28,069,22,18,39,201,26,0*64
  279. //$GPGSV,3,2,09,23,80,028,,24,56,053,,25,10,161,,32,25,274,28,0*60
  280. //$GPGSV,3,3,09,194,24,133,,0*67
  281. int nmea_parse_GPGSV(const char *buff, int buff_sz, nmeaGPGSV *pack)
  282. {
  283. int nsen, nsat;
  284. NMEA_ASSERT(buff && pack);
  285. memset(pack, 0, sizeof(nmeaGPGSV));
  286. nmea_trace_buff(buff, buff_sz);
  287. nsen = nmea_scanf(buff, buff_sz,
  288. "$GPGSV,%d,%d,%d,"
  289. "%d,%d,%d,%d,"
  290. "%d,%d,%d,%d,"
  291. "%d,%d,%d,%d,"
  292. "%d,%d,%d,%d*",
  293. &(pack->pack_count), &(pack->pack_index), &(pack->sat_count),
  294. &(pack->sat_data[0].id), &(pack->sat_data[0].elv), &(pack->sat_data[0].azimuth), &(pack->sat_data[0].sig),
  295. &(pack->sat_data[1].id), &(pack->sat_data[1].elv), &(pack->sat_data[1].azimuth), &(pack->sat_data[1].sig),
  296. &(pack->sat_data[2].id), &(pack->sat_data[2].elv), &(pack->sat_data[2].azimuth), &(pack->sat_data[2].sig),
  297. &(pack->sat_data[3].id), &(pack->sat_data[3].elv), &(pack->sat_data[3].azimuth), &(pack->sat_data[3].sig));
  298. nsat = (pack->pack_index - 1) * NMEA_SATINPACK;
  299. nsat = (nsat + NMEA_SATINPACK > pack->sat_count)?pack->sat_count - nsat:NMEA_SATINPACK;
  300. nsat = nsat * 4 + 3 /* first three sentence`s */;
  301. //printf("nmea_parse_GPGSV:%d-%d",nsen,nsat);
  302. if(nsen < nsat || nsen > (NMEA_SATINPACK * 4 + 3))
  303. {
  304. //printf("nmea_parse_GPGSV ERR:%d-%d",nsen,nsat);
  305. nmea_error("GPGSV parse error!");
  306. return 0;
  307. }
  308. return 1;
  309. }
  310. //$BDGSV,3,1,12,06,67,235,24,09,54,229,27,16,75,242,17,20,17,298,33,0*74
  311. //$BDGSV,3,2,12,25,30,052,21,27,09,205,23,29,09,306,31,30,19,253,23,0*77
  312. //$BDGSV,3,3,12,32,62,345,22,37,28,182,15,39,81,277,30,41,41,083,26,0*7C
  313. int nmea_parse_BDGSV(const char *buff, int buff_sz, nmeaGPGSV *pack)
  314. {
  315. int nsen, nsat;
  316. NMEA_ASSERT(buff && pack);
  317. memset(pack, 0, sizeof(nmeaGPGSV));
  318. nmea_trace_buff(buff, buff_sz);
  319. nsen = nmea_scanf(buff, buff_sz,
  320. "$BDGSV,%d,%d,%d,"
  321. "%d,%d,%d,%d,"
  322. "%d,%d,%d,%d,"
  323. "%d,%d,%d,%d,"
  324. "%d,%d,%d,%d*",
  325. &(pack->pack_count), &(pack->pack_index), &(pack->sat_count),
  326. &(pack->sat_data[0].id), &(pack->sat_data[0].elv), &(pack->sat_data[0].azimuth), &(pack->sat_data[0].sig),
  327. &(pack->sat_data[1].id), &(pack->sat_data[1].elv), &(pack->sat_data[1].azimuth), &(pack->sat_data[1].sig),
  328. &(pack->sat_data[2].id), &(pack->sat_data[2].elv), &(pack->sat_data[2].azimuth), &(pack->sat_data[2].sig),
  329. &(pack->sat_data[3].id), &(pack->sat_data[3].elv), &(pack->sat_data[3].azimuth), &(pack->sat_data[3].sig));
  330. nsat = (pack->pack_index - 1) * NMEA_SATINPACK;
  331. nsat = (nsat + NMEA_SATINPACK > pack->sat_count)?pack->sat_count - nsat:NMEA_SATINPACK;
  332. nsat = nsat * 4 + 3 /* first three sentence`s */;
  333. if(nsen < nsat || nsen > (NMEA_SATINPACK * 4 + 3))
  334. {
  335. //printf("BDGSV parse error!\n");
  336. nmea_error("GPGSV parse error!");
  337. return 0;
  338. }
  339. return 1;
  340. }
  341. /**
  342. * \brief Parse RMC packet from buffer.
  343. * @param buff a constant character pointer of packet buffer.
  344. * @param buff_sz buffer size.
  345. * @param pack a pointer of packet which will filled by function.
  346. * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
  347. */
  348. int nmea_parse_GPRMC(const char *buff, int buff_sz, nmeaGPRMC *pack)
  349. {
  350. int nsen;
  351. char time_buff[NMEA_TIMEPARSE_BUF];
  352. NMEA_ASSERT(buff && pack);
  353. memset(pack, 0, sizeof(nmeaGPRMC));
  354. nmea_trace_buff(buff, buff_sz);
  355. nsen = nmea_scanf(buff, buff_sz,
  356. "$GPRMC,%s,%C,%f,%C,%f,%C,%f,%f,%2d%2d%2d,%f,%C,%C*",
  357. &(time_buff[0]),
  358. &(pack->status), &(pack->lat), &(pack->ns), &(pack->lon), &(pack->ew),
  359. &(pack->speed), &(pack->direction),
  360. &(pack->utc.day), &(pack->utc.mon), &(pack->utc.year),
  361. &(pack->declination), &(pack->declin_ew), &(pack->mode));
  362. if(nsen != 13 && nsen != 14)
  363. {
  364. nmea_error("GPRMC parse error!");
  365. return 0;
  366. }
  367. if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc)))
  368. {
  369. nmea_error("GPRMC time parse error!");
  370. return 0;
  371. }
  372. if(pack->utc.year < 90)
  373. pack->utc.year += 100;
  374. pack->utc.mon -= 1;
  375. return 1;
  376. }
  377. //$GPRMC,014600.00,A,2237.496474,N,11356.089515,E,0.0,225.5,310518,2.3,W,A*23
  378. //$GNRMC,032950.000,A,3448.60391,N,11339.61318,E,0.00,165.77,050923,,A,V*0A
  379. //
  380. int nmea_parse_GNRMC(const char *buff, int buff_sz, nmeaGPRMC *pack)
  381. {
  382. int nsen;
  383. char time_buff[NMEA_TIMEPARSE_BUF];
  384. NMEA_ASSERT(buff && pack);
  385. memset(pack, 0, sizeof(nmeaGPRMC));
  386. nmea_trace_buff(buff, buff_sz);
  387. nsen = nmea_scanf(buff, buff_sz,
  388. "$GNRMC,%s,%C,%f,%C,%f,%C,%f,%f,%2d%2d%2d,%f,%C,%C",
  389. &(time_buff[0]),
  390. &(pack->status), &(pack->lat), &(pack->ns), &(pack->lon), &(pack->ew),
  391. &(pack->speed), &(pack->direction),
  392. &(pack->utc.day), &(pack->utc.mon), &(pack->utc.year),
  393. &(pack->declination), &(pack->declin_ew), &(pack->mode));
  394. if(nsen != 13 && nsen != 14)
  395. {
  396. //printf("GnRMC parse error!%d-%d",nsen,buff_sz);
  397. nmea_error("GPRMC parse error!");
  398. return 0;
  399. }
  400. if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc)))
  401. {
  402. nmea_error("GPRMC time parse error!");
  403. return 0;
  404. }
  405. if(pack->utc.year < 90)
  406. pack->utc.year += 100;
  407. pack->utc.mon -= 1;
  408. return 1;
  409. }
  410. /**
  411. * \brief Parse VTG packet from buffer.
  412. * @param buff a constant character pointer of packet buffer.
  413. * @param buff_sz buffer size.
  414. * @param pack a pointer of packet which will filled by function.
  415. * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
  416. */
  417. int nmea_parse_GPVTG(const char *buff, int buff_sz, nmeaGPVTG *pack)
  418. {
  419. NMEA_ASSERT(buff && pack);
  420. memset(pack, 0, sizeof(nmeaGPVTG));
  421. nmea_trace_buff(buff, buff_sz);
  422. if(8 != nmea_scanf(buff, buff_sz,
  423. "$GPVTG,%f,%C,%f,%C,%f,%C,%f,%C*",
  424. &(pack->dir), &(pack->dir_t),
  425. &(pack->dec), &(pack->dec_m),
  426. &(pack->spn), &(pack->spn_n),
  427. &(pack->spk), &(pack->spk_k)))
  428. {
  429. nmea_error("GPVTG parse error!");
  430. return 0;
  431. }
  432. if( pack->dir_t != 'T' ||
  433. pack->dec_m != 'M' ||
  434. pack->spn_n != 'N' ||
  435. pack->spk_k != 'K')
  436. {
  437. nmea_error("GPVTG parse error (format error)!");
  438. return 0;
  439. }
  440. return 1;
  441. }
  442. /**
  443. * \brief Fill nmeaINFO structure by GGA packet data.
  444. * @param pack a pointer of packet structure.
  445. * @param info a pointer of summary information structure.
  446. */
  447. void nmea_GPGGA2info(nmeaGPGGA *pack, nmeaINFO *info)
  448. {
  449. NMEA_ASSERT(pack && info);
  450. info->utc.hour = pack->utc.hour;
  451. info->utc.min = pack->utc.min;
  452. info->utc.sec = pack->utc.sec;
  453. info->utc.hsec = pack->utc.hsec;
  454. info->sig = pack->sig;
  455. info->satinfo.inuse = pack->satinuse;
  456. info->HDOP = pack->HDOP;
  457. info->elv = pack->elv;
  458. info->lat = ((pack->ns == 'N')?pack->lat:-(pack->lat));
  459. info->lon = ((pack->ew == 'E')?pack->lon:-(pack->lon));
  460. info->smask |= GPGGA;
  461. }
  462. //$GNGGA,020209.000,3448.60499,N,11339.61056,E,1,20,0.7,134.7,M,-18.9,M,,*66
  463. void nmea_GNGGA2info(nmeaGPGGA *pack, nmeaINFO *info)
  464. {
  465. NMEA_ASSERT(pack && info);
  466. info->utc.hour = pack->utc.hour;
  467. info->utc.min = pack->utc.min;
  468. info->utc.sec = pack->utc.sec;
  469. info->utc.hsec = pack->utc.hsec;
  470. info->sig = pack->sig;
  471. info->satinfo.inuse = pack->satinuse;
  472. info->HDOP = pack->HDOP;
  473. info->elv = pack->elv;
  474. info->lat = ((pack->ns == 'N')?pack->lat:-(pack->lat));
  475. info->lon = ((pack->ew == 'E')?pack->lon:-(pack->lon));
  476. info->smask |= GNGGA;
  477. }
  478. /**
  479. * \brief Fill nmeaINFO structure by GSA packet data.
  480. * @param pack a pointer of packet structure.
  481. * @param info a pointer of summary information structure.
  482. */
  483. void nmea_GPGSA2info(nmeaGPGSA *pack, nmeaINFO *info)
  484. {
  485. int i, j, nuse = 0;
  486. NMEA_ASSERT(pack && info);
  487. info->fix = pack->fix_type;
  488. info->PDOP = pack->PDOP;
  489. info->HDOP = pack->HDOP;
  490. info->VDOP = pack->VDOP;
  491. for(i = 0; i < NMEA_MAXSAT; ++i)
  492. {
  493. for(j = 0; j < info->satinfo.inview; ++j)
  494. {
  495. if(pack->sat_prn[i] && pack->sat_prn[i] == info->satinfo.sat[j].id)
  496. {
  497. info->satinfo.sat[j].in_use = 1;
  498. nuse++;
  499. }
  500. }
  501. }
  502. info->satinfo.inuse = nuse;
  503. info->smask |= GPGSA;
  504. }
  505. void nmea_GNGSA2info(nmeaGPGSA *pack, nmeaINFO *info)
  506. {
  507. int i, j, nuse = 0;
  508. NMEA_ASSERT(pack && info);
  509. info->fix = pack->fix_type;
  510. info->PDOP = pack->PDOP;
  511. info->HDOP = pack->HDOP;
  512. info->VDOP = pack->VDOP;
  513. for(i = 0; i < NMEA_MAXSAT; ++i)
  514. {
  515. for(j = 0; j < info->satinfo.inview; ++j)
  516. {
  517. if(pack->sat_prn[i] && pack->sat_prn[i] == info->satinfo.sat[j].id)
  518. {
  519. info->satinfo.sat[j].in_use = 1;
  520. nuse++;
  521. }
  522. }
  523. }
  524. info->satinfo.inuse = nuse;
  525. info->smask |= GNGSA;
  526. }
  527. /**
  528. * \brief Fill nmeaINFO structure by GSV packet data.
  529. * @param pack a pointer of packet structure.
  530. * @param info a pointer of summary information structure.
  531. */
  532. void nmea_GPGSV2info(nmeaGPGSV *pack, nmeaINFO *info)
  533. {
  534. int isat, isi, nsat;
  535. NMEA_ASSERT(pack && info);
  536. if(pack->pack_index > pack->pack_count ||
  537. pack->pack_index * NMEA_SATINPACK > NMEA_MAXSAT)
  538. return;
  539. if(pack->pack_index < 1)
  540. pack->pack_index = 1;
  541. gps_count = pack->sat_count;
  542. info->satinfo.inview = gps_count + bd_count ;
  543. //printf("GPS卫星数量:%d\n",pack->sat_count);
  544. nsat = (pack->pack_index - 1) * NMEA_SATINPACK;
  545. nsat = (nsat + NMEA_SATINPACK > pack->sat_count)?pack->sat_count - nsat:NMEA_SATINPACK;
  546. for(isat = 0; isat < nsat; ++isat)
  547. {
  548. isi = (pack->pack_index - 1) * NMEA_SATINPACK + isat;
  549. info->satinfo.sat[isi].id = pack->sat_data[isat].id;
  550. info->satinfo.sat[isi].elv = pack->sat_data[isat].elv;
  551. info->satinfo.sat[isi].azimuth = pack->sat_data[isat].azimuth;
  552. info->satinfo.sat[isi].sig = pack->sat_data[isat].sig;
  553. }
  554. info->smask |= GPGSV;
  555. }
  556. void nmea_BDGSV2info(nmeaGPGSV *pack, nmeaINFO *info)
  557. {
  558. int isat, isi, nsat;
  559. NMEA_ASSERT(pack && info);
  560. bd_count = pack->sat_count;
  561. info->satinfo.inview = gps_count + bd_count ;
  562. //printf("北斗卫星数量:%d\n",pack->sat_count);
  563. if(pack->pack_index > pack->pack_count ||
  564. pack->pack_index * NMEA_SATINPACK > NMEA_MAXSAT)
  565. return;
  566. if(pack->pack_index < 1)
  567. pack->pack_index = 1;
  568. nsat = (pack->pack_index - 1) * NMEA_SATINPACK;
  569. nsat = (nsat + NMEA_SATINPACK > pack->sat_count)?pack->sat_count - nsat:NMEA_SATINPACK;
  570. for(isat = 0; isat < nsat; ++isat)
  571. {
  572. isi = (pack->pack_index - 1) * NMEA_SATINPACK + isat;
  573. info->satinfo.sat[isi].id = pack->sat_data[isat].id;
  574. info->satinfo.sat[isi].elv = pack->sat_data[isat].elv;
  575. info->satinfo.sat[isi].azimuth = pack->sat_data[isat].azimuth;
  576. info->satinfo.sat[isi].sig = pack->sat_data[isat].sig;
  577. }
  578. info->satinfo.state = 'B';
  579. info->smask |= GPGSV;
  580. }
  581. /**
  582. * \brief Fill nmeaINFO structure by RMC packet data.
  583. * @param pack a pointer of packet structure.
  584. * @param info a pointer of summary information structure.
  585. */
  586. void nmea_GPRMC2info(nmeaGPRMC *pack, nmeaINFO *info)
  587. {
  588. NMEA_ASSERT(pack && info);
  589. if('A' == pack->status)
  590. {
  591. if(NMEA_SIG_BAD == info->sig)
  592. info->sig = NMEA_SIG_MID;
  593. if(NMEA_FIX_BAD == info->fix)
  594. info->fix = NMEA_FIX_2D;
  595. }
  596. else if('V' == pack->status)
  597. {
  598. info->sig = NMEA_SIG_BAD;
  599. info->fix = NMEA_FIX_BAD;
  600. }
  601. info->utc = pack->utc;
  602. info->lat = ((pack->ns == 'N')?pack->lat:-(pack->lat));
  603. info->lon = ((pack->ew == 'E')?pack->lon:-(pack->lon));
  604. info->speed = pack->speed * NMEA_TUD_KNOTS;
  605. info->direction = pack->direction;
  606. info->smask |= GPRMC;
  607. }
  608. void nmea_GNRMC2info(nmeaGPRMC *pack, nmeaINFO *info)
  609. {
  610. NMEA_ASSERT(pack && info);
  611. if('A' == pack->status)
  612. {
  613. if(NMEA_SIG_BAD == info->sig)
  614. info->sig = NMEA_SIG_MID;
  615. if(NMEA_FIX_BAD == info->fix)
  616. info->fix = NMEA_FIX_2D;
  617. }
  618. else if('V' == pack->status)
  619. {
  620. info->sig = NMEA_SIG_BAD;
  621. info->fix = NMEA_FIX_BAD;
  622. }
  623. info->utc = pack->utc;
  624. info->lat = ((pack->ns == 'N')?pack->lat:-(pack->lat));
  625. info->lon = ((pack->ew == 'E')?pack->lon:-(pack->lon));
  626. info->speed = pack->speed * NMEA_TUD_KNOTS;
  627. info->direction = pack->direction;
  628. info->smask |= GPRMC;
  629. }
  630. /**
  631. * \brief Fill nmeaINFO structure by VTG packet data.
  632. * @param pack a pointer of packet structure.
  633. * @param info a pointer of summary information structure.
  634. */
  635. void nmea_GPVTG2info(nmeaGPVTG *pack, nmeaINFO *info)
  636. {
  637. NMEA_ASSERT(pack && info);
  638. info->direction = pack->dir;
  639. info->declination = pack->dec;
  640. info->speed = pack->spk;
  641. info->smask |= GPVTG;
  642. }