libgps_json.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. /****************************************************************************
  2. NAME
  3. libgps_json.c - deserialize gpsd data coming from the server
  4. DESCRIPTION
  5. This module uses the generic JSON parser to get data from JSON
  6. representations to libgps structures.
  7. PERMISSIONS
  8. Written by Eric S. Raymond, 2009
  9. This file is Copyright (c) 2009-2018 by the GPSD project
  10. SPDX-License-Identifier: BSD-2-clause
  11. ***************************************************************************/
  12. /* isfinite() needs _POSIX_C_SOURCE >= 200112L
  13. * isnan(+Inf) is false, isfinite(+Inf) is false
  14. * use isfinite() to make sure a float is valid
  15. */
  16. #include "gpsd_config.h" /* must be before all includes */
  17. #include <math.h>
  18. #include <stdbool.h>
  19. #include <stddef.h>
  20. #include <string.h>
  21. #include "gpsd.h"
  22. #include "strfuncs.h"
  23. #ifdef SOCKET_EXPORT_ENABLE
  24. #include "gps_json.h"
  25. #include "timespec.h"
  26. static int json_tpv_read(const char *buf, struct gps_data_t *gpsdata,
  27. const char **endptr)
  28. {
  29. int leapseconds; /* FIXME, unused... */
  30. int ret;
  31. const struct json_attr_t json_attrs_1[] = {
  32. /* *INDENT-OFF* */
  33. {"class", t_check, .dflt.check = "TPV"},
  34. {"device", t_string, .addr.string = gpsdata->dev.path,
  35. .len = sizeof(gpsdata->dev.path)},
  36. {"time", t_time, .addr.ts = &gpsdata->fix.time,
  37. .dflt.ts = {0, 0}},
  38. {"leapseconds", t_integer, .addr.integer = &leapseconds,
  39. .dflt.integer = 0},
  40. {"ept", t_real, .addr.real = &gpsdata->fix.ept,
  41. .dflt.real = NAN},
  42. {"lon", t_real, .addr.real = &gpsdata->fix.longitude,
  43. .dflt.real = NAN},
  44. {"lat", t_real, .addr.real = &gpsdata->fix.latitude,
  45. .dflt.real = NAN},
  46. {"altHAE", t_real, .addr.real = &gpsdata->fix.altHAE,
  47. .dflt.real = NAN},
  48. {"altMSL", t_real, .addr.real = &gpsdata->fix.altMSL,
  49. .dflt.real = NAN},
  50. {"datum", t_string, .addr.string = gpsdata->fix.datum,
  51. .len = sizeof(gpsdata->fix.datum)},
  52. {"epc", t_real, .addr.real = &gpsdata->fix.epc,
  53. .dflt.real = NAN},
  54. {"epd", t_real, .addr.real = &gpsdata->fix.epd,
  55. .dflt.real = NAN},
  56. {"eph", t_real, .addr.real = &gpsdata->fix.eph,
  57. .dflt.real = NAN},
  58. {"eps", t_real, .addr.real = &gpsdata->fix.eps,
  59. .dflt.real = NAN},
  60. {"epx", t_real, .addr.real = &gpsdata->fix.epx,
  61. .dflt.real = NAN},
  62. {"epy", t_real, .addr.real = &gpsdata->fix.epy,
  63. .dflt.real = NAN},
  64. {"epv", t_real, .addr.real = &gpsdata->fix.epv,
  65. .dflt.real = NAN},
  66. {"track", t_real, .addr.real = &gpsdata->fix.track,
  67. .dflt.real = NAN},
  68. {"magtrack", t_real, .addr.real = &gpsdata->fix.magnetic_track,
  69. .dflt.real = NAN},
  70. {"magvar", t_real, .addr.real = &gpsdata->fix.magnetic_var,
  71. .dflt.real = NAN},
  72. {"speed", t_real, .addr.real = &gpsdata->fix.speed,
  73. .dflt.real = NAN},
  74. {"climb", t_real, .addr.real = &gpsdata->fix.climb,
  75. .dflt.real = NAN},
  76. {"ecefx", t_real, .addr.real = &gpsdata->fix.ecef.x,
  77. .dflt.real = NAN},
  78. {"ecefy", t_real, .addr.real = &gpsdata->fix.ecef.y,
  79. .dflt.real = NAN},
  80. {"ecefz", t_real, .addr.real = &gpsdata->fix.ecef.z,
  81. .dflt.real = NAN},
  82. {"ecefvx", t_real, .addr.real = &gpsdata->fix.ecef.vx,
  83. .dflt.real = NAN},
  84. {"ecefvy", t_real, .addr.real = &gpsdata->fix.ecef.vy,
  85. .dflt.real = NAN},
  86. {"ecefvz", t_real, .addr.real = &gpsdata->fix.ecef.vz,
  87. .dflt.real = NAN},
  88. {"ecefpAcc", t_real, .addr.real = &gpsdata->fix.ecef.vAcc,
  89. .dflt.real = NAN},
  90. {"ecefvAcc", t_real, .addr.real = &gpsdata->fix.ecef.pAcc,
  91. .dflt.real = NAN},
  92. {"mode", t_integer, .addr.integer = &gpsdata->fix.mode,
  93. .dflt.integer = MODE_NOT_SEEN},
  94. {"sep", t_real, .addr.real = &gpsdata->fix.sep,
  95. .dflt.real = NAN},
  96. {"status", t_integer, .addr.integer = &gpsdata->status,
  97. .dflt.integer = STATUS_FIX},
  98. {"relN", t_real, .addr.real = &gpsdata->fix.NED.relPosN,
  99. .dflt.real = NAN},
  100. {"relE", t_real, .addr.real = &gpsdata->fix.NED.relPosE,
  101. .dflt.real = NAN},
  102. {"relD", t_real, .addr.real = &gpsdata->fix.NED.relPosD,
  103. .dflt.real = NAN},
  104. {"velN", t_real, .addr.real = &gpsdata->fix.NED.relPosN,
  105. .dflt.real = NAN},
  106. {"velE", t_real, .addr.real = &gpsdata->fix.NED.relPosE,
  107. .dflt.real = NAN},
  108. {"velD", t_real, .addr.real = &gpsdata->fix.NED.relPosD,
  109. .dflt.real = NAN},
  110. {"geoidSep", t_real, .addr.real = &gpsdata->fix.geoid_sep,
  111. .dflt.real = NAN},
  112. {"depth", t_real, .addr.real = &gpsdata->fix.depth,
  113. .dflt.real = NAN},
  114. {"dgpsAge", t_real, .addr.real = &gpsdata->fix.dgps_age,
  115. .dflt.real = NAN},
  116. {"dgpsSta", t_integer, .addr.integer = &gpsdata->fix.dgps_station,
  117. .dflt.integer = -1},
  118. // ignore unkown keys, for cross-version compatibility
  119. {"", t_ignore},
  120. {NULL},
  121. /* *INDENT-ON* */
  122. };
  123. ret = json_read_object(buf, json_attrs_1, endptr);
  124. return ret;
  125. }
  126. static int json_noise_read(const char *buf, struct gps_data_t *gpsdata,
  127. const char **endptr)
  128. {
  129. int ret;
  130. const struct json_attr_t json_attrs_1[] = {
  131. /* *INDENT-OFF* */
  132. {"class", t_check, .dflt.check = "GST"},
  133. {"device", t_string, .addr.string = gpsdata->dev.path,
  134. .len = sizeof(gpsdata->dev.path)},
  135. {"time", t_time, .addr.ts = &gpsdata->gst.utctime,
  136. .dflt.ts = {0, 0}},
  137. {"rms", t_real, .addr.real = &gpsdata->gst.rms_deviation,
  138. .dflt.real = NAN},
  139. {"major", t_real, .addr.real = &gpsdata->gst.smajor_deviation,
  140. .dflt.real = NAN},
  141. {"minor", t_real, .addr.real = &gpsdata->gst.sminor_deviation,
  142. .dflt.real = NAN},
  143. {"orient", t_real, .addr.real = &gpsdata->gst.smajor_orientation,
  144. .dflt.real = NAN},
  145. {"lat", t_real, .addr.real = &gpsdata->gst.lat_err_deviation,
  146. .dflt.real = NAN},
  147. {"lon", t_real, .addr.real = &gpsdata->gst.lon_err_deviation,
  148. .dflt.real = NAN},
  149. {"alt", t_real, .addr.real = &gpsdata->gst.alt_err_deviation,
  150. .dflt.real = NAN},
  151. {NULL},
  152. /* *INDENT-ON* */
  153. };
  154. ret = json_read_object(buf, json_attrs_1, endptr);
  155. return ret;
  156. }
  157. /* decode a RAW messages into gpsdata.raw */
  158. static int json_raw_read(const char *buf, struct gps_data_t *gpsdata,
  159. const char **endptr)
  160. {
  161. int measurements;
  162. double mtime_s, mtime_ns;
  163. const struct json_attr_t json_attrs_meas[] = {
  164. /* *INDENT-OFF* */
  165. {"gnssid", t_ubyte, STRUCTOBJECT(struct meas_t, gnssid)},
  166. {"svid", t_ubyte, STRUCTOBJECT(struct meas_t, svid)},
  167. {"sigid", t_ubyte, STRUCTOBJECT(struct meas_t, sigid),
  168. .dflt.ubyte = 0},
  169. {"snr", t_ubyte, STRUCTOBJECT(struct meas_t, snr)},
  170. {"freqid", t_ubyte, STRUCTOBJECT(struct meas_t, freqid),
  171. .dflt.ubyte = 0},
  172. {"obs", t_string, STRUCTOBJECT(struct meas_t, obs_code),
  173. .len = sizeof(gpsdata->raw.meas[0].obs_code)},
  174. {"lli", t_ubyte, STRUCTOBJECT(struct meas_t, lli),
  175. .dflt.ubyte = 0},
  176. {"locktime", t_uinteger, STRUCTOBJECT(struct meas_t, locktime),
  177. .dflt.uinteger = 0},
  178. {"carrierphase", t_real, STRUCTOBJECT(struct meas_t, carrierphase),
  179. .dflt.real = NAN},
  180. {"pseudorange", t_real, STRUCTOBJECT(struct meas_t, pseudorange),
  181. .dflt.real = NAN},
  182. {"doppler", t_real, STRUCTOBJECT(struct meas_t, doppler),
  183. .dflt.real = NAN},
  184. {"c2c", t_real, STRUCTOBJECT(struct meas_t, c2c),
  185. .dflt.real = NAN},
  186. {"l2c", t_real, STRUCTOBJECT(struct meas_t, l2c),
  187. .dflt.real = NAN},
  188. /* *INDENT-ON* */
  189. {NULL},
  190. };
  191. const struct json_attr_t json_attrs_raw[] = {
  192. /* *INDENT-OFF* */
  193. {"class", t_check, .dflt.check = "RAW"},
  194. {"device", t_string, .addr.string = gpsdata->dev.path,
  195. .len = sizeof(gpsdata->dev.path)},
  196. {"time", t_real, .addr.real = &mtime_s,
  197. .dflt.real = NAN},
  198. {"nsec", t_real, .addr.real = &mtime_ns,
  199. .dflt.real = NAN},
  200. {"rawdata", t_array, STRUCTARRAY(gpsdata->raw.meas,
  201. json_attrs_meas, &measurements)},
  202. {NULL},
  203. /* *INDENT-ON* */
  204. };
  205. int status;
  206. memset(&gpsdata->raw, 0, sizeof(gpsdata->raw));
  207. status = json_read_object(buf, json_attrs_raw, endptr);
  208. if (status != 0)
  209. return status;
  210. if (0 == isfinite(mtime_s) || 0 == isfinite(mtime_ns))
  211. return status;
  212. gpsdata->raw.mtime.tv_sec = (time_t)mtime_s;
  213. gpsdata->raw.mtime.tv_nsec = (long)mtime_ns;
  214. return 0;
  215. }
  216. static int json_sky_read(const char *buf, struct gps_data_t *gpsdata,
  217. const char **endptr)
  218. {
  219. const struct json_attr_t json_attrs_satellites[] = {
  220. /* *INDENT-OFF* */
  221. {"PRN", t_short, STRUCTOBJECT(struct satellite_t, PRN)},
  222. {"el", t_real, STRUCTOBJECT(struct satellite_t, elevation),
  223. .dflt.real = NAN},
  224. {"az", t_real, STRUCTOBJECT(struct satellite_t, azimuth),
  225. .dflt.real = NAN},
  226. {"ss", t_real, STRUCTOBJECT(struct satellite_t, ss),
  227. .dflt.real = NAN},
  228. {"used", t_boolean, STRUCTOBJECT(struct satellite_t, used)},
  229. {"gnssid", t_ubyte, STRUCTOBJECT(struct satellite_t, gnssid)},
  230. {"svid", t_ubyte, STRUCTOBJECT(struct satellite_t, svid)},
  231. {"sigid", t_ubyte, STRUCTOBJECT(struct satellite_t, sigid)},
  232. {"freqid", t_byte, STRUCTOBJECT(struct satellite_t, freqid),
  233. .dflt.byte = -1},
  234. {"health", t_ubyte, STRUCTOBJECT(struct satellite_t, health),
  235. .dflt.ubyte = SAT_HEALTH_UNK},
  236. /* *INDENT-ON* */
  237. {NULL},
  238. };
  239. const struct json_attr_t json_attrs_2[] = {
  240. /* *INDENT-OFF* */
  241. {"class", t_check, .dflt.check = "SKY"},
  242. {"device", t_string, .addr.string = gpsdata->dev.path,
  243. .len = sizeof(gpsdata->dev.path)},
  244. {"time", t_time, .addr.ts = &gpsdata->skyview_time,
  245. .dflt.ts = {0, 0}},
  246. {"hdop", t_real, .addr.real = &gpsdata->dop.hdop,
  247. .dflt.real = NAN},
  248. {"xdop", t_real, .addr.real = &gpsdata->dop.xdop,
  249. .dflt.real = NAN},
  250. {"ydop", t_real, .addr.real = &gpsdata->dop.ydop,
  251. .dflt.real = NAN},
  252. {"vdop", t_real, .addr.real = &gpsdata->dop.vdop,
  253. .dflt.real = NAN},
  254. {"tdop", t_real, .addr.real = &gpsdata->dop.tdop,
  255. .dflt.real = NAN},
  256. {"pdop", t_real, .addr.real = &gpsdata->dop.pdop,
  257. .dflt.real = NAN},
  258. {"gdop", t_real, .addr.real = &gpsdata->dop.gdop,
  259. .dflt.real = NAN},
  260. {"satellites", t_array,
  261. STRUCTARRAY(gpsdata->skyview,
  262. json_attrs_satellites,
  263. &gpsdata->satellites_visible)},
  264. {NULL},
  265. /* *INDENT-ON* */
  266. };
  267. int status, i;
  268. memset(&gpsdata->skyview, 0, sizeof(gpsdata->skyview));
  269. status = json_read_object(buf, json_attrs_2, endptr);
  270. if (status != 0)
  271. return status;
  272. gpsdata->satellites_used = 0;
  273. gpsdata->satellites_visible = 0;
  274. for (i = 0; i < MAXCHANNELS; i++) {
  275. if(gpsdata->skyview[i].PRN > 0)
  276. gpsdata->satellites_visible++;
  277. if (gpsdata->skyview[i].used) {
  278. gpsdata->satellites_used++;
  279. }
  280. }
  281. return 0;
  282. }
  283. static int json_att_read(const char *buf, struct gps_data_t *gpsdata,
  284. const char **endptr)
  285. {
  286. const struct json_attr_t json_attrs_1[] = {
  287. /* *INDENT-OFF* */
  288. {"class", t_check, .dflt.check = "ATT"},
  289. {"device", t_string, .addr.string = gpsdata->dev.path,
  290. .len = sizeof(gpsdata->dev.path)},
  291. {"heading", t_real, .addr.real = &gpsdata->attitude.heading,
  292. .dflt.real = NAN},
  293. {"mag_st", t_character, .addr.character = &gpsdata->attitude.mag_st},
  294. {"pitch", t_real, .addr.real = &gpsdata->attitude.pitch,
  295. .dflt.real = NAN},
  296. {"pitch_st", t_character, .addr.character = &gpsdata->attitude.pitch_st},
  297. {"roll", t_real, .addr.real = &gpsdata->attitude.roll,
  298. .dflt.real = NAN},
  299. {"roll_st", t_character, .addr.character = &gpsdata->attitude.roll_st},
  300. {"yaw", t_real, .addr.real = &gpsdata->attitude.yaw,
  301. .dflt.real = NAN},
  302. {"yaw_st", t_character, .addr.character = &gpsdata->attitude.yaw_st},
  303. {"dip", t_real, .addr.real = &gpsdata->attitude.dip,
  304. .dflt.real = NAN},
  305. {"mag_len", t_real, .addr.real = &gpsdata->attitude.mag_len,
  306. .dflt.real = NAN},
  307. {"mag_x", t_real, .addr.real = &gpsdata->attitude.mag_x,
  308. .dflt.real = NAN},
  309. {"mag_y", t_real, .addr.real = &gpsdata->attitude.mag_y,
  310. .dflt.real = NAN},
  311. {"mag_z", t_real, .addr.real = &gpsdata->attitude.mag_z,
  312. .dflt.real = NAN},
  313. {"acc_len", t_real, .addr.real = &gpsdata->attitude.acc_len,
  314. .dflt.real = NAN},
  315. {"acc_x", t_real, .addr.real = &gpsdata->attitude.acc_x,
  316. .dflt.real = NAN},
  317. {"acc_y", t_real, .addr.real = &gpsdata->attitude.acc_y,
  318. .dflt.real = NAN},
  319. {"acc_z", t_real, .addr.real = &gpsdata->attitude.acc_z,
  320. .dflt.real = NAN},
  321. {"gyro_x", t_real, .addr.real = &gpsdata->attitude.gyro_x,
  322. .dflt.real = NAN},
  323. {"gyro_y", t_real, .addr.real = &gpsdata->attitude.gyro_y,
  324. .dflt.real = NAN},
  325. {"temp", t_real, .addr.real = &gpsdata->attitude.temp,
  326. .dflt.real = NAN},
  327. {"depth", t_real, .addr.real = &gpsdata->attitude.depth,
  328. .dflt.real = NAN},
  329. {NULL},
  330. /* *INDENT-ON* */
  331. };
  332. return json_read_object(buf, json_attrs_1, endptr);
  333. }
  334. static int json_devicelist_read(const char *buf, struct gps_data_t *gpsdata,
  335. const char **endptr)
  336. {
  337. const struct json_attr_t json_attrs_subdevices[] = {
  338. /* *INDENT-OFF* */
  339. {"class", t_check, .dflt.check = "DEVICE"},
  340. {"path", t_string, STRUCTOBJECT(struct devconfig_t, path),
  341. .len = sizeof(gpsdata->devices.list[0].path)},
  342. {"activated", t_time, STRUCTOBJECT(struct devconfig_t, activated)},
  343. {"activated", t_real, STRUCTOBJECT(struct devconfig_t, activated)},
  344. {"flags", t_integer, STRUCTOBJECT(struct devconfig_t, flags)},
  345. {"driver", t_string, STRUCTOBJECT(struct devconfig_t, driver),
  346. .len = sizeof(gpsdata->devices.list[0].driver)},
  347. {"hexdata", t_string, STRUCTOBJECT(struct devconfig_t, hexdata),
  348. .len = sizeof(gpsdata->devices.list[0].hexdata)},
  349. {"subtype", t_string, STRUCTOBJECT(struct devconfig_t, subtype),
  350. .len = sizeof(gpsdata->devices.list[0].subtype)},
  351. {"subtype1", t_string, STRUCTOBJECT(struct devconfig_t, subtype1),
  352. .len = sizeof(gpsdata->devices.list[0].subtype1)},
  353. {"native", t_integer, STRUCTOBJECT(struct devconfig_t, driver_mode),
  354. .dflt.integer = -1},
  355. {"bps", t_uinteger, STRUCTOBJECT(struct devconfig_t, baudrate),
  356. .dflt.uinteger = DEVDEFAULT_BPS},
  357. {"parity", t_character, STRUCTOBJECT(struct devconfig_t, parity),
  358. .dflt.character = DEVDEFAULT_PARITY},
  359. {"stopbits", t_uinteger, STRUCTOBJECT(struct devconfig_t, stopbits),
  360. .dflt.integer = DEVDEFAULT_STOPBITS},
  361. {"cycle", t_real, STRUCTOBJECT(struct devconfig_t, cycle),
  362. .dflt.real = NAN},
  363. {"mincycle", t_real, STRUCTOBJECT(struct devconfig_t, mincycle),
  364. .dflt.real = NAN},
  365. // ignore unkown keys, for cross-version compatibility
  366. {"", t_ignore},
  367. {NULL},
  368. /* *INDENT-ON* */
  369. };
  370. const struct json_attr_t json_attrs_devices[] = {
  371. {"class", t_check,.dflt.check = "DEVICES"},
  372. {"devices", t_array, STRUCTARRAY(gpsdata->devices.list,
  373. json_attrs_subdevices,
  374. &gpsdata->devices.ndevices)},
  375. {NULL},
  376. };
  377. int status;
  378. memset(&gpsdata->devices, 0, sizeof(gpsdata->devices));
  379. status = json_read_object(buf, json_attrs_devices, endptr);
  380. if (status != 0) {
  381. return status;
  382. }
  383. (void)clock_gettime(CLOCK_REALTIME, &gpsdata->devices.time);
  384. return 0;
  385. }
  386. static int json_version_read(const char *buf, struct gps_data_t *gpsdata,
  387. const char **endptr)
  388. {
  389. const struct json_attr_t json_attrs_version[] = {
  390. /* *INDENT-OFF* */
  391. {"class", t_check, .dflt.check = "VERSION"},
  392. {"release", t_string, .addr.string = gpsdata->version.release,
  393. .len = sizeof(gpsdata->version.release)},
  394. {"rev", t_string, .addr.string = gpsdata->version.rev,
  395. .len = sizeof(gpsdata->version.rev)},
  396. {"proto_major", t_integer, .addr.integer = &gpsdata->version.proto_major},
  397. {"proto_minor", t_integer, .addr.integer = &gpsdata->version.proto_minor},
  398. {"remote", t_string, .addr.string = gpsdata->version.remote,
  399. .len = sizeof(gpsdata->version.remote)},
  400. {NULL},
  401. /* *INDENT-ON* */
  402. };
  403. int status;
  404. memset(&gpsdata->version, 0, sizeof(gpsdata->version));
  405. status = json_read_object(buf, json_attrs_version, endptr);
  406. return status;
  407. }
  408. static int json_error_read(const char *buf, struct gps_data_t *gpsdata,
  409. const char **endptr)
  410. {
  411. const struct json_attr_t json_attrs_error[] = {
  412. /* *INDENT-OFF* */
  413. {"class", t_check, .dflt.check = "ERROR"},
  414. {"message", t_string, .addr.string = gpsdata->error,
  415. .len = sizeof(gpsdata->error)},
  416. {NULL},
  417. /* *INDENT-ON* */
  418. };
  419. int status;
  420. memset(&gpsdata->error, 0, sizeof(gpsdata->error));
  421. status = json_read_object(buf, json_attrs_error, endptr);
  422. if (status != 0)
  423. return status;
  424. return status;
  425. }
  426. int json_toff_read(const char *buf, struct gps_data_t *gpsdata,
  427. const char **endptr)
  428. {
  429. int real_sec = 0, real_nsec = 0, clock_sec = 0, clock_nsec = 0;
  430. const struct json_attr_t json_attrs_toff[] = {
  431. /* *INDENT-OFF* */
  432. {"class", t_check, .dflt.check = "TOFF"},
  433. {"device", t_string, .addr.string = gpsdata->dev.path,
  434. .len = sizeof(gpsdata->dev.path)},
  435. {"real_sec", t_integer, .addr.integer = &real_sec,
  436. .dflt.integer = 0},
  437. {"real_nsec", t_integer, .addr.integer = &real_nsec,
  438. .dflt.integer = 0},
  439. {"clock_sec", t_integer, .addr.integer = &clock_sec,
  440. .dflt.integer = 0},
  441. {"clock_nsec",t_integer, .addr.integer = &clock_nsec,
  442. .dflt.integer = 0},
  443. {NULL},
  444. /* *INDENT-ON* */
  445. };
  446. int status;
  447. memset(&gpsdata->toff, 0, sizeof(gpsdata->toff));
  448. status = json_read_object(buf, json_attrs_toff, endptr);
  449. gpsdata->toff.real.tv_sec = (time_t)real_sec;
  450. gpsdata->toff.real.tv_nsec = (long)real_nsec;
  451. gpsdata->toff.clock.tv_sec = (time_t)clock_sec;
  452. gpsdata->toff.clock.tv_nsec = (long)clock_nsec;
  453. if (status != 0)
  454. return status;
  455. return status;
  456. }
  457. int json_pps_read(const char *buf, struct gps_data_t *gpsdata,
  458. const char **endptr)
  459. {
  460. int real_sec = 0, real_nsec = 0, clock_sec = 0, clock_nsec = 0, precision=0;
  461. int qErr = 0;
  462. const struct json_attr_t json_attrs_pps[] = {
  463. /* *INDENT-OFF* */
  464. {"class", t_check, .dflt.check = "PPS"},
  465. {"device", t_string, .addr.string = gpsdata->dev.path,
  466. .len = sizeof(gpsdata->dev.path)},
  467. {"real_sec", t_integer, .addr.integer = &real_sec,
  468. .dflt.integer = 0},
  469. {"real_nsec", t_integer, .addr.integer = &real_nsec,
  470. .dflt.integer = 0},
  471. {"clock_sec", t_integer, .addr.integer = &clock_sec,
  472. .dflt.integer = 0},
  473. {"clock_nsec",t_integer, .addr.integer = &clock_nsec,
  474. .dflt.integer = 0},
  475. {"precision", t_integer, .addr.integer = &precision,
  476. .dflt.integer = 0},
  477. {"qErr", t_integer, .addr.integer = &qErr,
  478. .dflt.integer = 0},
  479. {NULL},
  480. /* *INDENT-ON* */
  481. };
  482. int status;
  483. memset(&gpsdata->pps, 0, sizeof(gpsdata->pps));
  484. status = json_read_object(buf, json_attrs_pps, endptr);
  485. /* This is good until GPS are more than nanosec accurate */
  486. gpsdata->pps.real.tv_sec = (time_t)real_sec;
  487. gpsdata->pps.real.tv_nsec = (long)real_nsec;
  488. gpsdata->pps.clock.tv_sec = (time_t)clock_sec;
  489. gpsdata->pps.clock.tv_nsec = (long)clock_nsec;
  490. // hope qErr fits in int
  491. gpsdata->qErr = (long)qErr;
  492. /* FIXME: precision is currently parsed but discarded */
  493. return status;
  494. }
  495. int json_oscillator_read(const char *buf, struct gps_data_t *gpsdata,
  496. const char **endptr)
  497. {
  498. bool running = false, reference = false, disciplined = false;
  499. int delta = 0;
  500. const struct json_attr_t json_attrs_osc[] = {
  501. /* *INDENT-OFF* */
  502. {"class", t_check, .dflt.check = "OSC"},
  503. {"device", t_string, .addr.string = gpsdata->dev.path,
  504. .len = sizeof(gpsdata->dev.path)},
  505. {"running", t_boolean, .addr.boolean = &running,
  506. .dflt.boolean = false},
  507. {"reference", t_boolean, .addr.boolean = &reference,
  508. .dflt.boolean = false},
  509. {"disciplined", t_boolean, .addr.boolean = &disciplined,
  510. .dflt.boolean = false},
  511. {"delta", t_integer, .addr.integer = &delta,
  512. .dflt.integer = 0},
  513. {NULL},
  514. /* *INDENT-ON* */
  515. };
  516. int status;
  517. memset(&gpsdata->osc, 0, sizeof(gpsdata->osc));
  518. status = json_read_object(buf, json_attrs_osc, endptr);
  519. gpsdata->osc.running = running;
  520. gpsdata->osc.reference = reference;
  521. gpsdata->osc.disciplined = disciplined;
  522. gpsdata->osc.delta = delta;
  523. return status;
  524. }
  525. // Test for JSON read status values that should be treated as a go-ahead
  526. // for further processing. JSON_BADATTR - to allow JSON attributes uknown
  527. // to this version of the library, for forward compatibility, is an obvious
  528. // thing to go here.
  529. #define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  530. #define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  531. int libgps_json_unpack(const char *buf,
  532. struct gps_data_t *gpsdata, const char **end)
  533. /* the only entry point - unpack a JSON object into gpsdata_t substructures */
  534. {
  535. int status;
  536. char *classtag = strstr(buf, "\"class\":");
  537. if (classtag == NULL)
  538. return -1;
  539. if (str_starts_with(classtag, "\"class\":\"TPV\"")) {
  540. status = json_tpv_read(buf, gpsdata, end);
  541. gpsdata->set = STATUS_SET;
  542. if (0 != gpsdata->fix.time.tv_sec)
  543. gpsdata->set |= TIME_SET;
  544. if (isfinite(gpsdata->fix.ept) != 0)
  545. gpsdata->set |= TIMERR_SET;
  546. if (isfinite(gpsdata->fix.longitude) != 0)
  547. gpsdata->set |= LATLON_SET;
  548. if (0 != isfinite(gpsdata->fix.altHAE) ||
  549. 0 != isfinite(gpsdata->fix.depth) ||
  550. 0 != isfinite(gpsdata->fix.altMSL))
  551. gpsdata->set |= ALTITUDE_SET;
  552. if (isfinite(gpsdata->fix.epx) != 0 && isfinite(gpsdata->fix.epy) != 0)
  553. gpsdata->set |= HERR_SET;
  554. if (isfinite(gpsdata->fix.epv) != 0)
  555. gpsdata->set |= VERR_SET;
  556. if (isfinite(gpsdata->fix.track) != 0)
  557. gpsdata->set |= TRACK_SET;
  558. if (0 != isfinite(gpsdata->fix.magnetic_track) ||
  559. 0 != isfinite(gpsdata->fix.magnetic_var))
  560. gpsdata->set |= MAGNETIC_TRACK_SET;
  561. if (isfinite(gpsdata->fix.speed) != 0)
  562. gpsdata->set |= SPEED_SET;
  563. if (isfinite(gpsdata->fix.climb) != 0)
  564. gpsdata->set |= CLIMB_SET;
  565. if (isfinite(gpsdata->fix.epd) != 0)
  566. gpsdata->set |= TRACKERR_SET;
  567. if (isfinite(gpsdata->fix.eps) != 0)
  568. gpsdata->set |= SPEEDERR_SET;
  569. if (isfinite(gpsdata->fix.epc) != 0)
  570. gpsdata->set |= CLIMBERR_SET;
  571. if (gpsdata->fix.mode != MODE_NOT_SEEN)
  572. gpsdata->set |= MODE_SET;
  573. return FILTER(status);
  574. } else if (str_starts_with(classtag, "\"class\":\"GST\"")) {
  575. status = json_noise_read(buf, gpsdata, end);
  576. if (PASS(status)) {
  577. gpsdata->set &= ~UNION_SET;
  578. gpsdata->set |= GST_SET;
  579. }
  580. return FILTER(status);
  581. } else if (str_starts_with(classtag, "\"class\":\"SKY\"")) {
  582. status = json_sky_read(buf, gpsdata, end);
  583. if (PASS(status))
  584. gpsdata->set |= SATELLITE_SET;
  585. return FILTER(status);
  586. } else if (str_starts_with(classtag, "\"class\":\"ATT\"")) {
  587. status = json_att_read(buf, gpsdata, end);
  588. if (PASS(status)) {
  589. gpsdata->set &= ~UNION_SET;
  590. gpsdata->set |= ATTITUDE_SET;
  591. }
  592. return FILTER(status);
  593. } else if (str_starts_with(classtag, "\"class\":\"DEVICES\"")) {
  594. status = json_devicelist_read(buf, gpsdata, end);
  595. if (PASS(status)) {
  596. gpsdata->set &= ~UNION_SET;
  597. gpsdata->set |= DEVICELIST_SET;
  598. }
  599. return FILTER(status);
  600. } else if (str_starts_with(classtag, "\"class\":\"DEVICE\"")) {
  601. status = json_device_read(buf, &gpsdata->dev, end);
  602. if (PASS(status))
  603. gpsdata->set |= DEVICE_SET;
  604. return FILTER(status);
  605. } else if (str_starts_with(classtag, "\"class\":\"WATCH\"")) {
  606. status = json_watch_read(buf, &gpsdata->policy, end);
  607. if (PASS(status)) {
  608. gpsdata->set &= ~UNION_SET;
  609. gpsdata->set |= POLICY_SET;
  610. }
  611. return FILTER(status);
  612. } else if (str_starts_with(classtag, "\"class\":\"VERSION\"")) {
  613. status = json_version_read(buf, gpsdata, end);
  614. if (status == 0) {
  615. gpsdata->set &= ~UNION_SET;
  616. gpsdata->set |= VERSION_SET;
  617. }
  618. return FILTER(status);
  619. #ifdef RTCM104V2_ENABLE
  620. } else if (str_starts_with(classtag, "\"class\":\"RTCM2\"")) {
  621. status = json_rtcm2_read(buf,
  622. gpsdata->dev.path, sizeof(gpsdata->dev.path),
  623. &gpsdata->rtcm2, end);
  624. if (PASS(status)) {
  625. gpsdata->set &= ~UNION_SET;
  626. gpsdata->set |= RTCM2_SET;
  627. }
  628. return FILTER(status);
  629. #endif /* RTCM104V2_ENABLE */
  630. #ifdef RTCM104V3_ENABLE
  631. } else if (str_starts_with(classtag, "\"class\":\"RTCM3\"")) {
  632. status = json_rtcm3_read(buf,
  633. gpsdata->dev.path, sizeof(gpsdata->dev.path),
  634. &gpsdata->rtcm3, end);
  635. if (PASS(status)) {
  636. gpsdata->set &= ~UNION_SET;
  637. gpsdata->set |= RTCM3_SET;
  638. }
  639. return FILTER(status);
  640. #endif /* RTCM104V3_ENABLE */
  641. #ifdef AIVDM_ENABLE
  642. } else if (str_starts_with(classtag, "\"class\":\"AIS\"")) {
  643. status = json_ais_read(buf,
  644. gpsdata->dev.path, sizeof(gpsdata->dev.path),
  645. &gpsdata->ais, end);
  646. if (PASS(status)) {
  647. gpsdata->set &= ~UNION_SET;
  648. gpsdata->set |= AIS_SET;
  649. }
  650. return FILTER(status);
  651. #endif /* AIVDM_ENABLE */
  652. } else if (str_starts_with(classtag, "\"class\":\"ERROR\"")) {
  653. status = json_error_read(buf, gpsdata, end);
  654. if (PASS(status)) {
  655. gpsdata->set &= ~UNION_SET;
  656. gpsdata->set |= ERROR_SET;
  657. }
  658. return FILTER(status);
  659. } else if (str_starts_with(classtag, "\"class\":\"TOFF\"")) {
  660. status = json_pps_read(buf, gpsdata, end);
  661. if (PASS(status)) {
  662. gpsdata->set &= ~UNION_SET;
  663. gpsdata->set |= TOFF_SET;
  664. }
  665. return FILTER(status);
  666. } else if (str_starts_with(classtag, "\"class\":\"PPS\"")) {
  667. status = json_pps_read(buf, gpsdata, end);
  668. if (PASS(status)) {
  669. gpsdata->set &= ~UNION_SET;
  670. gpsdata->set |= PPS_SET;
  671. }
  672. return FILTER(status);
  673. } else if (str_starts_with(classtag, "\"class\":\"OSC\"")) {
  674. status = json_oscillator_read(buf, gpsdata, end);
  675. if (PASS(status)) {
  676. gpsdata->set &= ~UNION_SET;
  677. gpsdata->set |= OSCILLATOR_SET;
  678. }
  679. return FILTER(status);
  680. } else if (str_starts_with(classtag, "\"class\":\"RAW\"")) {
  681. status = json_raw_read(buf, gpsdata, end);
  682. if (PASS(status)) {
  683. gpsdata->set &= ~UNION_SET;
  684. gpsdata->set |= RAW_SET;
  685. }
  686. return FILTER(status);
  687. } else
  688. return -1;
  689. }
  690. #endif /* SOCKET_EXPORT_ENABLE */
  691. /* libgps_json.c ends here */