Coverage Report

Created: 2025-11-11 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpsd/gpsd-3.26.2~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
112
{
30
112
    char *colon = strchr(from, ':');
31
32
112
    *plen = (size_t)atoi(from);
33
112
    if (NULL != colon) {
34
103
        (void)gps_hexpack(colon + 1, (unsigned char *)to, maxlen);
35
103
    }
36
112
}
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
304
{
43
    // collected but not actually used yet
44
304
    bool scaled;
45
46
304
#define AIS_HEADER \
47
14.8k
        {"class",          t_check,    .dflt.check = "AIS"}, \
48
14.8k
        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
49
14.8k
        {"device",         t_string,   .addr.string = path, \
50
14.8k
                                          .len = pathlen}, \
51
14.8k
        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
52
14.8k
        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
53
14.8k
                                          .dflt.boolean = false}, \
54
14.8k
        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
55
56
304
#define AIS_TYPE6 \
57
4.25k
        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
58
4.25k
                                       .dflt.uinteger = 0},\
59
4.25k
        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
60
4.25k
                                       .dflt.uinteger = 0},\
61
4.25k
        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
62
4.25k
                                       .dflt.boolean = false},\
63
4.25k
        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
64
4.25k
                                       .dflt.uinteger = 0},\
65
4.25k
        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
66
4.25k
                                       .dflt.uinteger = 0},
67
304
#define AIS_TYPE8 \
68
4.25k
        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
69
4.25k
                                       .dflt.uinteger = 0},\
70
4.25k
        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
71
4.25k
                                       .dflt.uinteger = 0},
72
73
304
    int status;
74
75
304
#include "ais_json.i"           // JSON parser template structures
76
77
304
#undef AIS_HEADER
78
79
304
    memset(ais, '\0', sizeof(struct ais_t));
