You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rtcm3_json.c 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /****************************************************************************
  2. NAME
  3. rtcm3_json.c - deserialize RTCM3 JSON
  4. DESCRIPTION
  5. This module uses the generic JSON parser to get data from RTCM3
  6. representations to libgps structures.
  7. PERMISSIONS
  8. This file is Copyright (c) 2013-2018 by the GPSD project
  9. SPDX-License-Identifier: BSD-2-clause
  10. ***************************************************************************/
  11. #include "gpsd_config.h" /* must be before all includes */
  12. #include <stdio.h>
  13. #include <math.h>
  14. #include <string.h>
  15. #include <stddef.h>
  16. #include "gpsd.h"
  17. #ifdef SOCKET_EXPORT_ENABLE
  18. #include "gps_json.h"
  19. int json_rtcm3_read(const char *buf,
  20. char *path, size_t pathlen, struct rtcm3_t *rtcm3,
  21. const char **endptr)
  22. {
  23. static char *stringptrs[NITEMS(rtcm3->rtcmtypes.data)];
  24. static char stringstore[sizeof(rtcm3->rtcmtypes.data) * 2];
  25. static int stringcount;
  26. /* *INDENT-OFF* */
  27. #define RTCM3_HEADER \
  28. {"class", t_check, .dflt.check = "RTCM3"}, \
  29. {"type", t_uinteger, .addr.uinteger = &rtcm3->type}, \
  30. {"device", t_string, .addr.string = path, .len = pathlen}, \
  31. {"length", t_uinteger, .addr.uinteger = &rtcm3->length},
  32. int status = 0, satcount = 0;
  33. #define RTCM3FIELD(type, fld) STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  34. const struct json_attr_t rtcm1001_satellite[] = {
  35. {"ident", t_uinteger, RTCM3FIELD(1001, ident)},
  36. {"ind", t_uinteger, RTCM3FIELD(1001, L1.indicator)},
  37. {"prange", t_real, RTCM3FIELD(1001, L1.pseudorange)},
  38. {"delta", t_real, RTCM3FIELD(1001, L1.rangediff)},
  39. {"lockt", t_uinteger, RTCM3FIELD(1001, L1.locktime)},
  40. {NULL},
  41. };
  42. const struct json_attr_t rtcm1002_satellite[] = {
  43. {"ident", t_uinteger, RTCM3FIELD(1002, ident)},
  44. {"ind", t_uinteger, RTCM3FIELD(1002, L1.indicator)},
  45. {"prange", t_real, RTCM3FIELD(1002, L1.pseudorange)},
  46. {"delta", t_real, RTCM3FIELD(1002, L1.rangediff)},
  47. {"lockt", t_uinteger, RTCM3FIELD(1002, L1.locktime)},
  48. {"amb", t_uinteger, RTCM3FIELD(1002, L1.ambiguity)},
  49. {"CNR", t_real, RTCM3FIELD(1002, L1.CNR)},
  50. {NULL},
  51. };
  52. const struct json_attr_t rtcm1009_satellite[] = {
  53. {"ident", t_uinteger, RTCM3FIELD(1009, ident)},
  54. {"ind", t_uinteger, RTCM3FIELD(1009, L1.indicator)},
  55. {"channel", t_uinteger, RTCM3FIELD(1009, L1.channel)},
  56. {"prange", t_real, RTCM3FIELD(1009, L1.pseudorange)},
  57. {"delta", t_real, RTCM3FIELD(1009, L1.rangediff)},
  58. {"lockt", t_uinteger, RTCM3FIELD(1009, L1.locktime)},
  59. {NULL},
  60. };
  61. const struct json_attr_t rtcm1010_satellite[] = {
  62. {"ident", t_uinteger, RTCM3FIELD(1010, ident)},
  63. {"ind", t_uinteger, RTCM3FIELD(1010, L1.indicator)},
  64. {"channel", t_uinteger, RTCM3FIELD(1010, L1.channel)},
  65. {"prange", t_real, RTCM3FIELD(1010, L1.pseudorange)},
  66. {"delta", t_real, RTCM3FIELD(1010, L1.rangediff)},
  67. {"lockt", t_uinteger, RTCM3FIELD(1010, L1.locktime)},
  68. {"amb", t_uinteger, RTCM3FIELD(1010, L1.ambiguity)},
  69. {"CNR", t_real, RTCM3FIELD(1010, L1.CNR)},
  70. {NULL},
  71. };
  72. #undef RTCM3FIELD
  73. #define R1001 &rtcm3->rtcmtypes.rtcm3_1001.header
  74. const struct json_attr_t json_rtcm1001[] = {
  75. RTCM3_HEADER
  76. {"station_id", t_uinteger, .addr.uinteger = R1001.station_id},
  77. {"tow", t_uinteger, .addr.uinteger = (unsigned int *)R1001.tow},
  78. {"sync", t_boolean, .addr.boolean = R1001.sync},
  79. {"smoothing", t_boolean, .addr.boolean = R1001.smoothing},
  80. {"interval", t_uinteger, .addr.uinteger = R1001.interval},
  81. {"satellites", t_array, STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1001.rtk_data,
  82. rtcm1001_satellite, &satcount)},
  83. {NULL},
  84. };
  85. #undef R1001
  86. #define R1002 &rtcm3->rtcmtypes.rtcm3_1002.header
  87. const struct json_attr_t json_rtcm1002[] = {
  88. RTCM3_HEADER
  89. {"station_id", t_uinteger, .addr.uinteger = R1002.station_id},
  90. {"tow", t_uinteger, .addr.uinteger = (unsigned int *)R1002.tow},
  91. {"sync", t_boolean, .addr.boolean = R1002.sync},
  92. {"smoothing", t_boolean, .addr.boolean = R1002.smoothing},
  93. {"interval", t_uinteger, .addr.uinteger = R1002.interval},
  94. {"satellites", t_array, STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1002.rtk_data,
  95. rtcm1002_satellite, &satcount)},
  96. {NULL},
  97. };
  98. #undef R1002
  99. #define R1007 rtcm3->rtcmtypes.rtcm3_1007
  100. const struct json_attr_t json_rtcm1007[] = {
  101. RTCM3_HEADER
  102. {"station_id", t_uinteger, .addr.uinteger = &R1007.station_id},
  103. {"desc", t_string, .addr.string = R1007.descriptor,
  104. .len = sizeof(R1007.descriptor)},
  105. {"setup_id", t_uinteger, .addr.uinteger = &R1007.setup_id},
  106. {NULL},
  107. };
  108. #undef R1002
  109. #define R1008 rtcm3->rtcmtypes.rtcm3_1008
  110. const struct json_attr_t json_rtcm1008[] = {
  111. RTCM3_HEADER
  112. {"station_id", t_uinteger, .addr.uinteger = &R1008.station_id},
  113. {"desc", t_string, .addr.string = R1008.descriptor,
  114. .len = sizeof(R1008.descriptor)},
  115. {"setup_id", t_uinteger, .addr.uinteger = &R1008.setup_id},
  116. {"serial", t_string, .addr.string = R1008.serial,
  117. .len = sizeof(R1008.serial)},
  118. {NULL},
  119. };
  120. #undef R1008
  121. #define R1009 &rtcm3->rtcmtypes.rtcm3_1009.header
  122. const struct json_attr_t json_rtcm1009[] = {
  123. RTCM3_HEADER
  124. {"station_id", t_uinteger, .addr.uinteger = R1009.station_id},
  125. {"tow", t_uinteger, .addr.uinteger = (unsigned int *)R1009.tow},
  126. {"sync", t_boolean, .addr.boolean = R1009.sync},
  127. {"smoothing", t_boolean, .addr.boolean = R1009.smoothing},
  128. {"interval", t_uinteger, .addr.uinteger = R1009.interval},
  129. {"satellites", t_array, STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1009.rtk_data,
  130. rtcm1009_satellite, &satcount)},
  131. {NULL},
  132. };
  133. #undef R1010
  134. #define R1010 &rtcm3->rtcmtypes.rtcm3_1010.header
  135. const struct json_attr_t json_rtcm1010[] = {
  136. RTCM3_HEADER
  137. {"station_id", t_uinteger, .addr.uinteger = R1010.station_id},
  138. {"tow", t_uinteger, .addr.uinteger = (unsigned int *)R1010.tow},
  139. {"sync", t_boolean, .addr.boolean = R1010.sync},
  140. {"smoothing", t_boolean, .addr.boolean = R1010.smoothing},
  141. {"interval", t_uinteger, .addr.uinteger = R1010.interval},
  142. {"satellites", t_array, STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1010.rtk_data,
  143. rtcm1010_satellite, &satcount)},
  144. {NULL},
  145. };
  146. #undef R1010
  147. #define R1014 &rtcm3->rtcmtypes.rtcm3_1014
  148. const struct json_attr_t json_rtcm1014[] = {
  149. RTCM3_HEADER
  150. {"netid", t_uinteger, .addr.uinteger = R1014.network_id},
  151. {"subnetid", t_uinteger, .addr.uinteger = R1014.subnetwork_id},
  152. {"statcount", t_uinteger, .addr.uinteger = R1014.stationcount},
  153. {"master", t_uinteger, .addr.uinteger = R1014.master_id},
  154. {"aux", t_uinteger, .addr.uinteger = R1014.aux_id},
  155. {"lat", t_real, .addr.real = R1014.d_lat},
  156. {"lon", t_real, .addr.real = R1014.d_lon},
  157. {"alt", t_real, .addr.real = R1014.d_alt},
  158. {NULL},
  159. };
  160. #undef R1014
  161. #define R1033 rtcm3->rtcmtypes.rtcm3_1033
  162. const struct json_attr_t json_rtcm1033[] = {
  163. RTCM3_HEADER
  164. {"station_id", t_uinteger, .addr.uinteger = &R1033.station_id},
  165. {"desc", t_string, .addr.string = R1033.descriptor,
  166. .len = sizeof(R1033.descriptor)},
  167. {"setup_id", t_uinteger, .addr.uinteger = &R1033.setup_id},
  168. {"serial", t_string, .addr.string = R1033.serial,
  169. .len = sizeof(R1033.serial)},
  170. {"receiver", t_string, .addr.string = R1033.receiver,
  171. .len = sizeof(R1033.receiver)},
  172. {"firmware", t_string, .addr.string = R1033.firmware,
  173. .len = sizeof(R1033.firmware)},
  174. {NULL},
  175. };
  176. #undef R1033
  177. const struct json_attr_t json_rtcm3_fallback[] = {
  178. RTCM3_HEADER
  179. {"data", t_array, .addr.array.element_type = t_string,
  180. .addr.array.arr.strings.ptrs = stringptrs,
  181. .addr.array.arr.strings.store = stringstore,
  182. .addr.array.arr.strings.storelen = sizeof(stringstore),
  183. .addr.array.count = &stringcount,
  184. .addr.array.maxlen = NITEMS(stringptrs)},
  185. {NULL},
  186. };
  187. #undef RTCM3_HEADER
  188. /* *INDENT-ON* */
  189. memset(rtcm3, '\0', sizeof(struct rtcm3_t));
  190. if (strstr(buf, "\"type\":1001,") != NULL) {
  191. status = json_read_object(buf, json_rtcm1001, endptr);
  192. if (status == 0)
  193. rtcm3->rtcmtypes.rtcm3_1001.header.satcount = (unsigned short)satcount;
  194. } else if (strstr(buf, "\"type\":1002,") != NULL) {
  195. status = json_read_object(buf, json_rtcm1002, endptr);
  196. if (status == 0)
  197. rtcm3->rtcmtypes.rtcm3_1002.header.satcount = (unsigned short)satcount;
  198. } else if (strstr(buf, "\"type\":1007,") != NULL) {
  199. status = json_read_object(buf, json_rtcm1007, endptr);
  200. } else if (strstr(buf, "\"type\":1008,") != NULL) {
  201. status = json_read_object(buf, json_rtcm1008, endptr);
  202. } else if (strstr(buf, "\"type\":1009,") != NULL) {
  203. status = json_read_object(buf, json_rtcm1009, endptr);
  204. } else if (strstr(buf, "\"type\":1010,") != NULL) {
  205. status = json_read_object(buf, json_rtcm1010, endptr);
  206. } else if (strstr(buf, "\"type\":1014,") != NULL) {
  207. status = json_read_object(buf, json_rtcm1014, endptr);
  208. } else if (strstr(buf, "\"type\":1033,") != NULL) {
  209. status = json_read_object(buf, json_rtcm1033, endptr);
  210. } else {
  211. int n;
  212. status = json_read_object(buf, json_rtcm3_fallback, endptr);
  213. for (n = 0; n < NITEMS(rtcm3->rtcmtypes.data); n++) {
  214. if (n >= stringcount) {
  215. rtcm3->rtcmtypes.data[n] = '\0';
  216. } else {
  217. unsigned int u;
  218. int fldcount = sscanf(stringptrs[n], "0x%02x\n", &u);
  219. if (fldcount != 1)
  220. return JSON_ERR_MISC;
  221. else
  222. rtcm3->rtcmtypes.data[n] = (char)u;
  223. }
  224. }
  225. }
  226. return status;
  227. }
  228. #endif /* SOCKET_EXPORT_ENABLE */
  229. /* rtcm3_json.c ends here */