Coverage Report

Created: 2026-05-30 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpsd/gpsd-3.27.6~dev/libgps/ais_json.c
Line
Count
Source
1
/****************************************************************************
2
3
NAME
4
   ais_json.c - deserialize AIS JSON
5
6
DESCRIPTION
7
   This module uses the generic JSON parser to get data from AIS
8
representations to libgps structures.
9
10
This file is Copyright 2010 by the GPSD project
11
SPDX-License-Identifier: BSD-2-clause
12
***************************************************************************/
13
14
#include "../include/gpsd_config.h"  // must be before all includes
15
16
#include <stdio.h>
17
#include <string.h>
18
#include <stdbool.h>
19
#include <stdlib.h>
20
#include <stddef.h>
21
#include <time.h>
22
23
#include "../include/gps.h"
24
#include "../include/json.h"
25
#include "../include/libgps.h"
26
27
static void lenhex_unpack(const char *from,
28
                          size_t * plen, char *to, size_t maxlen)
29
0
{
30
0
    const char *colon = strchr(from, ':');
31
32
0
    *plen = (size_t)atoi(from);
33
0
    if (NULL != colon) {
34
0
        (void)gps_hexpack(colon + 1, (unsigned char *)to, maxlen);
35
0
    }
36
0
}
37
38
39
int json_ais_read(const char *buf,
40
                  char *path, size_t pathlen, struct ais_t *ais,
41
                  const char **endptr)
42
0
{
43
    // collected but not actually used yet
44
0
    bool scaled;
45
46
0
#define AIS_HEADER \
47
0
        {"class",          t_check,    .dflt.check = "AIS"}, \
48
0
        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
49
0
        {"device",         t_string,   .addr.string = path, \
50
0
                                          .len = pathlen}, \
51
0
        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
52
0
        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
53
0
                                          .dflt.boolean = false}, \
54
0
        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
55
56
0
#define AIS_TYPE6 \
57
0
        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
58
0
                                       .dflt.uinteger = 0},\
59
0
        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
60
0
                                       .dflt.uinteger = 0},\
61
0
        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
62
0
                                       .dflt.boolean = false},\
63
0
        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
64
0
                                       .dflt.uinteger = 0},\
65
0
        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
66
0
                                       .dflt.uinteger = 0},
67
0
#define AIS_TYPE8 \
68
0
        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
69
0
                                       .dflt.uinteger = 0},\
70
0
        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
71
0
                                       .dflt.uinteger = 0},
72
73
0
    int status;
74
75
0
#include "ais_json.i"           // JSON parser template structures
76
77
0
#undef AIS_HEADER
78
79
0
    memset(ais, '\0', sizeof(struct ais_t));