80
81
304
    if (NULL != strstr(buf, "\"type\":1,") ||
82
304
        NULL != strstr(buf, "\"type\":2,") ||
83
304
        NULL != strstr(buf, "\"type\":3,")) {
84
4
        status = json_read_object(buf, json_ais1, endptr);
85
300
    } else if (NULL != strstr(buf, "\"type\":4,") ||
86
300
               NULL != strstr(buf, "\"type\":11,")) {
87
4
        status = json_read_object(buf, json_ais4, endptr);
88
4
        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
296
    } else if (strstr(buf, "\"type\":5,") != NULL) {
106
14
        status = json_read_object(buf, json_ais5, endptr);
107
14
        if (status == 0) {
108
3
            ais->type5.month = AIS_MONTH_NOT_AVAILABLE;
109
3
            ais->type5.day = AIS_DAY_NOT_AVAILABLE;
110
3
            ais->type5.hour = AIS_HOUR_NOT_AVAILABLE;
111
3
            ais->type5.minute = AIS_MINUTE_NOT_AVAILABLE;
112
3
            (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
113
3
                         &ais->type5.month,
114
3
                         &ais->type5.day,
115
3
                         &ais->type5.hour,
116
3
                         &ais->type5.minute);
117
3
        }
118
282
    } else if (strstr(buf, "\"type\":6,") != NULL) {
119
120
        bool structured = false;
120
120
        if (strstr(buf, "\"dac\":1,") != NULL) {
121
24
            if (strstr(buf, "\"fid\":12,") != NULL) {
122
4
                status = json_read_object(buf, json_ais6_fid12, endptr);
123
4
                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
4
                structured = true;
144
4
            }
145
20
            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
19
            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
18
            else if (strstr(buf, "\"fid\":18,") != NULL) {
154
4
                status = json_read_object(buf, json_ais6_fid18, endptr);
155
4
                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
4
                structured = true;
166
4
            }
167
14
            else if (strstr(buf, "\"fid\":20,") != NULL) {
168
6
                status = json_read_object(buf, json_ais6_fid20, endptr);
169
6
                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
6
                structured = true;
181
6
            }
182
8
            else if (strstr(buf, "\"fid\":25,") != NULL) {
183
2
                status = json_read_object(buf, json_ais6_fid25, endptr);
184
2
                structured = true;
185
2
            }
186
6
            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
4
            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
3
            else if (strstr(buf, "\"fid\":32,") != NULL ||
206
2
                     strstr(buf, "\"fid\":14,") != NULL) {
207
2
                status = json_read_object(buf, json_ais6_fid32, endptr);
208
2
                structured = true;
209
2
            }
210
24
        }
211
96
        else if (strstr(buf, "\"dac\":235,") != NULL ||
212
94
                 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
92
        else if (strstr(buf, "\"dac\":200,") != NULL) {
219
8
            if (strstr(buf, "\"fid\":21,") != NULL) {
220
4
                status = json_read_object(buf, json_ais6_fid21, endptr);
221
4
                structured = true;
222
4
                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
4
            }
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
8
        }
254
120
        if (!structured) {
255
88
            status = json_read_object(buf, json_ais6, endptr);
256
88
            if (status == 0)
257
78
                lenhex_unpack(data, &ais->type6.bitcount,
258
78
                              ais->type6.bitdata, sizeof(ais->type6.bitdata));
259
88
        }
260
120
        ais->type6.structured = structured;
261
162
    } else if (strstr(buf, "\"type\":7,") != NULL
262
160
               || strstr(buf, "\"type\":13,") != NULL) {
263
3
        status = json_read_object(buf, json_ais7, endptr);
264
159
    } else if (strstr(buf, "\"type\":8,") != NULL) {
265
89
        bool structured = false;
266
89
        if (strstr(buf, "\"dac\":1,") != NULL) {
267
63
            if (strstr(buf, "\"fid\":11,") != NULL) {
268
2
                status = json_read_object(buf, json_ais8_fid11, endptr);
269
2
                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
2
                structured = true;
279
2
            }
280
61
            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
59
            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
58
            else if (strstr(buf, "\"fid\":16,") != NULL) {
309
42
                status = json_read_object(buf, json_ais8_fid16, endptr);
310
42
                if (status == 0) {
311
1
                        structured = true;
312
1
                }
313
42
            }
314
16
            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
15
            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
14
            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
12
            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
11
            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
6
            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
5
            else if (strstr(buf, "\"fid\":31,") != NULL) {
372
4
                status = json_read_object(buf, json_ais8_fid31, endptr);
373
4
                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
4
                structured = true;
383
4
            }
384
63
        }
385
26
        else if (strstr(buf, "\"dac\":200,") != NULL &&
386
6
                 strstr(buf,"data")==NULL) {
387
5
            if (strstr(buf, "\"fid\":10,") != NULL) {
388
3
                status = json_read_object(buf, json_ais8_fid10, endptr);
389
3
                structured = true;
390
3
            }
391
5
            if (strstr(buf, "\"fid\":40,") != NULL) {
392
3
                status = json_read_object(buf, json_ais8_fid40, endptr);
393
3
                structured = true;
394
3
            }
395
5
        }
396
89
        if (!structured) {
397
64
            status = json_read_object(buf, json_ais8, endptr);
398
64
            if (status == 0)
399
18
                lenhex_unpack(data, &ais->type8.bitcount,
400
18
                              ais->type8.bitdata, sizeof(ais->type8.bitdata));
401
64
        }
402
89
        ais->type8.structured = structured;
403
89
    } else if (strstr(buf, "\"type\":9,") != NULL) {
404
1
        status = json_read_object(buf, json_ais9, endptr);
405
69
    } else if (strstr(buf, "\"type\":10,") != NULL) {
406
1
        status = json_read_object(buf, json_ais10, endptr);
407
68
    } else if (strstr(buf, "\"type\":12,") != NULL) {
408
2
        status = json_read_object(buf, json_ais12, endptr);
409
66
    } else if (strstr(buf, "\"type\":14,") != NULL) {
410
1
        status = json_read_object(buf, json_ais14, endptr);
411
65
    } else if (strstr(buf, "\"type\":15,") != NULL) {
412
1
        status = json_read_object(buf, json_ais15, endptr);
413
64
    } else if (strstr(buf, "\"type\":16,") != NULL) {
414
1
        status = json_read_object(buf, json_ais16, endptr);
415
63
    } else if (strstr(buf, "\"type\":17,") != NULL) {
416
5
        status = json_read_object(buf, json_ais17, endptr);
417
5
        if (status == 0)
418
1
            lenhex_unpack(data, &ais->type17.bitcount,
419
1
                          ais->type17.bitdata, sizeof(ais->type17.bitdata));
420
58
    } else if (strstr(buf, "\"type\":18,") != NULL) {
421
5
        status = json_read_object(buf, json_ais18, endptr);
422
53
    } else if (strstr(buf, "\"type\":19,") != NULL) {
423
1
        status = json_read_object(buf, json_ais19, endptr);
424
52
    } else if (strstr(buf, "\"type\":20,") != NULL) {
425
1
        status = json_read_object(buf, json_ais20, endptr);
426
51
    } else if (strstr(buf, "\"type\":21,") != NULL) {
427
2
        status = json_read_object(buf, json_ais21, endptr);
428
49
    } else if (strstr(buf, "\"type\":22,") != NULL) {
429
2
        status = json_read_object(buf, json_ais22, endptr);
430
47
    } else if (strstr(buf, "\"type\":23,") != NULL) {
431
19
        status = json_read_object(buf, json_ais23, endptr);
432
28
    } else if (strstr(buf, "\"type\":24,") != NULL) {
433
2
        status = json_read_object(buf, json_ais24, endptr);
434
26
    } else if (strstr(buf, "\"type\":25,") != NULL) {
435
15
        status = json_read_object(buf, json_ais25, endptr);
436
15
        if (status == 0)
437
11
            lenhex_unpack(data, &ais->type25.bitcount,
438
11
                          ais->type25.bitdata, sizeof(ais->type25.bitdata));
439
15
    } 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
2
    } else {
447
2
        if (NULL != endptr) {
448
0
            *endptr = NULL;
449
0
        }
450
2
        return JSON_ERR_MISC;
451
2
    }
452
302
    return status;
453
304
}
454
455
// vim: set expandtab shiftwidth=4