Coverage Report

Created: 2026-04-12 06:12

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