80
81
0
    if (NULL != strstr(buf, "\"type\":1,") ||
82
0
        NULL != strstr(buf, "\"type\":2,") ||
83
0
        NULL != strstr(buf, "\"type\":3,")) {
84
0
        status = json_read_object(buf, json_ais1, endptr);
85
0
    } else if (NULL != strstr(buf, "\"type\":4,") ||
86
0
               NULL != strstr(buf, "\"type\":11,")) {
87
0
        status = json_read_object(buf, json_ais4, endptr);
88
0
        if (0 == status) {
89
            // no need to set zeros, again.
90
            // ais->type4.year = AIS_YEAR_NOT_AVAILABLE;
91
            // ais->type4.month = AIS_MONTH_NOT_AVAILABLE;
92
            // ais->type4.day = AIS_DAY_NOT_AVAILABLE;
93
0
            ais->type4.hour = AIS_HOUR_NOT_AVAILABLE;
94
0
            ais->type4.minute = AIS_MINUTE_NOT_AVAILABLE;
95
0
            ais->type4.second = AIS_SECOND_NOT_AVAILABLE;
96
            /* We use %09u for the date to allow for dodgy years (>9999)
97
             * to go through. */
98
0
            (void)sscanf(timestamp, "%09u-%02u-%02uT%02u:%02u:%02uZ",
99
0
                         &ais->type4.year,
100
0
                         &ais->type4.month,
101
0
                         &ais->type4.day,
102
0
                         &ais->type4.hour,
103
0
                         &ais->type4.minute,
104
0
                         &ais->type4.second);
105
0
        }
106
0
    } else if (strstr(buf, "\"type\":5,") != NULL) {
107
0
        status = json_read_object(buf, json_ais5, endptr);
108
0
        if (status == 0) {
109
            // no need to set zeros, again.
110
            // ais->type5.month = AIS_MONTH_NOT_AVAILABLE;
111
            // ais->type5.day = AIS_DAY_NOT_AVAILABLE;
112
0
            ais->type5.hour = AIS_HOUR_NOT_AVAILABLE;
113
0
            ais->type5.minute = AIS_MINUTE_NOT_AVAILABLE;
114
0
            (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
115
0
                         &ais->type5.month,
116
0
                         &ais->type5.day,
117
0
                         &ais->type5.hour,
118
0
                         &ais->type5.minute);
119
0
        }
120
0
    } else if (strstr(buf, "\"type\":6,") != NULL) {
121
0
        bool structured = false;
122
0
        if (strstr(buf, "\"dac\":1,") != NULL) {
123
0
            if (strstr(buf, "\"fid\":12,") != NULL) {
124
0
                status = json_read_object(buf, json_ais6_fid12, endptr);
125
0
                if (status == 0) {
126
                    // no need to set zeros, again.
127
                    // ais->type6.dac1fid12.lmonth = AIS_MONTH_NOT_AVAILABLE;
128
                    // ais->type6.dac1fid12.lday = AIS_DAY_NOT_AVAILABLE;
129
0
                    ais->type6.dac1fid12.lhour = AIS_HOUR_NOT_AVAILABLE;
130
0
                    ais->type6.dac1fid12.lminute = AIS_MINUTE_NOT_AVAILABLE;
131
                    // ais->type6.dac1fid12.nmonth = AIS_MONTH_NOT_AVAILABLE;
132
                    // ais->type6.dac1fid12.nday = AIS_DAY_NOT_AVAILABLE;
133
0
                    ais->type6.dac1fid12.nhour = AIS_HOUR_NOT_AVAILABLE;
134
0
                    ais->type6.dac1fid12.nminute = AIS_MINUTE_NOT_AVAILABLE;
135
0
                    (void)sscanf(departure, "%02u-%02uT%02u:%02uZ",
136
0
                                 &ais->type6.dac1fid12.lmonth,
137
0
                                 &ais->type6.dac1fid12.lday,
138
0
                                 &ais->type6.dac1fid12.lhour,
139
0
                                 &ais->type6.dac1fid12.lminute);
140
0
                    (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
141
0
                                 &ais->type6.dac1fid12.nmonth,
142
0
                                 &ais->type6.dac1fid12.nday,
143
0
                                 &ais->type6.dac1fid12.nhour,
144
0
                                 &ais->type6.dac1fid12.nminute);
145
0
                }
146
0
                structured = true;
147
0
            }
148
0
            else if (strstr(buf, "\"fid\":15,") != NULL) {
149
0
                status = json_read_object(buf, json_ais6_fid15, endptr);
150
0
                structured = true;
151
0
            }
152
0
            else if (strstr(buf, "\"fid\":16,") != NULL) {
153
0
                status = json_read_object(buf, json_ais6_fid16, endptr);
154
0
                structured = true;
155
0
            }
156
0
            else if (strstr(buf, "\"fid\":18,") != NULL) {
157
0
                status = json_read_object(buf, json_ais6_fid18, endptr);
158
0
                if (status == 0) {
159
                    // no need to set zeros, again.
160
                    // ais->type6.dac1fid18.month = AIS_MONTH_NOT_AVAILABLE;
161
                    // ais->type6.dac1fid18.day = AIS_DAY_NOT_AVAILABLE;
162
0
                    ais->type6.dac1fid18.hour = AIS_HOUR_NOT_AVAILABLE;
163
0
                    ais->type6.dac1fid18.minute = AIS_MINUTE_NOT_AVAILABLE;
164
0
                    (void)sscanf(arrival, "%02u-%02uT%02u:%02uZ",
165
0
                                 &ais->type6.dac1fid18.month,
166
0
                                 &ais->type6.dac1fid18.day,
167
0
                                 &ais->type6.dac1fid18.hour,
168
0
                                 &ais->type6.dac1fid18.minute);
169
0
                }
170
0
                structured = true;
171
0
            }
172
0
            else if (strstr(buf, "\"fid\":20,") != NULL) {
173
0
                status = json_read_object(buf, json_ais6_fid20, endptr);
174
0
                if (status == 0) {
175
                    // no need to set zeros, again.
176
                    // ais->type6.dac1fid20.month = AIS_MONTH_NOT_AVAILABLE;
177
                    // ais->type6.dac1fid20.day = AIS_DAY_NOT_AVAILABLE;
178
0
                    ais->type6.dac1fid20.hour = AIS_HOUR_NOT_AVAILABLE;
179
0
                    ais->type6.dac1fid20.minute = AIS_MINUTE_NOT_AVAILABLE;
180
0
                    (void)sscanf(arrival, "%02u-%02uT%02u:%02uZ",
181
0
                                 &ais->type6.dac1fid20.month,
182
0
                                 &ais->type6.dac1fid20.day,
183
0
                                 &ais->type6.dac1fid20.hour,
184
0
                                 &ais->type6.dac1fid20.minute);
185
0
                }
186
0
                structured = true;
187
0
            }
188
0
            else if (strstr(buf, "\"fid\":25,") != NULL) {
189
0
                status = json_read_object(buf, json_ais6_fid25, endptr);
190
0
                structured = true;
191
0
            }
192
0
            else if (strstr(buf, "\"fid\":28,") != NULL) {
193
0
                status = json_read_object(buf, json_ais6_fid28, endptr);
194
0
                if (status == 0) {
195
                    // no need to set zeros, again.
196
                    // ais->type6.dac1fid28.month = AIS_MONTH_NOT_AVAILABLE;
197
                    // ais->type6.dac1fid28.day = AIS_DAY_NOT_AVAILABLE;
198
0
                    ais->type6.dac1fid28.hour = AIS_HOUR_NOT_AVAILABLE;
199
0
                    ais->type6.dac1fid28.minute = AIS_MINUTE_NOT_AVAILABLE;
200
0
                    (void)sscanf(start, "%02u-%02uT%02u:%02uZ",
201
0
                                 &ais->type6.dac1fid28.month,
202
0
                                 &ais->type6.dac1fid28.day,
203
0
                                 &ais->type6.dac1fid28.hour,
204
0
                                 &ais->type6.dac1fid28.minute);
205
0
                }
206
0
                structured = true;
207
0
            }
208
0
            else if (strstr(buf, "\"fid\":30,") != NULL) {
209
0
                status = json_read_object(buf, json_ais6_fid30, endptr);
210
0
                structured = true;
211
0
            }
212
0
            else if (strstr(buf, "\"fid\":32,") != NULL ||
213
0
                     strstr(buf, "\"fid\":14,") != NULL) {
214
0
                status = json_read_object(buf, json_ais6_fid32, endptr);
215
0
                structured = true;
216
0
            }
217
0
        }
218
0
        else if (strstr(buf, "\"dac\":235,") != NULL ||
219
0
                 strstr(buf, "\"dac\":250,") != NULL) {
220
0
            if (strstr(buf, "\"fid\":10,") != NULL) {
221
0
                status = json_read_object(buf, json_ais6_fid10, endptr);
222
0
                structured = true;
223
0
            }
224
0
        }
225
0
        else if (strstr(buf, "\"dac\":200,") != NULL) {
226
0
            if (strstr(buf, "\"fid\":21,") != NULL) {
227
0
                status = json_read_object(buf, json_ais6_fid21, endptr);
228
0
                structured = true;
229
0
                if (status == 0) {
230
                    // no need to set zeros, again.
231
                    // ais->type6.dac200fid21.month = AIS_MONTH_NOT_AVAILABLE;
232
                    // ais->type6.dac200fid21.day = AIS_DAY_NOT_AVAILABLE;
233
0
                    ais->type6.dac200fid21.hour = AIS_HOUR_NOT_AVAILABLE;
234
0
                    ais->type6.dac200fid21.minute = AIS_MINUTE_NOT_AVAILABLE;
235
0
                    (void)sscanf(eta, "%02u-%02uT%02u:%02u",
236
0
                                 &ais->type6.dac200fid21.month,
237
0
                                 &ais->type6.dac200fid21.day,
238
0
                                 &ais->type6.dac200fid21.hour,
239
0
                                 &ais->type6.dac200fid21.minute);
240
0
                }
241
0
            }
242
0
            else if (strstr(buf, "\"fid\":22,") != NULL) {
243
0
                status = json_read_object(buf, json_ais6_fid22, endptr);
244
0
                structured = true;
245
0
                if (status == 0) {
246
                    // no need to set zeros, again.
247
                    // ais->type6.dac200fid22.month = AIS_MONTH_NOT_AVAILABLE;
248
                    // ais->type6.dac200fid22.day = AIS_DAY_NOT_AVAILABLE;
249
0
                    ais->type6.dac200fid22.hour = AIS_HOUR_NOT_AVAILABLE;
250
0
                    ais->type6.dac200fid22.minute = AIS_MINUTE_NOT_AVAILABLE;
251
0
                    (void)sscanf(rta, "%02u-%02uT%02u:%02u",
252
0
                                 &ais->type6.dac200fid22.month,
253
0
                                 &ais->type6.dac200fid22.day,
254
0
                                 &ais->type6.dac200fid22.hour,
255
0
                                 &ais->type6.dac200fid22.minute);
256
0
                }
257
0
            }
258
0
            else if (strstr(buf, "\"fid\":55,") != NULL) {
259
0
                status = json_read_object(buf, json_ais6_fid55, endptr);
260
0
                structured = true;
261
0
            }
262
0
        }
263
0
        if (!structured) {
264
0
            status = json_read_object(buf, json_ais6, endptr);
265
0
            if (status == 0)
266
0
                lenhex_unpack(data, &ais->type6.bitcount,
267
0
                              ais->type6.bitdata, sizeof(ais->type6.bitdata));
268
0
        }
269
0
        ais->type6.structured = structured;
270
0
    } else if (strstr(buf, "\"type\":7,") != NULL
271
0
               || strstr(buf, "\"type\":13,") != NULL) {
272
0
        status = json_read_object(buf, json_ais7, endptr);
273
0
    } else if (strstr(buf, "\"type\":8,") != NULL) {
274
0
        bool structured = false;
275
0
        if (strstr(buf, "\"dac\":1,") != NULL) {
276
0
            if (strstr(buf, "\"fid\":11,") != NULL) {
277
0
                status = json_read_object(buf, json_ais8_fid11, endptr);
278
0
                if (status == 0) {
279
                    // ais->type8.dac1fid11.day = AIS_DAY_NOT_AVAILABLE;
280
0
                    ais->type8.dac1fid11.hour = AIS_HOUR_NOT_AVAILABLE;
281
0
                    ais->type8.dac1fid11.minute = AIS_MINUTE_NOT_AVAILABLE;
282
0
                    (void)sscanf(timestamp, "%02uT%02u:%02uZ",
283
0
                                 &ais->type8.dac1fid11.day,
284
0
                                 &ais->type8.dac1fid11.hour,
285
0
                                 &ais->type8.dac1fid11.minute);
286
0
                }
287
0
                structured = true;
288
0
            }
289
0
            else if (strstr(buf, "\"fid\":13,") != NULL) {
290
0
                status = json_read_object(buf, json_ais8_fid13, endptr);
291
0
                if (status == 0) {
292
                    // no need to set zeros, again.
293
                    // ais->type8.dac1fid13.fmonth = AIS_MONTH_NOT_AVAILABLE;
294
                    // ais->type8.dac1fid13.fday = AIS_DAY_NOT_AVAILABLE;
295
0
                    ais->type8.dac1fid13.fhour = AIS_HOUR_NOT_AVAILABLE;
296
0
                    ais->type8.dac1fid13.fminute = AIS_MINUTE_NOT_AVAILABLE;
297
0
                    (void)sscanf(departure, "%02u-%02uT%02u:%02uZ",
298
0
                                 &ais->type8.dac1fid13.fmonth,
299
0
                                 &ais->type8.dac1fid13.fday,
300
0
                                 &ais->type8.dac1fid13.fhour,
301
0
                                 &ais->type8.dac1fid13.fminute);
302
                    // no need to set zeros, again.
303
                    // ais->type8.dac1fid13.tmonth = AIS_MONTH_NOT_AVAILABLE;
304
                    // ais->type8.dac1fid13.tday = AIS_DAY_NOT_AVAILABLE;
305
0
                    ais->type8.dac1fid13.thour = AIS_HOUR_NOT_AVAILABLE;
306
0
                    ais->type8.dac1fid13.tminute = AIS_MINUTE_NOT_AVAILABLE;
307
0
                    (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
308
0
                                 &ais->type8.dac1fid13.tmonth,
309
0
                                 &ais->type8.dac1fid13.tday,
310
0
                                 &ais->type8.dac1fid13.thour,
311
0
                                 &ais->type8.dac1fid13.tminute);
312
0
                }
313
0
                structured = true;
314
0
            }
315
0
            else if (strstr(buf, "\"fid\":15,") != NULL) {
316
0
                status = json_read_object(buf, json_ais8_fid15, endptr);
317
0
                structured = true;
318
0
            }
319
0
            else if (strstr(buf, "\"fid\":16,") != NULL) {
320
0
                status = json_read_object(buf, json_ais8_fid16, endptr);
321
0
                if (status == 0) {
322
0
                        structured = true;
323
0
                }
324
0
            }
325
0
            else if (strstr(buf, "\"fid\":17,") != NULL) {
326
0
                status = json_read_object(buf, json_ais8_fid17, endptr);
327
0
                structured = true;
328
0
            }
329
0
            else if (strstr(buf, "\"fid\":19,") != NULL) {
330
0
                status = json_read_object(buf, json_ais8_fid19, endptr);
331
0
                structured = true;
332
0
            }
333
0
            else if (strstr(buf, "\"fid\":23,") != NULL) {
334
0
                status = json_read_object(buf, json_ais8_fid23, endptr);
335
0
                if (status == 0) {
336
                    // no need to set zeros, again.
337
                    /* ais->type8.dac200fid23.start_year =
338
                     *     AIS_YEAR_NOT_AVAILABLE;
339
                     * ais->type8.dac200fid23.start_month =
340
                     *    AIS_MONTH_NOT_AVAILABLE; */
341
                    // ais->type8.dac200fid23.start_day = AIS_DAY_NOT_AVAILABLE;
342
0
                    ais->type8.dac200fid23.start_hour = AIS_HOUR_NOT_AVAILABLE;
343
0
                    ais->type8.dac200fid23.start_minute = AIS_MINUTE_NOT_AVAILABLE;
344
                    /* ais->type8.dac200fid23.end_year =
345
                     *     AIS_YEAR_NOT_AVAILABLE;
346
                     * ais->type8.dac200fid23.end_month =
347
                     *     AIS_MONTH_NOT_AVAILABLE; */
348
                    // ais->type8.dac200fid23.end_day = AIS_DAY_NOT_AVAILABLE;
349
0
                    ais->type8.dac200fid23.end_hour = AIS_HOUR_NOT_AVAILABLE;
350
0
                    ais->type8.dac200fid23.end_minute = AIS_MINUTE_NOT_AVAILABLE;
351
0
                    (void)sscanf(start, "%09u-%02u-%02uT%02u:%02u",
352
0
                             &ais->type8.dac200fid23.start_year,
353
0
                             &ais->type8.dac200fid23.start_month,
354
0
                             &ais->type8.dac200fid23.start_day,
355
0
                             &ais->type8.dac200fid23.start_hour,
356
0
                             &ais->type8.dac200fid23.start_minute);
357
0
                    (void)sscanf(end, "%09u-%02u-%02uT%02u:%02u",
358
0
                             &ais->type8.dac200fid23.end_year,
359
0
                             &ais->type8.dac200fid23.end_month,
360
0
                             &ais->type8.dac200fid23.end_day,
361
0
                             &ais->type8.dac200fid23.end_hour,
362
0
                             &ais->type8.dac200fid23.end_minute);
363
0
                }
364
0
                structured = true;
365
0
            }
366
0
            else if (strstr(buf, "\"fid\":24,") != NULL) {
367
0
                status = json_read_object(buf, json_ais8_fid24, endptr);
368
0
                structured = true;
369
0
            }
370
0
            else if (strstr(buf, "\"fid\":27,") != NULL) {
371
0
                status = json_read_object(buf, json_ais8_fid27, endptr);
372
0
                if (status == 0) {
373
                    // no need to set zeros, again.
374
                    // ais->type8.dac1fid27.month = AIS_MONTH_NOT_AVAILABLE;
375
                    // ais->type8.dac1fid27.day = AIS_DAY_NOT_AVAILABLE;
376
0
                    ais->type8.dac1fid27.hour = AIS_HOUR_NOT_AVAILABLE;
377
0
                    ais->type8.dac1fid27.minute = AIS_MINUTE_NOT_AVAILABLE;
378
0
                    (void)sscanf(start, "%02u-%02uT%02u:%02uZ",
379
0
                                 &ais->type8.dac1fid27.month,
380
0
                                 &ais->type8.dac1fid27.day,
381
0
                                 &ais->type8.dac1fid27.hour,
382
0
                                 &ais->type8.dac1fid27.minute);
383
0
                }
384
0
                structured = true;
385
0
            }
386
0
            else if (strstr(buf, "\"fid\":29,") != NULL) {
387
0
                status = json_read_object(buf, json_ais8_fid29, endptr);
388
0
                structured = true;
389
0
            }
390
0
            else if (strstr(buf, "\"fid\":31,") != NULL) {
391
0
                status = json_read_object(buf, json_ais8_fid31, endptr);
392
0
                if (status == 0) {
393
                    // ais->type8.dac1fid31.day = AIS_DAY_NOT_AVAILABLE;
394
0
                    ais->type8.dac1fid31.hour = AIS_HOUR_NOT_AVAILABLE;
395
0
                    ais->type8.dac1fid31.minute = AIS_MINUTE_NOT_AVAILABLE;
396
0
                    (void)sscanf(timestamp, "%02uT%02u:%02uZ",
397
0
                                 &ais->type8.dac1fid31.day,
398
0
                                 &ais->type8.dac1fid31.hour,
399
0
                                 &ais->type8.dac1fid31.minute);
400
0
                }
401
0
                structured = true;
402
0
            }
403
0
        }
404
0
        else if (strstr(buf, "\"dac\":200,") != NULL &&
405
0
                 strstr(buf,"data")==NULL) {
406
0
            if (strstr(buf, "\"fid\":10,") != NULL) {
407
0
                status = json_read_object(buf, json_ais8_fid10, endptr);
408
0
                structured = true;
409
0
            }
410
0
            if (strstr(buf, "\"fid\":40,") != NULL) {
411
0
                status = json_read_object(buf, json_ais8_fid40, endptr);
412
0
                structured = true;
413
0
            }
414
0
        }
415
0
        if (!structured) {
416
0
            status = json_read_object(buf, json_ais8, endptr);
417
0
            if (status == 0)
418
0
                lenhex_unpack(data, &ais->type8.bitcount,
419
0
                              ais->type8.bitdata, sizeof(ais->type8.bitdata));
420
0
        }
421
0
        ais->type8.structured = structured;
422
0
    } else if (strstr(buf, "\"type\":9,") != NULL) {
423
0
        status = json_read_object(buf, json_ais9, endptr);
424
0
    } else if (strstr(buf, "\"type\":10,") != NULL) {
425
0
        status = json_read_object(buf, json_ais10, endptr);
426
0
    } else if (strstr(buf, "\"type\":12,") != NULL) {
427
0
        status = json_read_object(buf, json_ais12, endptr);
428
0
    } else if (strstr(buf, "\"type\":14,") != NULL) {
429
0
        status = json_read_object(buf, json_ais14, endptr);
430
0
    } else if (strstr(buf, "\"type\":15,") != NULL) {
431
0
        status = json_read_object(buf, json_ais15, endptr);
432
0
    } else if (strstr(buf, "\"type\":16,") != NULL) {
433
0
        status = json_read_object(buf, json_ais16, endptr);
434
0
    } else if (strstr(buf, "\"type\":17,") != NULL) {
435
0
        status = json_read_object(buf, json_ais17, endptr);
436
0
        if (status == 0)
437
0
            lenhex_unpack(data, &ais->type17.bitcount,
438
0
                          ais->type17.bitdata, sizeof(ais->type17.bitdata));
439
0
    } else if (strstr(buf, "\"type\":18,") != NULL) {
440
0
        status = json_read_object(buf, json_ais18, endptr);
441
0
    } else if (strstr(buf, "\"type\":19,") != NULL) {
442
0
        status = json_read_object(buf, json_ais19, endptr);
443
0
    } else if (strstr(buf, "\"type\":20,") != NULL) {
444
0
        status = json_read_object(buf, json_ais20, endptr);
445
0
    } else if (strstr(buf, "\"type\":21,") != NULL) {
446
0
        status = json_read_object(buf, json_ais21, endptr);
447
0
    } else if (strstr(buf, "\"type\":22,") != NULL) {
448
0
        status = json_read_object(buf, json_ais22, endptr);
449
0
    } else if (strstr(buf, "\"type\":23,") != NULL) {
450
0
        status = json_read_object(buf, json_ais23, endptr);
451
0
    } else if (strstr(buf, "\"type\":24,") != NULL) {
452
0
        status = json_read_object(buf, json_ais24, endptr);
453
0
    } else if (strstr(buf, "\"type\":25,") != NULL) {
454
0
        status = json_read_object(buf, json_ais25, endptr);
455
0
        if (status == 0)
456
0
            lenhex_unpack(data, &ais->type25.bitcount,
457
0
                          ais->type25.bitdata, sizeof(ais->type25.bitdata));
458
0
    } else if (strstr(buf, "\"type\":26,") != NULL) {
459
0
        status = json_read_object(buf, json_ais26, endptr);
460
0
        if (status == 0)
461
0
            lenhex_unpack(data, &ais->type26.bitcount,
462
0
                          ais->type26.bitdata, sizeof(ais->type26.bitdata));
463
0
    } else if (strstr(buf, "\"type\":27,") != NULL) {
464
0
        status = json_read_object(buf, json_ais27, endptr);
465
0
    } else {
466
0
        if (NULL != endptr) {
467
0
            *endptr = NULL;
468
0
        }
469
0
        return JSON_ERR_MISC;
470
0
    }
471
0
    return status;
472
0
}
473
474
// vim: set expandtab shiftwidth=4