drivers.c 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793
  1. /*
  2. * This file is Copyright 2010 by the GPSD project
  3. * SPDX-License-Identifier: BSD-2-clause
  4. */
  5. #include "../include/gpsd_config.h" /* must be before all includes */
  6. #include <assert.h>
  7. #include <ctype.h>
  8. #include <stdarg.h>
  9. #include <stdbool.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <unistd.h>
  14. #include "../include/bits.h" // for getbeu16(), to extract big-endian words
  15. #include "../include/compiler.h" // for FALLTHROUGH
  16. #include "../include/gpsd.h"
  17. #include "../include/strfuncs.h"
  18. ssize_t generic_get(struct gps_device_t *session)
  19. {
  20. return packet_get(session->gpsdata.gps_fd, &session->lexer);
  21. }
  22. // This handles only bad, comment, and maybe NMEA packets.
  23. gps_mask_t generic_parse_input(struct gps_device_t *session)
  24. {
  25. if (BAD_PACKET == session->lexer.type ||
  26. COMMENT_PACKET == session->lexer.type) {
  27. // ignore bad packets and comment packets
  28. return 0;
  29. }
  30. if (NMEA_PACKET == session->lexer.type) {
  31. const struct gps_type_t **dp;
  32. gps_mask_t st = 0;
  33. char *sentence = (char *)session->lexer.outbuffer;
  34. if ('\n' != sentence[strlen(sentence)-1]) {
  35. GPSD_LOG(LOG_IO, &session->context->errout,
  36. "<= GPS: %s\n", sentence);
  37. } else {
  38. GPSD_LOG(LOG_IO, &session->context->errout,
  39. "<= GPS: %s", sentence);
  40. }
  41. if (0 == (st=nmea_parse(sentence, session))) {
  42. GPSD_LOG(LOG_WARN, &session->context->errout,
  43. "unknown sentence: \"%s\"\n", sentence);
  44. }
  45. for (dp = gpsd_drivers; *dp; dp++) {
  46. char *trigger = (*dp)->trigger;
  47. if (trigger!=NULL && str_starts_with(sentence, trigger)) {
  48. GPSD_LOG(LOG_PROG, &session->context->errout,
  49. "found trigger string %s.\n", trigger);
  50. if (*dp != session->device_type) {
  51. (void)gpsd_switch_driver(session, (*dp)->type_name);
  52. if (session->device_type != NULL
  53. && session->device_type->event_hook != NULL)
  54. session->device_type->event_hook(session,
  55. event_triggermatch);
  56. st |= DEVICEID_SET;
  57. }
  58. }
  59. }
  60. return st;
  61. }
  62. GPSD_LOG(LOG_SHOUT, &session->context->errout,
  63. "packet type %d fell through (should never happen): %s.\n",
  64. session->lexer.type, gpsd_prettydump(session));
  65. return 0;
  66. }
  67. /**************************************************************************
  68. *
  69. * Generic driver -- make no assumptions about the device type
  70. *
  71. **************************************************************************/
  72. /* *INDENT-OFF* */
  73. const struct gps_type_t driver_unknown = {
  74. .type_name = "Unknown", /* full name of type */
  75. .packet_type = COMMENT_PACKET, /* associated lexer packet type */
  76. .flags = DRIVER_NOFLAGS, /* no flags set */
  77. .trigger = NULL, /* it's the default */
  78. .channels = 12, /* consumer-grade GPS */
  79. .probe_detect = NULL, /* no probe */
  80. .get_packet = generic_get, /* use generic packet getter */
  81. .parse_packet = generic_parse_input, /* how to interpret a packet */
  82. .rtcm_writer = NULL, /* write RTCM data straight */
  83. .init_query = NULL, /* non-perturbing initial query */
  84. .event_hook = NULL, /* lifetime event handler */
  85. .speed_switcher = NULL, /* no speed switcher */
  86. .mode_switcher = NULL, /* no mode switcher */
  87. .rate_switcher = NULL, /* no sample-rate switcher */
  88. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  89. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  90. .control_send = NULL, /* how to send control strings */
  91. .time_offset = NULL, /* no method for NTP fudge factor */
  92. };
  93. /* *INDENT-ON* */
  94. /**************************************************************************
  95. *
  96. * NMEA 0183
  97. *
  98. * This is separate from the 'unknown' driver because we don't want to
  99. * ship NMEA subtype probe strings to a device until we've seen at
  100. * least one NMEA packet. This avoids spamming devices that might
  101. * actually be USB modems or other things in USB device class FF that
  102. * just happen to have one of 'our' adaptor chips in front of them.
  103. *
  104. **************************************************************************/
  105. static void nmea_event_hook(struct gps_device_t *session, event_t event)
  106. {
  107. if (session->context->readonly)
  108. return;
  109. /*
  110. * This is where we try to tickle NMEA devices into revealing their
  111. * inner natures.
  112. */
  113. if (event == event_configure) {
  114. /*
  115. * The reason for splitting these probes up by packet sequence
  116. * number, interleaving them with the first few packet receives,
  117. * is because many generic-NMEA devices get confused if you send
  118. * too much at them in one go.
  119. *
  120. * A fast response to an early probe will change drivers so the
  121. * later ones won't be sent at all. Thus, for best overall
  122. * performance, order these to probe for the most popular types
  123. * soonest.
  124. *
  125. * Note: don't make the trigger strings identical to the probe,
  126. * because some NMEA devices (notably SiRFs) will just echo
  127. * unknown strings right back at you. A useful dodge is to append
  128. * a comma to the trigger, because that won't be in the response
  129. * unless there is actual following data.
  130. */
  131. switch (session->lexer.counter) {
  132. case 0:
  133. /* probe for Garmin serial GPS -- expect $PGRMC followed by data */
  134. GPSD_LOG(LOG_PROG, &session->context->errout,
  135. "=> Probing for Garmin NMEA\n");
  136. (void)nmea_send(session, "$PGRMCE");
  137. break;
  138. #ifdef SIRF_ENABLE
  139. case 1:
  140. /*
  141. * We used to try to probe for SiRF by issuing
  142. * "$PSRF105,1" and expecting "$Ack Input105.". But it
  143. * turns out this only works for SiRF-IIs; SiRF-I and
  144. * SiRF-III don't respond. Sadly, the MID132 binary
  145. * request for firmware version is ignored in NMEA mode.
  146. * Thus the only reliable probe is to try to flip the SiRF
  147. * into binary mode, cluing in the library to revert it on
  148. * close.
  149. *
  150. * SiRFs dominate the consumer-grade GPS-mouse market, so
  151. * we used to put this test first. Unfortunately this
  152. * causes problems for gpsctl, as it cannot select the
  153. * NMEA driver without switching the device back to binary
  154. * mode! Fix this if we ever find a nondisruptive probe
  155. * string.
  156. */
  157. GPSD_LOG(LOG_PROG, &session->context->errout,
  158. "=> Probing for SiRF\n");
  159. (void)nmea_send(session,
  160. "$PSRF100,0,%d,%d,%d,0",
  161. session->gpsdata.dev.baudrate,
  162. 9 - session->gpsdata.dev.stopbits,
  163. session->gpsdata.dev.stopbits);
  164. break;
  165. #endif /* SIRF_ENABLE */
  166. case 2:
  167. /* probe for the FV-18 -- expect $PFEC,GPint followed by data */
  168. GPSD_LOG(LOG_PROG, &session->context->errout,
  169. "=> Probing for FV-18\n");
  170. (void)nmea_send(session, "$PFEC,GPint");
  171. break;
  172. case 3:
  173. /* probe for the Trimble Copernicus */
  174. GPSD_LOG(LOG_PROG, &session->context->errout,
  175. "=> Probing for Trimble Copernicus\n");
  176. (void)nmea_send(session, "$PTNLSNM,0139,01");
  177. break;
  178. #ifdef EVERMORE_ENABLE
  179. case 4:
  180. GPSD_LOG(LOG_PROG, &session->context->errout,
  181. "=> Probing for Evermore\n");
  182. // FIXME: not passive compatible
  183. /* Enable checksum and GGA(1s), GLL(0s), GSA(1s), GSV(1s),
  184. * RMC(1s), VTG(0s), PEMT101(0s)
  185. * EverMore will reply with: \x10\x02\x04\x38\x8E\xC6\x10\x03 */
  186. (void)gpsd_write(session,
  187. "\x10\x02\x12\x8E\x7F\x01\x01\x00\x01\x01\x01"
  188. "\x00\x00\x00\x00\x00\x00\x00\x00\x13\x10\x03",
  189. 22);
  190. break;
  191. #endif /* EVERMORE_ENABLE */
  192. #ifdef GPSCLOCK_ENABLE
  193. case 5:
  194. /* probe for Furuno Electric GH-79L4-N (GPSClock);
  195. * expect $PFEC,GPssd */
  196. GPSD_LOG(LOG_PROG, &session->context->errout,
  197. "=> Probing for GPSClock\n");
  198. (void)nmea_send(session, "$PFEC,GPsrq");
  199. break;
  200. #endif /* GPSCLOCK_ENABLE */
  201. case 6:
  202. /* probe for Ashtech -- expect $PASHR,RID */
  203. GPSD_LOG(LOG_PROG, &session->context->errout,
  204. "=> Probing for Ashtech\n");
  205. (void)nmea_send(session, "$PASHQ,RID");
  206. break;
  207. #ifdef UBLOX_ENABLE
  208. case 7:
  209. // probe for UBX
  210. GPSD_LOG(LOG_PROG, &session->context->errout,
  211. "=> Probing for UBX\n");
  212. // query port configuration UBX-MON-VER
  213. (void)ubx_write(session, 0x0a, 0x04, NULL, 0);
  214. // query port configuration UBX-CFG-PRT
  215. (void)ubx_write(session, 0x06, 0x00, NULL, 0);
  216. break;
  217. #endif /* UBLOX_ENABLE */
  218. case 8:
  219. /* probe for MTK-3301 -- expect $PMTK705 */
  220. GPSD_LOG(LOG_PROG, &session->context->errout,
  221. "=> Probing for MediaTek\n");
  222. (void)nmea_send(session, "$PMTK605");
  223. break;
  224. #ifdef GREIS_ENABLE
  225. case 9:
  226. /* probe for Javad GREIS -- expect reply with JAVAD */
  227. GPSD_LOG(LOG_PROG, &session->context->errout,
  228. "=> Probing for Javad GREIS\n");
  229. /* TODO: confirm this actually gets JAVAD response */
  230. (void)nmea_send(session, "print,/par/rcv/vendor");
  231. break;
  232. #endif /* GREIS_ENABLE */
  233. default:
  234. break;
  235. }
  236. }
  237. }
  238. /* *INDENT-OFF* */
  239. const struct gps_type_t driver_nmea0183 = {
  240. .type_name = "NMEA0183", /* full name of type */
  241. .packet_type = NMEA_PACKET, /* associated lexer packet type */
  242. .flags = DRIVER_NOFLAGS, /* remember this */
  243. .trigger = NULL, /* it's the default */
  244. .channels = 12, /* consumer-grade GPS */
  245. .probe_detect = NULL, /* no probe */
  246. .get_packet = generic_get, /* use generic packet getter */
  247. .parse_packet = generic_parse_input, /* how to interpret a packet */
  248. .rtcm_writer = gpsd_write, /* write RTCM data straight */
  249. .init_query = NULL, /* non-perturbing initial query */
  250. .event_hook = nmea_event_hook, /* lifetime event handler */
  251. .speed_switcher = NULL, /* no speed switcher */
  252. #ifdef BINARY_ENABLE
  253. .mode_switcher = NULL, /* maybe switchable if it was a SiRF */
  254. #else
  255. .mode_switcher = NULL, /* no binary mode to revert to */
  256. #endif /* BINARY_ENABLE */
  257. .rate_switcher = NULL, /* no sample-rate switcher */
  258. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  259. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  260. .control_send = nmea_write, /* how to send control strings */
  261. .time_offset = NULL, /* no method for NTP fudge factor */
  262. };
  263. /* *INDENT-ON* */
  264. #if defined(GARMIN_ENABLE)
  265. /**************************************************************************
  266. *
  267. * Garmin NMEA
  268. *
  269. **************************************************************************/
  270. static void garmin_mode_switch(struct gps_device_t *session, int mode)
  271. /* only does anything in one direction, going to Garmin binary driver */
  272. {
  273. struct timespec delay;
  274. if (mode == MODE_BINARY) {
  275. (void)nmea_send(session, "$PGRMC1,1,2,1,,,,2,W,N");
  276. (void)nmea_send(session, "$PGRMI,,,,,,,R");
  277. /* wait 333 uSec, standard Garmin settling time */
  278. delay.tv_sec = 0;
  279. delay.tv_nsec = 333000L;
  280. nanosleep(&delay, NULL);
  281. }
  282. }
  283. static void garmin_nmea_event_hook(struct gps_device_t *session,
  284. event_t event)
  285. {
  286. if (session->context->readonly)
  287. return;
  288. if (event == event_driver_switch) {
  289. /* forces a reconfigure as the following packets come in */
  290. session->lexer.counter = 0;
  291. }
  292. if (session->context->passive) {
  293. return;
  294. }
  295. if (event == event_configure) {
  296. /*
  297. * And here's that reconfigure. It's split up like this because
  298. * receivers like the Garmin GPS-10 don't handle having having a lot of
  299. * probes shoved at them very well.
  300. */
  301. switch (session->lexer.counter) {
  302. case 0:
  303. /* reset some config, AutoFix, WGS84, PPS
  304. * Set the PPS pulse length to 40ms which leaves the Garmin 18-5hz
  305. * with a 160ms low state.
  306. * NOTE: new PPS only takes effect after next power cycle
  307. */
  308. (void)nmea_send(session, "$PGRMC,A,,100,,,,,,A,,1,2,1,30");
  309. break;
  310. case 1:
  311. /* once a sec, no averaging, NMEA 2.3, WAAS */
  312. (void)nmea_send(session, "$PGRMC1,1,1,1,,,,2,W,N");
  313. break;
  314. case 2:
  315. /* get some more config info */
  316. (void)nmea_send(session, "$PGRMC1E");
  317. break;
  318. case 3:
  319. /* turn off all output except GGA */
  320. (void)nmea_send(session, "$PGRMO,,2");
  321. (void)nmea_send(session, "$PGRMO,GPGGA,1");
  322. break;
  323. case 4:
  324. /* enable GPGGA, GPGSA, GPGSV, GPRMC on Garmin serial GPS */
  325. (void)nmea_send(session, "$PGRMO,GPGSA,1");
  326. break;
  327. case 5:
  328. (void)nmea_send(session, "$PGRMO,GPGSV,1");
  329. break;
  330. case 6:
  331. (void)nmea_send(session, "$PGRMO,GPRMC,1");
  332. break;
  333. case 7:
  334. (void)nmea_send(session, "$PGRMO,PGRME,1");
  335. break;
  336. }
  337. }
  338. }
  339. /* *INDENT-OFF* */
  340. const struct gps_type_t driver_garmin = {
  341. .type_name = "Garmin NMEA", /* full name of type */
  342. .packet_type = NMEA_PACKET, /* associated lexer packet type */
  343. .flags = DRIVER_STICKY, /* remember this */
  344. .trigger = "$PGRMC,", /* Garmin private */
  345. .channels = 12, /* not used by this driver */
  346. .probe_detect = NULL, /* no probe */
  347. .get_packet = generic_get, /* use generic packet getter */
  348. .parse_packet = generic_parse_input, /* how to interpret a packet */
  349. .rtcm_writer = NULL, /* some do, some don't, skip for now */
  350. .init_query = NULL, /* non-perturbing initial query */
  351. .event_hook = garmin_nmea_event_hook, /* lifetime event handler */
  352. .speed_switcher = NULL, /* no speed switcher */
  353. .mode_switcher = garmin_mode_switch, /* mode switcher */
  354. .rate_switcher = NULL, /* no sample-rate switcher */
  355. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  356. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  357. .control_send = nmea_write, /* how to send control strings */
  358. .time_offset = NULL, /* no method for NTP fudge factor */
  359. };
  360. // *INDENT-ON*
  361. #endif // GARMIN_ENABLE
  362. /**************************************************************************
  363. *
  364. * Ashtech (then Thales, now Magellan Professional) Receivers
  365. *
  366. **************************************************************************/
  367. static void ashtech_event_hook(struct gps_device_t *session, event_t event)
  368. {
  369. if (session->context->readonly)
  370. return;
  371. if (event == event_wakeup)
  372. (void)nmea_send(session, "$PASHQ,RID");
  373. if ( session->context->passive) {
  374. return;
  375. }
  376. if (event == event_identified) {
  377. /* turn WAAS on. can't hurt... */
  378. (void)nmea_send(session, "$PASHS,WAS,ON");
  379. /* reset to known output state */
  380. (void)nmea_send(session, "$PASHS,NME,ALL,A,OFF");
  381. /* then turn on some useful sentences */
  382. #ifdef __future__
  383. /* we could parse these, but they're oversize so they get dropped */
  384. (void)nmea_send(session, "$PASHS,NME,POS,A,ON");
  385. (void)nmea_send(session, "$PASHS,NME,SAT,A,ON");
  386. #else
  387. (void)nmea_send(session, "$PASHS,NME,GGA,A,ON");
  388. (void)nmea_send(session, "$PASHS,NME,GSA,A,ON");
  389. (void)nmea_send(session, "$PASHS,NME,GSV,A,ON");
  390. (void)nmea_send(session, "$PASHS,NME,RMC,A,ON");
  391. #endif
  392. (void)nmea_send(session, "$PASHS,NME,ZDA,A,ON");
  393. }
  394. }
  395. /* *INDENT-OFF* */
  396. const struct gps_type_t driver_ashtech = {
  397. .type_name = "Ashtech", /* full name of type */
  398. .packet_type = NMEA_PACKET, /* associated lexer packet type */
  399. .flags = DRIVER_STICKY, /* remember this */
  400. .trigger = "$PASHR,RID,", /* Ashtech receivers respond thus */
  401. .channels = 24, /* not used, GG24 has 24 channels */
  402. .probe_detect = NULL, /* no probe */
  403. .get_packet = generic_get, /* how to get a packet */
  404. .parse_packet = generic_parse_input, /* how to interpret a packet */
  405. .rtcm_writer = gpsd_write, /* write RTCM data straight */
  406. .init_query = NULL, /* non-perturbing initial query */
  407. .event_hook = ashtech_event_hook, /* lifetime event handler */
  408. .speed_switcher = NULL, /* no speed switcher */
  409. .mode_switcher = NULL, /* no mode switcher */
  410. .rate_switcher = NULL, /* no sample-rate switcher */
  411. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  412. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  413. .control_send = nmea_write, /* how to send control strings */
  414. .time_offset = NULL, /* no method for NTP fudge factor */
  415. };
  416. /* *INDENT-ON* */
  417. #ifdef FV18_ENABLE
  418. /**************************************************************************
  419. *
  420. * FV18 -- uses 2 stop bits, needs to be told to send GSAs
  421. *
  422. **************************************************************************/
  423. static void fv18_event_hook(struct gps_device_t *session, event_t event)
  424. {
  425. if (session->context->readonly)
  426. return;
  427. /*
  428. * Tell an FV18 to send GSAs so we'll know if 3D is accurate.
  429. * Suppress GLL and VTG. Enable ZDA so dates will be accurate for replay.
  430. * It's possible we might not need to redo this on event_reactivate,
  431. * but doing so is safe and cheap.
  432. */
  433. if (event == event_identified || event == event_reactivate)
  434. (void)nmea_send(session,
  435. "$PFEC,GPint,GSA01,DTM00,ZDA01,RMC01,GLL00,VTG00,GSV05");
  436. }
  437. /* *INDENT-OFF* */
  438. const struct gps_type_t driver_fv18 = {
  439. .type_name = "San Jose Navigation FV18", /* full name of type */
  440. .packet_type = NMEA_PACKET, /* associated lexer packet type */
  441. .flags = DRIVER_STICKY, /* remember this */
  442. .trigger = "$PFEC,GPint,", /* FV18s should echo the probe */
  443. .channels = 12, /* not used by this driver */
  444. .probe_detect = NULL, /* no probe */
  445. .get_packet = generic_get, /* how to get a packet */
  446. .parse_packet = generic_parse_input, /* how to interpret a packet */
  447. .rtcm_writer = gpsd_write, /* write RTCM data straight */
  448. .init_query = NULL, /* non-perturbing initial query */
  449. .event_hook = fv18_event_hook, /* lifetime event handler */
  450. .speed_switcher = NULL, /* no speed switcher */
  451. .mode_switcher = NULL, /* no mode switcher */
  452. .rate_switcher = NULL, /* no sample-rate switcher */
  453. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  454. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  455. .control_send = nmea_write, /* how to send control strings */
  456. .time_offset = NULL, /* no method for NTP fudge factor */
  457. };
  458. /* *INDENT-ON* */
  459. #endif /* FV18_ENABLE */
  460. #ifdef GPSCLOCK_ENABLE
  461. /**************************************************************************
  462. *
  463. * Furuno Electric GPSClock (GH-79L4)
  464. *
  465. **************************************************************************/
  466. /*
  467. * Based on http://www.tecsys.de/fileadmin/user_upload/pdf/gh79_1an_intant.pdf
  468. */
  469. /* *INDENT-OFF* */
  470. const struct gps_type_t driver_gpsclock = {
  471. .type_name = "Furuno Electric GH-79L4", /* full name of type */
  472. .packet_type = NMEA_PACKET, /* associated lexer packet type */
  473. .flags = DRIVER_STICKY, /* remember this */
  474. .trigger = "$PFEC,GPssd", /* GPSClock should return this */
  475. .channels = 12, /* not used by this driver */
  476. .probe_detect = NULL, /* no probe */
  477. .get_packet = generic_get, /* how to get a packet */
  478. .parse_packet = generic_parse_input, /* how to interpret a packet */
  479. .rtcm_writer = gpsd_write, /* write RTCM data straight */
  480. .init_query = NULL, /* non-perturbing initial query */
  481. .event_hook = NULL, /* no lifetime event handler */
  482. .speed_switcher = NULL, /* no speed switcher */
  483. .mode_switcher = NULL, /* no mode switcher */
  484. .rate_switcher = NULL, /* sample rate is fixed */
  485. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  486. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  487. .control_send = nmea_write, /* how to send control strings */
  488. .time_offset = NULL, /* no method for NTP fudge factor */
  489. };
  490. /* *INDENT-ON* */
  491. #endif /* GPSCLOCK_ENABLE */
  492. #ifdef TRIPMATE_ENABLE
  493. /**************************************************************************
  494. *
  495. * TripMate -- extended NMEA, gets faster fix when primed with lat/long/time
  496. *
  497. **************************************************************************/
  498. /*
  499. * Some technical FAQs on the TripMate:
  500. * http://vancouver-webpages.com/pub/peter/tripmate.faq
  501. * http://www.asahi-net.or.jp/~KN6Y-GTU/tripmate/trmfaqe.html
  502. * The TripMate was discontinued sometime before November 1998
  503. * and was replaced by the Zodiac EarthMate.
  504. */
  505. static void tripmate_event_hook(struct gps_device_t *session, event_t event)
  506. {
  507. if (session->context->readonly)
  508. return;
  509. /* TripMate requires this response to the ASTRAL it sends at boot time */
  510. if (event == event_identified)
  511. (void)nmea_send(session, "$IIGPQ,ASTRAL");
  512. /* stop it sending PRWIZCH */
  513. if (event == event_identified || event == event_reactivate)
  514. (void)nmea_send(session, "$PRWIILOG,ZCH,V,,");
  515. }
  516. /* *INDENT-OFF* */
  517. static const struct gps_type_t driver_tripmate = {
  518. .type_name = "Delorme TripMate", /* full name of type */
  519. .packet_type = NMEA_PACKET, /* lexer packet type */
  520. .flags = DRIVER_STICKY, /* no rollover or other flags */
  521. .trigger ="ASTRAL", /* tells us to switch */
  522. .channels = 12, /* consumer-grade GPS */
  523. .probe_detect = NULL, /* no probe */
  524. .get_packet = generic_get, /* how to get a packet */
  525. .parse_packet = generic_parse_input, /* how to interpret a packet */
  526. .rtcm_writer = gpsd_write, /* send RTCM data straight */
  527. .init_query = NULL, /* non-perturbing query */
  528. .event_hook = tripmate_event_hook, /* lifetime event handler */
  529. .speed_switcher= NULL, /* no speed switcher */
  530. .mode_switcher = NULL, /* no mode switcher */
  531. .rate_switcher = NULL, /* no sample-rate switcher */
  532. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  533. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  534. .control_send = nmea_write, /* how to send control strings */
  535. .time_offset = NULL, /* no method for NTP fudge factor */
  536. };
  537. /* *INDENT-ON* */
  538. #endif /* TRIPMATE_ENABLE */
  539. #ifdef EARTHMATE_ENABLE
  540. /**************************************************************************
  541. *
  542. * Zodiac EarthMate textual mode
  543. *
  544. * Note: This is the pre-2003 version using Zodiac binary protocol.
  545. * There is a good HOWTO at <http://www.hamhud.net/ka9mva/earthmate.htm>.
  546. * It has been replaced with a design that uses a SiRF chipset.
  547. *
  548. **************************************************************************/
  549. static void earthmate_event_hook(struct gps_device_t *session, event_t event)
  550. {
  551. struct timespec delay;
  552. if (session->context->readonly)
  553. return;
  554. if (event == event_triggermatch) {
  555. (void)gpsd_write(session, "EARTHA\r\n", 8);
  556. /* wait 10,000 uSec */
  557. delay.tv_sec = 0;
  558. delay.tv_nsec = 10000000L;
  559. nanosleep(&delay, NULL);
  560. (void)gpsd_switch_driver(session, "Zodiac");
  561. }
  562. }
  563. /* *INDENT-OFF* */
  564. static const struct gps_type_t driver_earthmate = {
  565. .type_name = "Pre-2003 Delorme EarthMate",
  566. .packet_type = NMEA_PACKET, /* associated lexer packet type */
  567. .flags = DRIVER_STICKY, /* no rollover or other flags */
  568. .trigger = "EARTHA", /* Earthmate trigger string */
  569. .channels = 12, /* not used by NMEA parser */
  570. .probe_detect = NULL, /* no probe */
  571. .get_packet = generic_get, /* how to get a packet */
  572. .parse_packet = generic_parse_input, /* how to interpret a packet */
  573. .rtcm_writer = NULL, /* don't send RTCM data */
  574. .init_query = NULL, /* non-perturbing query */
  575. .event_hook = earthmate_event_hook, /* lifetime event handler */
  576. .speed_switcher= NULL, /* no speed switcher */
  577. .mode_switcher = NULL, /* no mode switcher */
  578. .rate_switcher = NULL, /* no sample-rate switcher */
  579. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  580. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  581. .control_send = nmea_write, /* never actually used. */
  582. .time_offset = NULL, /* no method for NTP fudge factor */
  583. };
  584. /* *INDENT-ON* */
  585. #endif /* EARTHMATE_ENABLE */
  586. #ifdef TNT_ENABLE
  587. /**************************************************************************
  588. * True North Technologies - Revolution 2X Digital compass
  589. *
  590. * More info: http://www.tntc.com/
  591. *
  592. * This is a digital compass which uses magnetometers to measure the
  593. * strength of the earth's magnetic field. Based on these measurements
  594. * it provides a compass heading using NMEA formatted output strings.
  595. * This is useful to supplement the heading provided by another GPS
  596. * unit. A GPS heading is unreliable at slow speed or no speed.
  597. *
  598. **************************************************************************/
  599. static ssize_t tnt_control_send(struct gps_device_t *session,
  600. char *msg, size_t len UNUSED)
  601. /* send a control string in TNT native formal */
  602. {
  603. ssize_t status;
  604. unsigned char sum = '\0';
  605. char c, *p = msg;
  606. if (*p == '@') {
  607. p++;
  608. }
  609. #ifdef __UNUSED__
  610. else {
  611. GPSD_LOG(LOG_ERROR, &session->context->errout,
  612. "Bad TNT sentence: '%s'\n", msg);
  613. }
  614. #endif /* __UNUSED__ */
  615. while (((c = *p) != '\0')) {
  616. sum ^= c;
  617. p++;
  618. }
  619. (void)snprintf(p, 6, "*%02X\r\n", (unsigned int)sum);
  620. status = gpsd_write(session, msg, strlen(msg));
  621. return status;
  622. }
  623. static bool tnt_send(struct gps_device_t *session, const char *fmt, ...)
  624. /* printf(3)-like TNT command generator */
  625. {
  626. char buf[BUFSIZ];
  627. va_list ap;
  628. ssize_t sent;
  629. va_start(ap, fmt);
  630. (void)vsnprintf(buf, sizeof(buf) - 5, fmt, ap);
  631. va_end(ap);
  632. sent = tnt_control_send(session, buf, strlen(buf));
  633. if (sent == (ssize_t) strlen(buf)) {
  634. GPSD_LOG(LOG_IO, &session->context->errout,
  635. "=> GPS: %s\n", buf);
  636. return true;
  637. } else {
  638. GPSD_LOG(LOG_WARN, &session->context->errout,
  639. "=> GPS: %s FAILED\n", buf);
  640. return false;
  641. }
  642. }
  643. static bool tnt_speed(struct gps_device_t *session,
  644. speed_t speed, char parity UNUSED, int stopbits UNUSED)
  645. {
  646. /*
  647. * Baud rate change followed by device reset.
  648. * See page 40 of Technical Guide 1555-B. We need:
  649. * 2400 -> 1, 4800 -> 2, 9600 -> 3, 19200 -> 4, 38400 -> 5
  650. */
  651. unsigned int val = speed / 2400u; // 2400->1, 4800->2, 9600->4, 19200->8...
  652. unsigned int i = 0;
  653. /* fast way to compute log2(val) */
  654. while ((val >> i) > 1)
  655. ++i;
  656. return tnt_send(session, "@B6=%d", i + 1)
  657. && tnt_send(session, "@F28.6=1");
  658. }
  659. /* TNT lifetime event hook */
  660. static void tnt_event_hook(struct gps_device_t *session, event_t event)
  661. {
  662. if (session->context->readonly)
  663. return;
  664. if (event == event_wakeup) {
  665. (void)tnt_send(session, "@F0.3=1"); /* set run mode */
  666. (void)tnt_send(session, "@F2.2=1"); /* report in degrees */
  667. }
  668. }
  669. /* *INDENT-OFF* */
  670. const struct gps_type_t driver_trueNorth = {
  671. .type_name = "True North", /* full name of type */
  672. .packet_type = NMEA_PACKET, /* associated lexer packet type */
  673. .flags = DRIVER_STICKY, /* remember this */
  674. .trigger = "$PTNTHTM", /* their proprietary sentence */
  675. .channels = 0, /* not an actual GPS at all */
  676. .probe_detect = NULL, /* no probe in run mode */
  677. .get_packet = generic_get, /* how to get a packet */
  678. .parse_packet = generic_parse_input, /* how to interpret a packet */
  679. .rtcm_writer = NULL, /* Don't send */
  680. .init_query = NULL, /* non-perturbing initial query */
  681. .event_hook = tnt_event_hook, /* lifetime event handler */
  682. .speed_switcher = tnt_speed, /* no speed switcher */
  683. .mode_switcher = NULL, /* no mode switcher */
  684. .rate_switcher = NULL, /* no wrapup */
  685. .min_cycle.tv_sec = 0, /* not relevant, no rate switch */
  686. .min_cycle.tv_nsec = 500000000, /* not relevant, no rate switch */
  687. .control_send = tnt_control_send, /* how to send control strings */
  688. .time_offset = NULL,
  689. };
  690. /* *INDENT-ON* */
  691. #endif
  692. #ifdef OCEANSERVER_ENABLE
  693. /**************************************************************************
  694. * OceanServer - Digital Compass, OS5000 Series
  695. *
  696. * More info: http://www.ocean-server.com/download/OS5000_Compass_Manual.pdf
  697. *
  698. * This is a digital compass which uses magnetometers to measure the
  699. * strength of the earth's magnetic field. Based on these measurements
  700. * it provides a compass heading using NMEA formatted output strings.
  701. * This is useful to supplement the heading provided by another GPS
  702. * unit. A GPS heading is unreliable at slow speed or no speed.
  703. *
  704. **************************************************************************/
  705. static int oceanserver_send(struct gpsd_errout_t *errout,
  706. const int fd, const char *fmt, ...)
  707. {
  708. int status;
  709. char buf[BUFSIZ];
  710. va_list ap;
  711. va_start(ap, fmt);
  712. (void)vsnprintf(buf, sizeof(buf) - 5, fmt, ap);
  713. va_end(ap);
  714. (void)strlcat(buf, "", sizeof(buf));
  715. status = (int)write(fd, buf, strlen(buf));
  716. (void)tcdrain(fd);
  717. if (status == (int)strlen(buf)) {
  718. GPSD_LOG(LOG_IO, errout, "=> GPS: %s\n", buf);
  719. return status;
  720. } else {
  721. GPSD_LOG(LOG_WARN, errout, "=> GPS: %s FAILED\n", buf);
  722. return -1;
  723. }
  724. }
  725. static void oceanserver_event_hook(struct gps_device_t *session,
  726. event_t event)
  727. {
  728. if (session->context->readonly)
  729. return;
  730. if (event == event_configure && session->lexer.counter == 0) {
  731. /* report in NMEA format */
  732. (void)oceanserver_send(&session->context->errout,
  733. session->gpsdata.gps_fd, "2\n");
  734. /* ship all fields */
  735. (void)oceanserver_send(&session->context->errout,
  736. session->gpsdata.gps_fd, "X2047");
  737. }
  738. }
  739. /* *INDENT-OFF* */
  740. static const struct gps_type_t driver_oceanServer = {
  741. .type_name = "OceanServer OS5000", /* full name of type */
  742. .packet_type = NMEA_PACKET, /* associated lexer packet type */
  743. .flags = DRIVER_STICKY, /* no rollover or other flags */
  744. .trigger = "$OHPR,", /* detect their main sentence */
  745. .channels = 0, /* not an actual GPS at all */
  746. .probe_detect = NULL,
  747. .get_packet = generic_get, /* how to get a packet */
  748. .parse_packet = generic_parse_input, /* how to interpret a packet */
  749. .rtcm_writer = NULL, /* Don't send */
  750. .init_query = NULL, /* non-perturbing initial query */
  751. .event_hook = oceanserver_event_hook,
  752. .speed_switcher = NULL, /* no speed switcher */
  753. .mode_switcher = NULL, /* no mode switcher */
  754. .rate_switcher = NULL, /* no wrapup */
  755. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  756. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  757. .control_send = nmea_write, /* how to send control strings */
  758. .time_offset = NULL,
  759. };
  760. /* *INDENT-ON* */
  761. #endif
  762. #ifdef FURY_ENABLE
  763. /**************************************************************************
  764. *
  765. * Jackson Labs Fury, a high-precision laboratory clock
  766. *
  767. * Will also support other Jackon Labs boards, including the Firefly.
  768. *
  769. * Note: you must either build with fixed_port_speed=115200 or tweak the
  770. * speed on the port to 115200 before running. The device's default mode
  771. * does not stream output, so our hunt loop will simply time out otherwise.
  772. *
  773. **************************************************************************/
  774. static bool fury_rate_switcher(struct gps_device_t *session, double rate)
  775. {
  776. char buf[78];
  777. double inverted;
  778. /* rate is a frequency, but the command takes interval in # of seconds */
  779. if (rate == 0.0)
  780. inverted = 0.0;
  781. else
  782. inverted = 1.0/rate;
  783. if (inverted > 256)
  784. return false;
  785. (void)snprintf(buf, sizeof(buf), "GPS:GPGGA %d\r\n", (int)inverted);
  786. (void)gpsd_write(session, buf, strlen(buf));
  787. return true;
  788. }
  789. static void fury_event_hook(struct gps_device_t *session, event_t event)
  790. {
  791. if (event == event_wakeup && gpsd_get_speed(session) == 115200)
  792. (void)fury_rate_switcher(session, 1.0);
  793. else if (event == event_deactivate)
  794. (void)fury_rate_switcher(session, 0.0);
  795. }
  796. /* *INDENT-OFF* */
  797. static const struct gps_type_t driver_fury = {
  798. .type_name = "Jackson Labs Fury", /* full name of type */
  799. .packet_type = NMEA_PACKET, /* associated lexer packet type */
  800. .flags = DRIVER_STICKY, /* no rollover or other flags */
  801. .trigger = NULL, /* detect their main sentence */
  802. .channels = 0, /* not an actual GPS at all */
  803. .probe_detect = NULL,
  804. .get_packet = generic_get, /* how to get a packet */
  805. .parse_packet = generic_parse_input, /* how to interpret a packet */
  806. .rtcm_writer = NULL, /* Don't send */
  807. .init_query = NULL, /* non-perturbing initial query */
  808. .event_hook = fury_event_hook,
  809. .speed_switcher = NULL, /* no speed switcher */
  810. .mode_switcher = NULL, /* no mode switcher */
  811. .rate_switcher = fury_rate_switcher,
  812. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  813. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  814. .control_send = nmea_write, /* how to send control strings */
  815. .time_offset = NULL,
  816. };
  817. /* *INDENT-ON* */
  818. #endif /* FURY_ENABLE */
  819. #ifdef RTCM104V2_ENABLE
  820. /**************************************************************************
  821. *
  822. * RTCM-104 (v2), used for broadcasting DGPS corrections and by DGPS radios
  823. *
  824. **************************************************************************/
  825. static gps_mask_t rtcm104v2_analyze(struct gps_device_t *session)
  826. {
  827. rtcm2_unpack(session, &session->gpsdata.rtcm2,
  828. (char *)session->lexer.isgps.buf);
  829. session->cycle_end_reliable = true;
  830. return RTCM2_SET;
  831. }
  832. /* *INDENT-OFF* */
  833. static const struct gps_type_t driver_rtcm104v2 = {
  834. .type_name = "RTCM104V2", /* full name of type */
  835. .packet_type = RTCM2_PACKET, /* associated lexer packet type */
  836. .flags = DRIVER_NOFLAGS, /* no rollover or other flags */
  837. .trigger = NULL, /* no recognition string */
  838. .channels = 0, /* not used */
  839. .probe_detect = NULL, /* no probe */
  840. .get_packet = generic_get, /* how to get a packet */
  841. .parse_packet = rtcm104v2_analyze, /* */
  842. .rtcm_writer = NULL, /* don't send RTCM data, */
  843. .init_query = NULL, /* non-perturbing initial query */
  844. .event_hook = NULL, /* no event_hook */
  845. .speed_switcher= NULL, /* no speed switcher */
  846. .mode_switcher = NULL, /* no mode switcher */
  847. .rate_switcher = NULL, /* no sample-rate switcher */
  848. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  849. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  850. .control_send = NULL, /* how to send control strings */
  851. .time_offset = NULL,
  852. };
  853. /* *INDENT-ON* */
  854. #endif /* RTCM104V2_ENABLE */
  855. #ifdef RTCM104V3_ENABLE
  856. /**************************************************************************
  857. *
  858. * RTCM-104 (v3), used for broadcasting DGPS corrections and by DGPS radios
  859. *
  860. **************************************************************************/
  861. static gps_mask_t rtcm104v3_analyze(struct gps_device_t *session)
  862. {
  863. uint16_t type = getbeu16(session->lexer.outbuffer, 3) >> 4;
  864. GPSD_LOG(LOG_RAW, &session->context->errout, "RTCM 3.x packet %d\n", type);
  865. rtcm3_unpack(session->context,
  866. &session->gpsdata.rtcm3,
  867. (char *)session->lexer.outbuffer);
  868. session->cycle_end_reliable = true;
  869. return RTCM3_SET;
  870. }
  871. /* *INDENT-OFF* */
  872. static const struct gps_type_t driver_rtcm104v3 = {
  873. .type_name = "RTCM104V3", /* full name of type */
  874. .packet_type = RTCM3_PACKET, /* associated lexer packet type */
  875. .flags = DRIVER_NOFLAGS, /* no rollover or other flags */
  876. .trigger = NULL, /* no recognition string */
  877. .channels = 0, /* not used */
  878. .probe_detect = NULL, /* no probe */
  879. .get_packet = generic_get, /* how to get a packet */
  880. .parse_packet = rtcm104v3_analyze, /* */
  881. .rtcm_writer = NULL, /* don't send RTCM data, */
  882. .init_query = NULL, /* non-perturbing initial query */
  883. .event_hook = NULL, /* no event hook */
  884. .speed_switcher= NULL, /* no speed switcher */
  885. .mode_switcher = NULL, /* no mode switcher */
  886. .rate_switcher = NULL, /* no sample-rate switcher */
  887. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  888. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  889. .control_send = NULL, /* how to send control strings */
  890. .time_offset = NULL,
  891. };
  892. /* *INDENT-ON* */
  893. #endif /* RTCM104V3_ENABLE */
  894. #ifdef GARMINTXT_ENABLE
  895. /**************************************************************************
  896. *
  897. * Garmin Simple Text protocol
  898. *
  899. **************************************************************************/
  900. /* *INDENT-OFF* */
  901. static const struct gps_type_t driver_garmintxt = {
  902. .type_name = "Garmin Simple Text", /* full name of type */
  903. .packet_type = GARMINTXT_PACKET, /* associated lexer packet type */
  904. .flags = DRIVER_NOFLAGS, /* no rollover or other flags */
  905. .trigger = NULL, /* no recognition string */
  906. .channels = 0, /* not used */
  907. .probe_detect = NULL, /* no probe */
  908. .get_packet = generic_get, /* how to get a packet */
  909. .parse_packet = garmintxt_parse, /* how to parse one */
  910. .rtcm_writer = NULL, /* don't send RTCM data, */
  911. .init_query = NULL, /* non-perturbing initial query */
  912. .event_hook = NULL, /* no event hook */
  913. .speed_switcher= NULL, /* no speed switcher */
  914. .mode_switcher = NULL, /* no mode switcher */
  915. .rate_switcher = NULL, /* no sample-rate switcher */
  916. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  917. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  918. .control_send = NULL, /* how to send control strings */
  919. .time_offset = NULL,
  920. };
  921. /* *INDENT-ON* */
  922. #endif /* GARMINTXT_ENABLE */
  923. /**************************************************************************
  924. *
  925. * MediaTek MTK-3301, 3329, 3333, 3339
  926. *
  927. * OEMs for several GPS vendors, notably including Garmin, FasTrax, Trimble,
  928. * and AdaFruit. Website at <http://www.mediatek.com/>.
  929. *
  930. * The Trimble Condor appears to be an MTK3329. It behaves as an MTK3301
  931. * and positively acknowledges all 3301 sentences as valid. It ignores $PMTK
  932. * sentence fields that are not implemented in the Trimble Condor. It does
  933. * not have power-save mode and ignores $PMTK320. For $PMTK314 it silently
  934. * ignores periodic enabling of messages that aren't supported.
  935. *
  936. * From its datasheet the MTK3339 seems to add QZSS support not present in
  937. * earlier versions. The data sheet says it has 66 channels, which mkes
  938. * sense given the multi-constellation capability. The channel count
  939. * in the driver is never used by the NMEA driver so leaving the lower MTK3301
  940. * value in there is OK.
  941. *
  942. * MTK3333 support 10Hz.
  943. *
  944. * The Adafruit GPS HAT for the Raspberry Pi is an MTK3339. It works with this
  945. * driver; in fact AdaFruit's overview page for the product features GPSD.
  946. *
  947. * SIMCom DIM68M appears to be an MTK3333.
  948. *
  949. **************************************************************************/
  950. static void mtk3301_event_hook(struct gps_device_t *session, event_t event)
  951. {
  952. /*
  953. 0 NMEA_SEN_GLL, GPGLL interval - Geographic Position - Latitude longitude
  954. 1 NMEA_SEN_RMC, GPRMC interval - Recommended Minimum Specific GNSS Sentence
  955. 2 NMEA_SEN_VTG, GPVTG interval - Course Over Ground and Ground Speed
  956. 3 NMEA_SEN_GGA, GPGGA interval - GPS Fix Data
  957. 4 NMEA_SEN_GSA, GPGSA interval - GNSS DOPS and Active Satellites
  958. 5 NMEA_SEN_GSV, GPGSV interval - GNSS Satellites in View
  959. 6 NMEA_SEN_GRS, GPGRS interval - GNSS Range Residuals
  960. 7 NMEA_SEN_GST, GPGST interval - GNSS Pseudorange Errors Statistics
  961. 13 NMEA_SEN_MALM, PMTKALM interval - GPS almanac information
  962. 14 NMEA_SEN_MEPH, PMTKEPH interval - GPS ephemeris information
  963. 15 NMEA_SEN_MDGP, PMTKDGP interval - GPS differential correction information
  964. 16 NMEA_SEN_MDBG, PMTKDBG interval – MTK debug information
  965. 17 NMEA_SEN_ZDA, GPZDA interval - Time & Date
  966. 18 NMEA_SEN_MCHN, PMTKCHN interval – GPS channel status
  967. // MTK 3333
  968. 19 NMEA_SEN_DTM, GPDTM interval - Datum reference
  969. "$PMTK314,1,1,1,1,1,5,1,1,0,0,0,0,0,0,0,0,0,1,0"
  970. */
  971. if (session->context->readonly)
  972. return;
  973. if (event == event_triggermatch) {
  974. (void)nmea_send(session, "$PMTK320,0"); /* power save off */
  975. // Fix interval, 1000 millseconds
  976. (void)nmea_send(session, "$PMTK300,1000,0,0,0.0,0.0");
  977. // Set NMEA sentences.
  978. (void)nmea_send(session,
  979. "$PMTK314,0,1,0,1,1,5,1,1,0,0,0,0,0,0,0,0,0,1,0");
  980. // DGPS is WAAS
  981. (void)nmea_send(session, "$PMTK301,2");
  982. // SBAS enable
  983. (void)nmea_send(session, "$PMTK313,1");
  984. /* PMTK_API_Q_OUTPUT_CTL - Query PPS pulse width - Trimble only?
  985. * http://trl.trimble.com/docushare/dsweb/Get/Document-482603/CONDOR_UG_2C_75263-00.pdf *
  986. * badly documented */
  987. (void)nmea_send(session, "$PMTK424");
  988. }
  989. }
  990. // mtk3301_speed_switcher()
  991. // Always returns True
  992. static bool mtk3301_speed_switcher(struct gps_device_t* session,
  993. speed_t speed, char parity UNUSED,
  994. int stopbits UNUSED)
  995. {
  996. int i;
  997. char buf[BUFSIZ] = {0};
  998. (void)snprintf(buf, sizeof(buf), "$PQBAUD,W,%d", (int) speed);
  999. // Calling PQBAUD fails to set the receiver's baud rate
  1000. // some of the time. Sending it twice seems to work every time.
  1001. // So just for good measure, send it three times.
  1002. for (i = 0; i < 3; i++) {
  1003. (void)nmea_send(session, buf);
  1004. }
  1005. return true;
  1006. }
  1007. static bool mtk3301_rate_switcher(struct gps_device_t *session, double rate)
  1008. {
  1009. char buf[78];
  1010. unsigned int milliseconds = (unsigned int)(1000 * rate);
  1011. if (rate > 1) {
  1012. // force no slower than 1Hz
  1013. milliseconds = 1000;
  1014. } else if (rate < 0.1) {
  1015. // force no faster than 10Hz, MTK3333 can do 10Hz
  1016. milliseconds = 100;
  1017. }
  1018. (void)snprintf(buf, sizeof(buf), "$PMTK300,%u,0,0,0,0", milliseconds);
  1019. (void)nmea_send(session, buf); /* Fix interval */
  1020. return true;
  1021. }
  1022. /* *INDENT-OFF* */
  1023. const struct gps_type_t driver_mtk3301 = {
  1024. .type_name = "MTK-3301", /* full name of type */
  1025. .packet_type = NMEA_PACKET, /* associated lexer packet type */
  1026. .flags = DRIVER_STICKY, /* remember this */
  1027. .trigger = "$PMTK705,", /* firmware release name and version */
  1028. .channels = 12, /* not used by this driver */
  1029. .probe_detect = NULL, /* no probe */
  1030. .get_packet = generic_get, /* how to get a packet */
  1031. .parse_packet = generic_parse_input, /* how to interpret a packet */
  1032. .rtcm_writer = gpsd_write, /* write RTCM data straight */
  1033. .init_query = NULL, /* non-perturbing initial query */
  1034. .event_hook = mtk3301_event_hook, /* lifetime event handler */
  1035. .speed_switcher = mtk3301_speed_switcher, // sample speed switcher
  1036. .mode_switcher = NULL, /* no mode switcher */
  1037. .rate_switcher = mtk3301_rate_switcher, /* sample rate switcher */
  1038. .min_cycle.tv_sec = 0,
  1039. .min_cycle.tv_nsec = 100000000, /* max 10Hz */
  1040. .control_send = nmea_write, /* how to send control strings */
  1041. .time_offset = NULL,
  1042. };
  1043. /* *INDENT-ON* */
  1044. #ifdef ISYNC_ENABLE
  1045. /**************************************************************************
  1046. *
  1047. * Spectratime LNRCLOK / GRCLOK iSync GPS-disciplined rubidium oscillators
  1048. *
  1049. * These devices comprise a u-blox 6 attached to a separate iSync
  1050. * microcontroller which drives the rubidium oscillator. The iSync
  1051. * microcontroller can be configured to pass through the underlying
  1052. * GPS communication channel, while still using the GPS PPSREF signal
  1053. * to discipline the rubidium oscillator.
  1054. *
  1055. * The iSync can also generate its own periodic status packets in NMEA
  1056. * format. These describe the state of the oscillator (including
  1057. * whether or not the oscillator PPSOUT is synced to the GPS PPSREF).
  1058. * These packets are transmitted in the middle of the underlying GPS
  1059. * packets, forcing us to handle interrupted NMEA packets.
  1060. *
  1061. * The default state of the device is to generate no periodic output.
  1062. * We send a probe string to initiate beating of the iSync-proprietary
  1063. * $PTNTS,B message, which is then detected as a NMEA trigger.
  1064. *
  1065. **************************************************************************/
  1066. static ssize_t isync_write(struct gps_device_t *session, const char *data)
  1067. {
  1068. return gpsd_write(session, data, strlen(data));
  1069. }
  1070. static bool isync_detect(struct gps_device_t *session)
  1071. {
  1072. speed_t old_baudrate;
  1073. char old_parity;
  1074. unsigned int old_stopbits;
  1075. /* Set 9600 8N1 */
  1076. old_baudrate = session->gpsdata.dev.baudrate;
  1077. old_parity = session->gpsdata.dev.parity;
  1078. old_stopbits = session->gpsdata.dev.stopbits;
  1079. gpsd_set_speed(session, 9600, 'N', 1);
  1080. /* Cancel pass-through mode and initiate beating of $PTNTS,B
  1081. * message, which can subsequently be detected as a trigger.
  1082. */
  1083. (void)isync_write(session, "@@@@\r\nMAW0C0B\r\n");
  1084. /* return serial port to original settings */
  1085. gpsd_set_speed(session, old_baudrate, old_parity, old_stopbits);
  1086. return false;
  1087. }
  1088. static void isync_event_hook(struct gps_device_t *session, event_t event)
  1089. {
  1090. if (session->context->readonly)
  1091. return;
  1092. if (event == event_driver_switch) {
  1093. session->lexer.counter = 0;
  1094. }
  1095. if (event == event_configure) {
  1096. switch (session->lexer.counter) {
  1097. case 1:
  1098. /* Configure timing and frequency flags:
  1099. * - Thermal compensation active
  1100. * - PPSREF active
  1101. * - PPSOUT active
  1102. */
  1103. (void)isync_write(session, "MAW040B\r\n");
  1104. /* Configure tracking flags:
  1105. * - Save frequency every 24 hours
  1106. * - Align PPSOUT to PPSINT
  1107. * - Track PPSREF
  1108. */
  1109. (void)isync_write(session, "MAW0513\r\n");
  1110. /* Configure tracking start flags:
  1111. * - Tracking restart allowed
  1112. * - Align to PPSREF
  1113. */
  1114. (void)isync_write(session, "MAW0606\r\n");
  1115. /* Configure tracking window:
  1116. * - 4us
  1117. */
  1118. (void)isync_write(session, "MAW1304\r\n");
  1119. /* Configure alarm window:
  1120. * - 4us
  1121. */
  1122. (void)isync_write(session, "MAW1404\r\n");
  1123. break;
  1124. case 2:
  1125. /* Configure pulse every d second:
  1126. * - pulse every second
  1127. */
  1128. (void)isync_write(session, "MAW1701\r\n");
  1129. /* Configure pulse origin:
  1130. * - zero offset
  1131. */
  1132. (void)isync_write(session, "MAW1800\r\n");
  1133. /* Configure pulse width:
  1134. * - 600ms
  1135. */
  1136. (void)isync_write(session, "MAW1223C34600\r\n");
  1137. break;
  1138. case 3:
  1139. /* Configure GPS resource utilization:
  1140. * - do not consider GPS messages
  1141. */
  1142. (void)isync_write(session, "MAW2200\r\n");
  1143. /* Restart sync */
  1144. (void)isync_write(session, "SY1\r\n");
  1145. /* Restart tracking */
  1146. (void)isync_write(session, "TR1\r\n");
  1147. break;
  1148. case 4:
  1149. /* Cancel BTx messages (if any) */
  1150. (void)isync_write(session, "BT0\r\n");
  1151. /* Configure messages coming out every second:
  1152. * - Oscillator status ($PTNTA) at 750ms
  1153. */
  1154. (void)isync_write(session, "MAW0B00\r\n");
  1155. (void)isync_write(session, "MAW0C0A\r\n");
  1156. break;
  1157. case 5:
  1158. /* Enable GPS passthrough and force u-blox driver to
  1159. * select NMEA mode.
  1160. */
  1161. session->mode = 0;
  1162. session->drivers_identified = 0;
  1163. (void)isync_write(session, "@@@@GPS\r\n");
  1164. break;
  1165. case 6:
  1166. /* Trigger detection of underlying u-blox (if necessary) */
  1167. (void)ubx_write(session, 0x06, 0x00, NULL, 0);
  1168. break;
  1169. }
  1170. }
  1171. }
  1172. /* *INDENT-OFF* */
  1173. const struct gps_type_t driver_isync = {
  1174. .type_name = "iSync", /* full name of type */
  1175. .packet_type = NMEA_PACKET, /* associated lexer packet type */
  1176. .flags = DRIVER_STICKY, /* remember this */
  1177. .trigger = "$PTNTS,B,", /* iSync status message */
  1178. .channels = 50, /* copied from driver_ubx */
  1179. .probe_detect = isync_detect, /* how to detect at startup time */
  1180. .get_packet = generic_get, /* how to get a packet */
  1181. .parse_packet = generic_parse_input, /* how to interpret a packet */
  1182. .init_query = NULL, /* non-perturbing initial query */
  1183. .event_hook = isync_event_hook, /* lifetime event handler */
  1184. .speed_switcher = NULL, /* no speed switcher */
  1185. .mode_switcher = NULL, /* no mode switcher */
  1186. .rate_switcher = NULL, /* no sample-rate switcher */
  1187. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  1188. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  1189. .control_send = nmea_write, /* how to send control strings */
  1190. .time_offset = NULL, /* no method for NTP fudge factor */
  1191. };
  1192. /* *INDENT-ON* */
  1193. #endif /* ISYNC_ENABLE */
  1194. #ifdef AIVDM_ENABLE
  1195. /**************************************************************************
  1196. *
  1197. * AIVDM - ASCII armoring of binary AIS packets
  1198. *
  1199. **************************************************************************/
  1200. static bool aivdm_decode(const char *buf, size_t buflen,
  1201. struct gps_device_t *session,
  1202. struct ais_t *ais,
  1203. int debug)
  1204. {
  1205. #ifdef __UNUSED_DEBUG__
  1206. char *sixbits[64] = {
  1207. "000000", "000001", "000010", "000011", "000100",
  1208. "000101", "000110", "000111", "001000", "001001",
  1209. "001010", "001011", "001100", "001101", "001110",
  1210. "001111", "010000", "010001", "010010", "010011",
  1211. "010100", "010101", "010110", "010111", "011000",
  1212. "011001", "011010", "011011", "011100", "011101",
  1213. "011110", "011111", "100000", "100001", "100010",
  1214. "100011", "100100", "100101", "100110", "100111",
  1215. "101000", "101001", "101010", "101011", "101100",
  1216. "101101", "101110", "101111", "110000", "110001",
  1217. "110010", "110011", "110100", "110101", "110110",
  1218. "110111", "111000", "111001", "111010", "111011",
  1219. "111100", "111101", "111110", "111111",
  1220. };
  1221. #endif /* __UNUSED_DEBUG__ */
  1222. int nfrags, ifrag, nfields = 0;
  1223. unsigned char *field[NMEA_MAX*2];
  1224. unsigned char fieldcopy[NMEA_MAX*2+1];
  1225. unsigned char *data, *cp;
  1226. char const *cp1;
  1227. int pad;
  1228. struct aivdm_context_t *ais_context;
  1229. int i;
  1230. if (buflen == 0)
  1231. return false;
  1232. /* we may need to dump the raw packet */
  1233. GPSD_LOG(LOG_PROG, &session->context->errout,
  1234. "AIVDM packet length %zd: %s\n", buflen, buf);
  1235. /* first clear the result, making sure we don't return garbage */
  1236. memset(ais, 0, sizeof(*ais));
  1237. /* discard overlong sentences */
  1238. if (strlen(buf) > sizeof(fieldcopy)-1) {
  1239. GPSD_LOG(LOG_ERROR, &session->context->errout,
  1240. "overlong AIVDM packet.\n");
  1241. return false;
  1242. }
  1243. /* discard sentences with high-half characters in them, they're corrupted */
  1244. for (cp1 = buf; *cp1; cp1++) {
  1245. if (!isascii(*cp1)) {
  1246. GPSD_LOG(LOG_ERROR, &session->context->errout,
  1247. "corrupted AIVDM packet.\n");
  1248. return false;
  1249. }
  1250. }
  1251. /* extract packet fields */
  1252. (void)strlcpy((char *)fieldcopy, buf, sizeof(fieldcopy));
  1253. field[nfields++] = (unsigned char *)buf;
  1254. for (cp = fieldcopy;
  1255. cp < fieldcopy + buflen; cp++)
  1256. {
  1257. if (
  1258. (*cp == (unsigned char)',') ||
  1259. (*cp == (unsigned char)'*')
  1260. ) {
  1261. *cp = '\0';
  1262. field[nfields++] = cp + 1;
  1263. }
  1264. }
  1265. #ifdef __UNDEF_DEBUG_
  1266. for(int nf = 0; nf < nfields; nf++)
  1267. GPSD_LOG(LOG_DATA, &session->context->errout,
  1268. "field [%d] [%s]\n", nf, field[nf]);
  1269. #endif
  1270. /* discard sentences with exiguous commas; catches run-ons */
  1271. if (nfields < 7) {
  1272. GPSD_LOG(LOG_ERROR, &session->context->errout,
  1273. "malformed AIVDM packet.\n");
  1274. return false;
  1275. }
  1276. switch (field[4][0]) {
  1277. case '\0':
  1278. /*
  1279. * Apparently an empty channel is normal for AIVDO sentences,
  1280. * which makes sense as they don't come in over radio. This
  1281. * is going to break if there's ever an AIVDO type 24, though.
  1282. */
  1283. if (!str_starts_with((const char *)field[0], "!AIVDO"))
  1284. GPSD_LOG(LOG_INF, &session->context->errout,
  1285. "invalid empty AIS channel. Assuming 'A'\n");
  1286. ais_context = &session->driver.aivdm.context[0];
  1287. session->driver.aivdm.ais_channel ='A';
  1288. break;
  1289. case '1':
  1290. if (strcmp((char *)field[4], (char *)"12") == 0) {
  1291. GPSD_LOG(LOG_INF, &session->context->errout,
  1292. "ignoring bogus AIS channel '12'.\n");
  1293. return false;
  1294. }
  1295. FALLTHROUGH
  1296. case 'A':
  1297. ais_context = &session->driver.aivdm.context[0];
  1298. session->driver.aivdm.ais_channel ='A';
  1299. break;
  1300. case '2':
  1301. case 'B':
  1302. ais_context = &session->driver.aivdm.context[1];
  1303. session->driver.aivdm.ais_channel ='B';
  1304. break;
  1305. case 'C':
  1306. GPSD_LOG(LOG_INF, &session->context->errout,
  1307. "ignoring AIS channel C (secure AIS).\n");
  1308. return false;
  1309. default:
  1310. GPSD_LOG(LOG_ERROR, &session->context->errout,
  1311. "invalid AIS channel 0x%0X .\n", field[4][0]);
  1312. return false;
  1313. }
  1314. nfrags = atoi((char *)field[1]); /* number of fragments to expect */
  1315. ifrag = atoi((char *)field[2]); /* fragment id */
  1316. data = field[5];
  1317. pad = 0;
  1318. if(isdigit(field[6][0]))
  1319. pad = field[6][0] - '0'; /* number of padding bits ASCII encoded*/
  1320. GPSD_LOG(LOG_PROG, &session->context->errout,
  1321. "nfrags=%d, ifrag=%d, decoded_frags=%d, data=%s, pad=%d\n",
  1322. nfrags, ifrag, ais_context->decoded_frags, data, pad);
  1323. /* assemble the binary data */
  1324. /* check fragment ordering */
  1325. if (ifrag != ais_context->decoded_frags + 1) {
  1326. GPSD_LOG(LOG_ERROR, &session->context->errout,
  1327. "invalid fragment #%d received, expected #%d.\n",
  1328. ifrag, ais_context->decoded_frags + 1);
  1329. if (ifrag != 1)
  1330. return false;
  1331. /* else, ifrag==1: Just discard all that was previously decoded and
  1332. * simply handle that packet */
  1333. ais_context->decoded_frags = 0;
  1334. }
  1335. if (ifrag == 1) {
  1336. (void)memset(ais_context->bits, '\0', sizeof(ais_context->bits));
  1337. ais_context->bitlen = 0;
  1338. }
  1339. /* wacky 6-bit encoding, shades of FIELDATA */
  1340. for (cp = data; cp < data + strlen((char *)data); cp++) {
  1341. unsigned char ch;
  1342. ch = *cp;
  1343. ch -= 48;
  1344. if (ch >= 40)
  1345. ch -= 8;
  1346. #ifdef __UNUSED_DEBUG__
  1347. GPSD_LOG(LOG_RAW, &session->context->errout,
  1348. "%c: %s\n", *cp, sixbits[ch]);
  1349. #endif /* __UNUSED_DEBUG__ */
  1350. for (i = 5; i >= 0; i--) {
  1351. if ((ch >> i) & 0x01) {
  1352. ais_context->bits[ais_context->bitlen / 8] |=
  1353. (1 << (7 - ais_context->bitlen % 8));
  1354. }
  1355. ais_context->bitlen++;
  1356. if (ais_context->bitlen > sizeof(ais_context->bits)) {
  1357. GPSD_LOG(LOG_INF, &session->context->errout,
  1358. "overlong AIVDM payload truncated.\n");
  1359. return false;
  1360. }
  1361. }
  1362. }
  1363. ais_context->bitlen -= pad;
  1364. /* time to pass buffered-up data to where it's actually processed? */
  1365. if (ifrag == nfrags) {
  1366. if (debug >= LOG_INF) {
  1367. size_t clen = BITS_TO_BYTES(ais_context->bitlen);
  1368. GPSD_LOG(LOG_INF, &session->context->errout,
  1369. "AIVDM payload is %zd bits, %zd chars: %s\n",
  1370. ais_context->bitlen, clen,
  1371. gpsd_hexdump(session->msgbuf, sizeof(session->msgbuf),
  1372. (char *)ais_context->bits, clen));
  1373. }
  1374. /* clear waiting fragments count */
  1375. ais_context->decoded_frags = 0;
  1376. /* decode the assembled binary packet */
  1377. return ais_binary_decode(&session->context->errout,
  1378. ais,
  1379. ais_context->bits,
  1380. ais_context->bitlen,
  1381. &ais_context->type24_queue);
  1382. }
  1383. /* we're still waiting on another sentence */
  1384. ais_context->decoded_frags++;
  1385. return false;
  1386. }
  1387. static gps_mask_t aivdm_analyze(struct gps_device_t *session)
  1388. {
  1389. if (session->lexer.type == AIVDM_PACKET) {
  1390. if (aivdm_decode
  1391. ((char *)session->lexer.outbuffer, session->lexer.outbuflen,
  1392. session, &session->gpsdata.ais,
  1393. session->context->errout.debug)) {
  1394. return ONLINE_SET | AIS_SET;
  1395. } else
  1396. return ONLINE_SET;
  1397. } else if (session->lexer.type == NMEA_PACKET) {
  1398. return nmea_parse((char *)session->lexer.outbuffer, session);
  1399. } else
  1400. return 0;
  1401. }
  1402. /* *INDENT-OFF* */
  1403. const struct gps_type_t driver_aivdm = {
  1404. /* Full name of type */
  1405. .type_name = "AIVDM", /* associated lexer packet type */
  1406. .packet_type = AIVDM_PACKET, /* numeric packet type */
  1407. .flags = DRIVER_NOFLAGS, /* no rollover or other flags */
  1408. .trigger = NULL, /* identifying response */
  1409. .channels = 0, /* not used by this driver */
  1410. .probe_detect = NULL, /* no probe */
  1411. .get_packet = generic_get, /* how to get a packet */
  1412. .parse_packet = aivdm_analyze, /* how to analyze a packet */
  1413. .rtcm_writer = NULL, /* don't send RTCM data, */
  1414. .init_query = NULL, /* non-perturbing initial query */
  1415. .event_hook = NULL, /* lifetime event handler */
  1416. .speed_switcher = NULL, /* no speed switcher */
  1417. .mode_switcher = NULL, /* no mode switcher */
  1418. .rate_switcher = NULL, /* no rate switcher */
  1419. .min_cycle.tv_sec = 1, /* max 1Hz */
  1420. .min_cycle.tv_nsec = 0,
  1421. .control_send = NULL, /* no control sender */
  1422. .time_offset = NULL, /* no NTP communication */
  1423. };
  1424. /* *INDENT-ON* */
  1425. #endif /* AIVDM_ENABLE */
  1426. /**************************************************************************
  1427. *
  1428. * JSON passthrough driver
  1429. *
  1430. **************************************************************************/
  1431. /* prepend the session path to the value of a specified attribute */
  1432. static void path_rewrite(struct gps_device_t *session, char *prefix)
  1433. {
  1434. /*
  1435. * Hack the packet to reflect its origin. This code is supposed
  1436. * to insert the path naming the remote gpsd instance into the
  1437. * beginning of the path attribute, followed by a # to separate it
  1438. * from the device.
  1439. */
  1440. char *prefloc;
  1441. assert(prefix != NULL && session->lexer.outbuffer != NULL);
  1442. /* possibly the rewrite has been done already, this comw up in gpsmon */
  1443. if (strstr((char *)session->lexer.outbuffer,
  1444. session->gpsdata.dev.path) != NULL)
  1445. return;
  1446. for (prefloc = (char *)session->lexer.outbuffer;
  1447. prefloc < (char *)session->lexer.outbuffer+session->lexer.outbuflen;
  1448. prefloc++)
  1449. if (str_starts_with(prefloc, prefix)) {
  1450. char *sfxloc;
  1451. char copy[sizeof(session->lexer.outbuffer)+1];
  1452. (void)strlcpy(copy,
  1453. (char *)session->lexer.outbuffer,
  1454. sizeof(copy));
  1455. prefloc += strlen(prefix);
  1456. (void)strlcpy(prefloc,
  1457. session->gpsdata.dev.path,
  1458. sizeof(session->gpsdata.dev.path));
  1459. if ((sfxloc = strchr(prefloc, '#')))
  1460. *sfxloc = '\0'; /* Avoid accumulating multiple device names */
  1461. (void)strlcat((char *)session->lexer.outbuffer, "#",
  1462. sizeof(session->lexer.outbuffer));
  1463. (void)strlcat((char *)session->lexer.outbuffer,
  1464. copy + (prefloc-(char *)session->lexer.outbuffer),
  1465. sizeof(session->lexer.outbuffer));
  1466. }
  1467. session->lexer.outbuflen = strlen((char *)session->lexer.outbuffer);
  1468. }
  1469. static gps_mask_t json_pass_packet(struct gps_device_t *session)
  1470. {
  1471. GPSD_LOG(LOG_IO, &session->context->errout,
  1472. "<= GPS: %s\n", (char *)session->lexer.outbuffer);
  1473. if (strstr(session->gpsdata.dev.path, ":/") != NULL &&
  1474. strstr(session->gpsdata.dev.path, "localhost") == NULL)
  1475. {
  1476. /* devices and paths need to be edited */
  1477. if (strstr((char *)session->lexer.outbuffer, "DEVICE") != NULL)
  1478. path_rewrite(session, "\"path\":\"");
  1479. path_rewrite(session, "\"device\":\"");
  1480. /* mark certain responses without a path or device attribute */
  1481. if (session->gpsdata.dev.path[0] != '\0') {
  1482. if (strstr((char *)session->lexer.outbuffer, "VERSION") != NULL
  1483. || strstr((char *)session->lexer.outbuffer, "WATCH") != NULL
  1484. || strstr((char *)session->lexer.outbuffer, "DEVICES") != NULL) {
  1485. session->lexer.outbuffer[session->lexer.outbuflen-1] = '\0';
  1486. (void)strlcat((char *)session->lexer.outbuffer, ",\"remote\":\"",
  1487. sizeof(session->lexer.outbuffer));
  1488. (void)strlcat((char *)session->lexer.outbuffer,
  1489. session->gpsdata.dev.path,
  1490. sizeof(session->lexer.outbuffer));
  1491. (void)strlcat((char *)session->lexer.outbuffer, "\"}",
  1492. sizeof(session->lexer.outbuffer));
  1493. }
  1494. session->lexer.outbuflen = strlen((char *)session->lexer.outbuffer);
  1495. }
  1496. }
  1497. GPSD_LOG(LOG_PROG, &session->context->errout,
  1498. "JSON, passing through %s\n",
  1499. (char *)session->lexer.outbuffer);
  1500. return PASSTHROUGH_IS;
  1501. }
  1502. /* *INDENT-OFF* */
  1503. const struct gps_type_t driver_json_passthrough = {
  1504. .type_name = "JSON slave driver", /* full name of type */
  1505. .packet_type = JSON_PACKET, /* associated lexer packet type */
  1506. .flags = DRIVER_NOFLAGS, /* don't remember this */
  1507. .trigger = NULL, /* it's the default */
  1508. .channels = 0, /* not used */
  1509. .probe_detect = NULL, /* no probe */
  1510. .get_packet = generic_get, /* use generic packet getter */
  1511. .parse_packet = json_pass_packet, /* how to interpret a packet */
  1512. .rtcm_writer = NULL, /* write RTCM data straight */
  1513. .init_query = NULL, /* non-perturbing initial query */
  1514. .event_hook = NULL, /* lifetime event handler */
  1515. .speed_switcher = NULL, /* no speed switcher */
  1516. .mode_switcher = NULL, /* no mode switcher */
  1517. .rate_switcher = NULL, /* no sample-rate switcher */
  1518. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  1519. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  1520. .control_send = NULL, /* how to send control strings */
  1521. .time_offset = NULL, /* no method for NTP fudge factor */
  1522. };
  1523. /* *INDENT-ON* */
  1524. /* *INDENT-OFF* */
  1525. const struct gps_type_t driver_pps = {
  1526. .type_name = "PPS", /* full name of type */
  1527. .packet_type = BAD_PACKET, /* associated lexer packet type */
  1528. .flags = DRIVER_NOFLAGS, /* don't remember this */
  1529. .trigger = NULL, /* it's the default */
  1530. .channels = 0, /* not used */
  1531. .probe_detect = NULL, /* no probe */
  1532. .get_packet = NULL, /* use generic packet getter */
  1533. .parse_packet = NULL, /* how to interpret a packet */
  1534. .rtcm_writer = NULL, /* write RTCM data straight */
  1535. .init_query = NULL, /* non-perturbing initial query */
  1536. .event_hook = NULL, /* lifetime event handler */
  1537. .speed_switcher = NULL, /* no speed switcher */
  1538. .mode_switcher = NULL, /* no mode switcher */
  1539. .rate_switcher = NULL, /* no sample-rate switcher */
  1540. .min_cycle.tv_sec = 1, /* not relevant, no rate switch */
  1541. .min_cycle.tv_nsec = 0, /* not relevant, no rate switch */
  1542. .control_send = NULL, /* how to send control strings */
  1543. .time_offset = NULL, /* no method for NTP fudge factor */
  1544. };
  1545. /* *INDENT-ON* */
  1546. extern const struct gps_type_t driver_evermore;
  1547. extern const struct gps_type_t driver_garmin_ser_binary;
  1548. extern const struct gps_type_t driver_garmin_usb_binary;
  1549. extern const struct gps_type_t driver_geostar;
  1550. extern const struct gps_type_t driver_greis;
  1551. extern const struct gps_type_t driver_italk;
  1552. extern const struct gps_type_t driver_navcom;
  1553. extern const struct gps_type_t driver_nmea2000;
  1554. extern const struct gps_type_t driver_oncore;
  1555. extern const struct gps_type_t driver_sirf;
  1556. extern const struct gps_type_t driver_skytraq;
  1557. extern const struct gps_type_t driver_superstar2;
  1558. extern const struct gps_type_t driver_tsip;
  1559. extern const struct gps_type_t driver_ubx;
  1560. extern const struct gps_type_t driver_zodiac;
  1561. // the point of this rigamarole is to not have to export a table size
  1562. static const struct gps_type_t *gpsd_driver_array[] = {
  1563. &driver_unknown,
  1564. &driver_nmea0183,
  1565. &driver_ashtech,
  1566. #ifdef TRIPMATE_ENABLE
  1567. &driver_tripmate,
  1568. #endif // TRIPMATE_ENABLE
  1569. #ifdef EARTHMATE_ENABLE
  1570. &driver_earthmate,
  1571. #endif // EARTHMATE_ENABLE
  1572. #ifdef GPSCLOCK_ENABLE
  1573. &driver_gpsclock,
  1574. #endif // GPSCLOCK_ENABLE
  1575. #ifdef GARMIN_ENABLE
  1576. &driver_garmin,
  1577. #endif // GARMIN_ENABLE
  1578. &driver_mtk3301,
  1579. #ifdef OCEANSERVER_ENABLE
  1580. &driver_oceanServer,
  1581. #endif // OCEANSERVER_ENABLE
  1582. #ifdef FV18_ENABLE
  1583. &driver_fv18,
  1584. #endif // FV18_ENABLE
  1585. #ifdef TNT_ENABLE
  1586. &driver_trueNorth,
  1587. #endif // TNT_ENABLE
  1588. #ifdef FURY_ENABLE
  1589. &driver_fury,
  1590. #endif // FURY_ENABLE
  1591. #ifdef AIVDM_ENABLE
  1592. &driver_aivdm,
  1593. #endif // AIVDM_ENABLE
  1594. #ifdef EVERMORE_ENABLE
  1595. &driver_evermore,
  1596. #endif // EVERMORE_ENABLE
  1597. #ifdef GARMIN_ENABLE
  1598. // be sure to try Garmin Serial Binary before Garmin USB Binary
  1599. &driver_garmin_ser_binary,
  1600. &driver_garmin_usb_binary,
  1601. #endif // GARMIN_ENABLE
  1602. #ifdef GEOSTAR_ENABLE
  1603. &driver_geostar,
  1604. #endif // GEOSTAR_ENABLE
  1605. #ifdef GREIS_ENABLE
  1606. &driver_greis,
  1607. #endif // GREIS_ENABLE
  1608. #ifdef ITRAX_ENABLE
  1609. &driver_italk,
  1610. #endif // ITRAX_ENABLE
  1611. #ifdef ONCORE_ENABLE
  1612. &driver_oncore,
  1613. #endif // ONCORE_ENABLE
  1614. #ifdef NAVCOM_ENABLE
  1615. &driver_navcom,
  1616. #endif // NAVCOM_ENABLE
  1617. #ifdef SIRF_ENABLE
  1618. &driver_sirf,
  1619. #endif // SIRF_ENABLE
  1620. #ifdef SKYTRAQ_ENABLE
  1621. &driver_skytraq,
  1622. #endif // SKYTRAQ_ENABLE
  1623. #ifdef SUPERSTAR2_ENABLE
  1624. &driver_superstar2,
  1625. #endif // SUPERSTAR2_ENABLE
  1626. #ifdef TSIP_ENABLE
  1627. &driver_tsip,
  1628. #endif // TSIP_ENABLE
  1629. #ifdef ISYNC_ENABLE
  1630. &driver_isync,
  1631. #endif // ISYNC_ENABLE
  1632. #ifdef UBLOX_ENABLE
  1633. &driver_ubx,
  1634. #endif // UBLOX_ENABLE
  1635. #ifdef ZODIAC_ENABLE
  1636. &driver_zodiac,
  1637. #endif // ZODIAC_ENABLE
  1638. #ifdef NMEA2000_ENABLE
  1639. &driver_nmea2000,
  1640. #endif // NMEA2000_ENABLE
  1641. #ifdef RTCM104V2_ENABLE
  1642. &driver_rtcm104v2,
  1643. #endif // RTCM104V2_ENABLE
  1644. #ifdef RTCM104V3_ENABLE
  1645. &driver_rtcm104v3,
  1646. #endif // RTCM104V3_ENABLE
  1647. #ifdef GARMINTXT_ENABLE
  1648. &driver_garmintxt,
  1649. #endif // GARMINTXT_ENABLE
  1650. &driver_json_passthrough,
  1651. &driver_pps,
  1652. NULL,
  1653. };
  1654. const struct gps_type_t **gpsd_drivers = &gpsd_driver_array[0];
  1655. // vim: set expandtab shiftwidth=4