Coverage Report

Created: 2025-11-28 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mosquitto/libcommon/property_common.c
Line
Count
Source
1
/*
2
Copyright (c) 2018-2021 Roger Light <roger@atchoo.org>
3
4
All rights reserved. This program and the accompanying materials
5
are made available under the terms of the Eclipse Public License 2.0
6
and Eclipse Distribution License v1.0 which accompany this distribution.
7
8
The Eclipse Public License is available at
9
   https://www.eclipse.org/legal/epl-2.0/
10
and the Eclipse Distribution License is available at
11
  http://www.eclipse.org/org/documents/edl-v10.php.
12
13
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
14
15
Contributors:
16
   Roger Light - initial implementation and documentation.
17
*/
18
19
#include "config.h"
20
21
#include <errno.h>
22
#include <stdlib.h>
23
#include <string.h>
24
25
#ifndef WIN32
26
#  include <strings.h>
27
#endif
28
29
#include "mosquitto.h"
30
#include "property_common.h"
31
32
33
void mosquitto_property_free(mosquitto_property **property)
34
21.8M
{
35
21.8M
  if(!property || !(*property)){
36
0
    return;
37
0
  }
38
39
21.8M
  switch((*property)->property_type){
40
594k
    case MQTT_PROP_TYPE_STRING:
41
594k
      mosquitto_FREE((*property)->value.s.v);
42
594k
      break;
43
44
1.43M
    case MQTT_PROP_TYPE_BINARY:
45
1.43M
      mosquitto_FREE((*property)->value.bin.v);
46
1.43M
      break;
47
48
12.8k
    case MQTT_PROP_TYPE_STRING_PAIR:
49
12.8k
      mosquitto_FREE((*property)->name.v);
50
12.8k
      mosquitto_FREE((*property)->value.s.v);
51
12.8k
      break;
52
53
17.2M
    case MQTT_PROP_TYPE_BYTE:
54
18.2M
    case MQTT_PROP_TYPE_INT16:
55
18.7M
    case MQTT_PROP_TYPE_INT32:
56
19.7M
    case MQTT_PROP_TYPE_VARINT:
57
      /* Nothing to free */
58
19.7M
      break;
59
21.8M
  }
60
61
21.8M
  mosquitto_FREE(*property);
62
21.8M
}
63
64
65
BROKER_EXPORT void mosquitto_property_free_all(mosquitto_property **property)
66
310k
{
67
310k
  mosquitto_property *p, *next;
68
69
310k
  if(!property){
70
0
    return;
71
0
  }
72
73
310k
  p = *property;
74
22.1M
  while(p){
75
21.8M
    next = p->next;
76
21.8M
    mosquitto_property_free(&p);
77
21.8M
    p = next;
78
21.8M
  }
79
310k
  *property = NULL;
80
310k
}
81
82
83
unsigned int mosquitto_property_get_length(const mosquitto_property *property)
84
2.84k
{
85
2.84k
  if(!property){
86
0
    return 0;
87
0
  }
88
89
2.84k
  switch(property->property_type){
90
2.84k
    case MQTT_PROP_TYPE_BYTE:
91
2.84k
      return 2; /* 1 (identifier) + 1 byte */
92
93
0
    case MQTT_PROP_TYPE_INT16:
94
0
      return 3; /* 1 (identifier) + 2 bytes */
95
96
0
    case MQTT_PROP_TYPE_INT32:
97
0
      return 5; /* 1 (identifier) + 4 bytes */
98
99
0
    case MQTT_PROP_TYPE_VARINT:
100
0
      if(property->value.varint < 128){
101
0
        return 2;
102
0
      }else if(property->value.varint < 16384){
103
0
        return 3;
104
0
      }else if(property->value.varint < 2097152){
105
0
        return 4;
106
0
      }else if(property->value.varint < 268435456){
107
0
        return 5;
108
0
      }else{
109
0
        return 0;
110
0
      }
111
112
0
    case MQTT_PROP_TYPE_BINARY:
113
0
      return 3U + property->value.bin.len; /* 1 + 2 bytes (len) + X bytes (payload) */
114
115
0
    case MQTT_PROP_TYPE_STRING:
116
0
      return 3U + property->value.s.len; /* 1 + 2 bytes (len) + X bytes (string) */
117
118
0
    case MQTT_PROP_TYPE_STRING_PAIR:
119
0
      return 5U + property->value.s.len + property->name.len; /* 1 + 2*(2 bytes (len) + X bytes (string))*/
120
121
0
    default:
122
0
      return 0;
123
2.84k
  }
124
0
  return 0;
125
2.84k
}
126
127
128
unsigned int mosquitto_property_get_length_all(const mosquitto_property *property)
129
3.25k
{
130
3.25k
  const mosquitto_property *p;
131
3.25k
  unsigned int len = 0;
132
133
3.25k
  p = property;
134
6.09k
  while(p){
135
2.84k
    len += mosquitto_property_get_length(p);
136
2.84k
    p = p->next;
137
2.84k
  }
138
3.25k
  return len;
139
3.25k
}
140
141
142
BROKER_EXPORT int mosquitto_property_check_command(int command, int identifier)
143
17.4k
{
144
17.4k
  switch(identifier){
145
1.73k
    case MQTT_PROP_PAYLOAD_FORMAT_INDICATOR:
146
2.62k
    case MQTT_PROP_MESSAGE_EXPIRY_INTERVAL:
147
4.18k
    case MQTT_PROP_CONTENT_TYPE:
148
5.73k
    case MQTT_PROP_RESPONSE_TOPIC:
149
7.11k
    case MQTT_PROP_CORRELATION_DATA:
150
7.11k
      if(command != CMD_PUBLISH && command != CMD_WILL){
151
138
        return MOSQ_ERR_PROTOCOL;
152
138
      }
153
6.98k
      break;
154
155
6.98k
    case MQTT_PROP_SUBSCRIPTION_IDENTIFIER:
156
1.67k
      if(command != CMD_PUBLISH && command != CMD_SUBSCRIBE){
157
14
        return MOSQ_ERR_PROTOCOL;
158
14
      }
159
1.66k
      break;
160
161
1.66k
    case MQTT_PROP_SESSION_EXPIRY_INTERVAL:
162
37
      if(command != CMD_CONNECT && command != CMD_CONNACK && command != CMD_DISCONNECT){
163
10
        return MOSQ_ERR_PROTOCOL;
164
10
      }
165
27
      break;
166
167
195
    case MQTT_PROP_AUTHENTICATION_METHOD:
168
370
    case MQTT_PROP_AUTHENTICATION_DATA:
169
370
      if(command != CMD_CONNECT && command != CMD_CONNACK && command != CMD_AUTH){
170
47
        return MOSQ_ERR_PROTOCOL;
171
47
      }
172
323
      break;
173
174
323
    case MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER:
175
72
    case MQTT_PROP_SERVER_KEEP_ALIVE:
176
101
    case MQTT_PROP_RESPONSE_INFORMATION:
177
132
    case MQTT_PROP_MAXIMUM_QOS:
178
166
    case MQTT_PROP_RETAIN_AVAILABLE:
179
201
    case MQTT_PROP_WILDCARD_SUB_AVAILABLE:
180
236
    case MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE:
181
274
    case MQTT_PROP_SHARED_SUB_AVAILABLE:
182
274
      if(command != CMD_CONNACK){
183
145
        return MOSQ_ERR_PROTOCOL;
184
145
      }
185
129
      break;
186
187
129
    case MQTT_PROP_WILL_DELAY_INTERVAL:
188
18
      if(command != CMD_WILL){
189
8
        return MOSQ_ERR_PROTOCOL;
190
8
      }
191
10
      break;
192
193
75
    case MQTT_PROP_REQUEST_PROBLEM_INFORMATION:
194
150
    case MQTT_PROP_REQUEST_RESPONSE_INFORMATION:
195
150
      if(command != CMD_CONNECT){
196
34
        return MOSQ_ERR_PROTOCOL;
197
34
      }
198
116
      break;
199
200
116
    case MQTT_PROP_SERVER_REFERENCE:
201
42
      if(command != CMD_CONNACK && command != CMD_DISCONNECT){
202
25
        return MOSQ_ERR_PROTOCOL;
203
25
      }
204
17
      break;
205
206
65
    case MQTT_PROP_REASON_STRING:
207
65
      if(command == CMD_CONNECT || command == CMD_PUBLISH || command == CMD_SUBSCRIBE || command == CMD_UNSUBSCRIBE){
208
26
        return MOSQ_ERR_PROTOCOL;
209
26
      }
210
39
      break;
211
212
145
    case MQTT_PROP_RECEIVE_MAXIMUM:
213
278
    case MQTT_PROP_TOPIC_ALIAS_MAXIMUM:
214
678
    case MQTT_PROP_MAXIMUM_PACKET_SIZE:
215
678
      if(command != CMD_CONNECT && command != CMD_CONNACK){
216
322
        return MOSQ_ERR_PROTOCOL;
217
322
      }
218
356
      break;
219
220
1.25k
    case MQTT_PROP_TOPIC_ALIAS:
221
1.25k
      if(command != CMD_PUBLISH){
222
18
        return MOSQ_ERR_PROTOCOL;
223
18
      }
224
1.23k
      break;
225
226
5.78k
    case MQTT_PROP_USER_PROPERTY:
227
5.78k
      break;
228
229
0
    default:
230
0
      return MOSQ_ERR_PROTOCOL;
231
17.4k
  }
232
16.6k
  return MOSQ_ERR_SUCCESS;
233
17.4k
}
234
235
236
BROKER_EXPORT const char *mosquitto_property_identifier_to_string(int identifier)
237
0
{
238
0
  switch(identifier){
239
0
    case MQTT_PROP_PAYLOAD_FORMAT_INDICATOR:
240
0
      return "payload-format-indicator";
241
0
    case MQTT_PROP_MESSAGE_EXPIRY_INTERVAL:
242
0
      return "message-expiry-interval";
243
0
    case MQTT_PROP_CONTENT_TYPE:
244
0
      return "content-type";
245
0
    case MQTT_PROP_RESPONSE_TOPIC:
246
0
      return "response-topic";
247
0
    case MQTT_PROP_CORRELATION_DATA:
248
0
      return "correlation-data";
249
0
    case MQTT_PROP_SUBSCRIPTION_IDENTIFIER:
250
0
      return "subscription-identifier";
251
0
    case MQTT_PROP_SESSION_EXPIRY_INTERVAL:
252
0
      return "session-expiry-interval";
253
0
    case MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER:
254
0
      return "assigned-client-identifier";
255
0
    case MQTT_PROP_SERVER_KEEP_ALIVE:
256
0
      return "server-keep-alive";
257
0
    case MQTT_PROP_AUTHENTICATION_METHOD:
258
0
      return "authentication-method";
259
0
    case MQTT_PROP_AUTHENTICATION_DATA:
260
0
      return "authentication-data";
261
0
    case MQTT_PROP_REQUEST_PROBLEM_INFORMATION:
262
0
      return "request-problem-information";
263
0
    case MQTT_PROP_WILL_DELAY_INTERVAL:
264
0
      return "will-delay-interval";
265
0
    case MQTT_PROP_REQUEST_RESPONSE_INFORMATION:
266
0
      return "request-response-information";
267
0
    case MQTT_PROP_RESPONSE_INFORMATION:
268
0
      return "response-information";
269
0
    case MQTT_PROP_SERVER_REFERENCE:
270
0
      return "server-reference";
271
0
    case MQTT_PROP_REASON_STRING:
272
0
      return "reason-string";
273
0
    case MQTT_PROP_RECEIVE_MAXIMUM:
274
0
      return "receive-maximum";
275
0
    case MQTT_PROP_TOPIC_ALIAS_MAXIMUM:
276
0
      return "topic-alias-maximum";
277
0
    case MQTT_PROP_TOPIC_ALIAS:
278
0
      return "topic-alias";
279
0
    case MQTT_PROP_MAXIMUM_QOS:
280
0
      return "maximum-qos";
281
0
    case MQTT_PROP_RETAIN_AVAILABLE:
282
0
      return "retain-available";
283
0
    case MQTT_PROP_USER_PROPERTY:
284
0
      return "user-property";
285
0
    case MQTT_PROP_MAXIMUM_PACKET_SIZE:
286
0
      return "maximum-packet-size";
287
0
    case MQTT_PROP_WILDCARD_SUB_AVAILABLE:
288
0
      return "wildcard-subscription-available";
289
0
    case MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE:
290
0
      return "subscription-identifier-available";
291
0
    case MQTT_PROP_SHARED_SUB_AVAILABLE:
292
0
      return "shared-subscription-available";
293
0
    default:
294
0
      return NULL;
295
0
  }
296
0
}
297
298
299
BROKER_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type)
300
0
{
301
0
  if(!propname){
302
0
    return MOSQ_ERR_INVAL;
303
0
  }
304
305
0
  if(!strcasecmp(propname, "payload-format-indicator")){
306
0
    *identifier = MQTT_PROP_PAYLOAD_FORMAT_INDICATOR;
307
0
    *type = MQTT_PROP_TYPE_BYTE;
308
0
  }else if(!strcasecmp(propname, "message-expiry-interval")){
309
0
    *identifier = MQTT_PROP_MESSAGE_EXPIRY_INTERVAL;
310
0
    *type = MQTT_PROP_TYPE_INT32;
311
0
  }else if(!strcasecmp(propname, "content-type")){
312
0
    *identifier = MQTT_PROP_CONTENT_TYPE;
313
0
    *type = MQTT_PROP_TYPE_STRING;
314
0
  }else if(!strcasecmp(propname, "response-topic")){
315
0
    *identifier = MQTT_PROP_RESPONSE_TOPIC;
316
0
    *type = MQTT_PROP_TYPE_STRING;
317
0
  }else if(!strcasecmp(propname, "correlation-data")){
318
0
    *identifier = MQTT_PROP_CORRELATION_DATA;
319
0
    *type = MQTT_PROP_TYPE_BINARY;
320
0
  }else if(!strcasecmp(propname, "subscription-identifier")){
321
0
    *identifier = MQTT_PROP_SUBSCRIPTION_IDENTIFIER;
322
0
    *type = MQTT_PROP_TYPE_VARINT;
323
0
  }else if(!strcasecmp(propname, "session-expiry-interval")){
324
0
    *identifier = MQTT_PROP_SESSION_EXPIRY_INTERVAL;
325
0
    *type = MQTT_PROP_TYPE_INT32;
326
0
  }else if(!strcasecmp(propname, "assigned-client-identifier")){
327
0
    *identifier = MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER;
328
0
    *type = MQTT_PROP_TYPE_STRING;
329
0
  }else if(!strcasecmp(propname, "server-keep-alive")){
330
0
    *identifier = MQTT_PROP_SERVER_KEEP_ALIVE;
331
0
    *type = MQTT_PROP_TYPE_INT16;
332
0
  }else if(!strcasecmp(propname, "authentication-method")){
333
0
    *identifier = MQTT_PROP_AUTHENTICATION_METHOD;
334
0
    *type = MQTT_PROP_TYPE_STRING;
335
0
  }else if(!strcasecmp(propname, "authentication-data")){
336
0
    *identifier = MQTT_PROP_AUTHENTICATION_DATA;
337
0
    *type = MQTT_PROP_TYPE_BINARY;
338
0
  }else if(!strcasecmp(propname, "request-problem-information")){
339
0
    *identifier = MQTT_PROP_REQUEST_PROBLEM_INFORMATION;
340
0
    *type = MQTT_PROP_TYPE_BYTE;
341
0
  }else if(!strcasecmp(propname, "will-delay-interval")){
342
0
    *identifier = MQTT_PROP_WILL_DELAY_INTERVAL;
343
0
    *type = MQTT_PROP_TYPE_INT32;
344
0
  }else if(!strcasecmp(propname, "request-response-information")){
345
0
    *identifier = MQTT_PROP_REQUEST_RESPONSE_INFORMATION;
346
0
    *type = MQTT_PROP_TYPE_BYTE;
347
0
  }else if(!strcasecmp(propname, "response-information")){
348
0
    *identifier = MQTT_PROP_RESPONSE_INFORMATION;
349
0
    *type = MQTT_PROP_TYPE_STRING;
350
0
  }else if(!strcasecmp(propname, "server-reference")){
351
0
    *identifier = MQTT_PROP_SERVER_REFERENCE;
352
0
    *type = MQTT_PROP_TYPE_STRING;
353
0
  }else if(!strcasecmp(propname, "reason-string")){
354
0
    *identifier = MQTT_PROP_REASON_STRING;
355
0
    *type = MQTT_PROP_TYPE_STRING;
356
0
  }else if(!strcasecmp(propname, "receive-maximum")){
357
0
    *identifier = MQTT_PROP_RECEIVE_MAXIMUM;
358
0
    *type = MQTT_PROP_TYPE_INT16;
359
0
  }else if(!strcasecmp(propname, "topic-alias-maximum")){
360
0
    *identifier = MQTT_PROP_TOPIC_ALIAS_MAXIMUM;
361
0
    *type = MQTT_PROP_TYPE_INT16;
362
0
  }else if(!strcasecmp(propname, "topic-alias")){
363
0
    *identifier = MQTT_PROP_TOPIC_ALIAS;
364
0
    *type = MQTT_PROP_TYPE_INT16;
365
0
  }else if(!strcasecmp(propname, "maximum-qos")){
366
0
    *identifier = MQTT_PROP_MAXIMUM_QOS;
367
0
    *type = MQTT_PROP_TYPE_BYTE;
368
0
  }else if(!strcasecmp(propname, "retain-available")){
369
0
    *identifier = MQTT_PROP_RETAIN_AVAILABLE;
370
0
    *type = MQTT_PROP_TYPE_BYTE;
371
0
  }else if(!strcasecmp(propname, "user-property")){
372
0
    *identifier = MQTT_PROP_USER_PROPERTY;
373
0
    *type = MQTT_PROP_TYPE_STRING_PAIR;
374
0
  }else if(!strcasecmp(propname, "maximum-packet-size")){
375
0
    *identifier = MQTT_PROP_MAXIMUM_PACKET_SIZE;
376
0
    *type = MQTT_PROP_TYPE_INT32;
377
0
  }else if(!strcasecmp(propname, "wildcard-subscription-available")){
378
0
    *identifier = MQTT_PROP_WILDCARD_SUB_AVAILABLE;
379
0
    *type = MQTT_PROP_TYPE_BYTE;
380
0
  }else if(!strcasecmp(propname, "subscription-identifier-available")){
381
0
    *identifier = MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE;
382
0
    *type = MQTT_PROP_TYPE_BYTE;
383
0
  }else if(!strcasecmp(propname, "shared-subscription-available")){
384
0
    *identifier = MQTT_PROP_SHARED_SUB_AVAILABLE;
385
0
    *type = MQTT_PROP_TYPE_BYTE;
386
0
  }else{
387
0
    return MOSQ_ERR_INVAL;
388
0
  }
389
0
  return MOSQ_ERR_SUCCESS;
390
0
}
391
392
393
static void property__add(mosquitto_property **proplist, struct mqtt5__property *prop)
394
1.42k
{
395
1.42k
  mosquitto_property *p;
396
397
1.42k
  if(!(*proplist)){
398
1.42k
    *proplist = prop;
399
1.42k
  }
400
401
1.42k
  p = *proplist;
402
1.42k
  while(p->next){
403
0
    p = p->next;
404
0
  }
405
1.42k
  p->next = prop;
406
1.42k
  prop->next = NULL;
407
1.42k
}
408
409
410
BROKER_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value)
411
1.42k
{
412
1.42k
  mosquitto_property *prop;
413
414
1.42k
  if(!proplist){
415
0
    return MOSQ_ERR_INVAL;
416
0
  }
417
1.42k
  if(identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
418
1.42k
      && identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION
419
1.42k
      && identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION
420
1.42k
      && identifier != MQTT_PROP_MAXIMUM_QOS
421
2
      && identifier != MQTT_PROP_RETAIN_AVAILABLE
422
0
      && identifier != MQTT_PROP_WILDCARD_SUB_AVAILABLE
423
0
      && identifier != MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE
424
0
      && identifier != MQTT_PROP_SHARED_SUB_AVAILABLE){
425
0
    return MOSQ_ERR_INVAL;
426
0
  }
427
428
1.42k
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
429
1.42k
  if(!prop){
430
0
    return MOSQ_ERR_NOMEM;
431
0
  }
432
433
1.42k
  prop->client_generated = true;
434
1.42k
  prop->identifier = identifier;
435
1.42k
  prop->value.i8 = value;
436
1.42k
  prop->property_type = MQTT_PROP_TYPE_BYTE;
437
438
1.42k
  property__add(proplist, prop);
439
1.42k
  return MOSQ_ERR_SUCCESS;
440
1.42k
}
441
442
443
BROKER_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value)
444
0
{
445
0
  mosquitto_property *prop;
446
447
0
  if(!proplist){
448
0
    return MOSQ_ERR_INVAL;
449
0
  }
450
0
  if(identifier != MQTT_PROP_SERVER_KEEP_ALIVE
451
0
      && identifier != MQTT_PROP_RECEIVE_MAXIMUM
452
0
      && identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM
453
0
      && identifier != MQTT_PROP_TOPIC_ALIAS){
454
0
    return MOSQ_ERR_INVAL;
455
0
  }
456
457
0
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
458
0
  if(!prop){
459
0
    return MOSQ_ERR_NOMEM;
460
0
  }
461
462
0
  prop->client_generated = true;
463
0
  prop->identifier = identifier;
464
0
  prop->value.i16 = value;
465
0
  prop->property_type = MQTT_PROP_TYPE_INT16;
466
467
0
  property__add(proplist, prop);
468
0
  return MOSQ_ERR_SUCCESS;
469
0
}
470
471
472
BROKER_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value)
473
0
{
474
0
  mosquitto_property *prop;
475
476
0
  if(!proplist){
477
0
    return MOSQ_ERR_INVAL;
478
0
  }
479
0
  if(identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL
480
0
      && identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL
481
0
      && identifier != MQTT_PROP_WILL_DELAY_INTERVAL
482
0
      && identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){
483
484
0
    return MOSQ_ERR_INVAL;
485
0
  }
486
487
0
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
488
0
  if(!prop){
489
0
    return MOSQ_ERR_NOMEM;
490
0
  }
491
492
0
  prop->client_generated = true;
493
0
  prop->identifier = identifier;
494
0
  prop->value.i32 = value;
495
0
  prop->property_type = MQTT_PROP_TYPE_INT32;
496
497
0
  property__add(proplist, prop);
498
0
  return MOSQ_ERR_SUCCESS;
499
0
}
500
501
502
BROKER_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value)
503
0
{
504
0
  mosquitto_property *prop;
505
506
0
  if(!proplist || value > MQTT_MAX_PAYLOAD){
507
0
    return MOSQ_ERR_INVAL;
508
0
  }
509
0
  if(identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER){
510
0
    return MOSQ_ERR_INVAL;
511
0
  }
512
513
0
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
514
0
  if(!prop){
515
0
    return MOSQ_ERR_NOMEM;
516
0
  }
517
518
0
  prop->client_generated = true;
519
0
  prop->identifier = identifier;
520
0
  prop->value.varint = value;
521
0
  prop->property_type = MQTT_PROP_TYPE_VARINT;
522
523
0
  property__add(proplist, prop);
524
0
  return MOSQ_ERR_SUCCESS;
525
0
}
526
527
528
BROKER_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len)
529
0
{
530
0
  mosquitto_property *prop;
531
532
0
  if(!proplist){
533
0
    return MOSQ_ERR_INVAL;
534
0
  }
535
0
  if(identifier != MQTT_PROP_CORRELATION_DATA
536
0
      && identifier != MQTT_PROP_AUTHENTICATION_DATA){
537
538
0
    return MOSQ_ERR_INVAL;
539
0
  }
540
541
0
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
542
0
  if(!prop){
543
0
    return MOSQ_ERR_NOMEM;
544
0
  }
545
546
0
  prop->client_generated = true;
547
0
  prop->identifier = identifier;
548
0
  prop->property_type = MQTT_PROP_TYPE_BINARY;
549
550
0
  if(len){
551
0
    prop->value.bin.v = mosquitto_malloc(len);
552
0
    if(!prop->value.bin.v){
553
0
      mosquitto_FREE(prop);
554
0
      return MOSQ_ERR_NOMEM;
555
0
    }
556
557
0
    memcpy(prop->value.bin.v, value, len);
558
0
    prop->value.bin.len = len;
559
0
  }
560
561
0
  property__add(proplist, prop);
562
0
  return MOSQ_ERR_SUCCESS;
563
0
}
564
565
566
BROKER_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value)
567
0
{
568
0
  mosquitto_property *prop;
569
0
  size_t slen = 0;
570
571
0
  if(!proplist){
572
0
    return MOSQ_ERR_INVAL;
573
0
  }
574
0
  if(value){
575
0
    slen = strlen(value);
576
0
    if(mosquitto_validate_utf8(value, (int)slen)){
577
0
      return MOSQ_ERR_MALFORMED_UTF8;
578
0
    }
579
0
  }
580
581
0
  if(identifier != MQTT_PROP_CONTENT_TYPE
582
0
      && identifier != MQTT_PROP_RESPONSE_TOPIC
583
0
      && identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER
584
0
      && identifier != MQTT_PROP_AUTHENTICATION_METHOD
585
0
      && identifier != MQTT_PROP_RESPONSE_INFORMATION
586
0
      && identifier != MQTT_PROP_SERVER_REFERENCE
587
0
      && identifier != MQTT_PROP_REASON_STRING){
588
589
0
    return MOSQ_ERR_INVAL;
590
0
  }
591
592
0
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
593
0
  if(!prop){
594
0
    return MOSQ_ERR_NOMEM;
595
0
  }
596
597
0
  prop->client_generated = true;
598
0
  prop->identifier = identifier;
599
0
  prop->property_type = MQTT_PROP_TYPE_STRING;
600
0
  if(value && slen > 0){
601
0
    prop->value.s.v = mosquitto_strdup(value);
602
0
    if(!prop->value.s.v){
603
0
      mosquitto_FREE(prop);
604
0
      return MOSQ_ERR_NOMEM;
605
0
    }
606
0
    prop->value.s.len = (uint16_t)slen;
607
0
  }
608
609
0
  property__add(proplist, prop);
610
0
  return MOSQ_ERR_SUCCESS;
611
0
}
612
613
614
BROKER_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value)
615
0
{
616
0
  mosquitto_property *prop;
617
0
  size_t slen_name = 0, slen_value = 0;
618
619
0
  if(!proplist){
620
0
    return MOSQ_ERR_INVAL;
621
0
  }
622
0
  if(identifier != MQTT_PROP_USER_PROPERTY){
623
0
    return MOSQ_ERR_INVAL;
624
0
  }
625
0
  if(name){
626
0
    slen_name = strlen(name);
627
0
    if(mosquitto_validate_utf8(name, (int)slen_name)){
628
0
      return MOSQ_ERR_MALFORMED_UTF8;
629
0
    }
630
0
  }
631
0
  if(value){
632
0
    if(mosquitto_validate_utf8(value, (int)slen_value)){
633
0
      return MOSQ_ERR_MALFORMED_UTF8;
634
0
    }
635
0
  }
636
637
0
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
638
0
  if(!prop){
639
0
    return MOSQ_ERR_NOMEM;
640
0
  }
641
642
0
  prop->client_generated = true;
643
0
  prop->identifier = identifier;
644
0
  prop->property_type = MQTT_PROP_TYPE_STRING_PAIR;
645
646
0
  if(name){
647
0
    prop->name.v = mosquitto_strdup(name);
648
0
    if(!prop->name.v){
649
0
      mosquitto_FREE(prop);
650
0
      return MOSQ_ERR_NOMEM;
651
0
    }
652
0
    prop->name.len = (uint16_t)strlen(name);
653
0
  }
654
655
0
  if(value){
656
0
    prop->value.s.v = mosquitto_strdup(value);
657
0
    if(!prop->value.s.v){
658
0
      mosquitto_FREE(prop->name.v);
659
0
      mosquitto_FREE(prop);
660
0
      return MOSQ_ERR_NOMEM;
661
0
    }
662
0
    prop->value.s.len = (uint16_t)strlen(value);
663
0
  }
664
665
0
  property__add(proplist, prop);
666
0
  return MOSQ_ERR_SUCCESS;
667
0
}
668
669
670
BROKER_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties)
671
9.58k
{
672
9.58k
  const mosquitto_property *p, *tail;
673
9.58k
  int rc;
674
675
9.58k
  p = properties;
676
677
26.2k
  while(p){
678
    /* Validity checks */
679
17.6k
    if(p->identifier == MQTT_PROP_REQUEST_PROBLEM_INFORMATION
680
17.5k
        || p->identifier == MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
681
15.7k
        || p->identifier == MQTT_PROP_REQUEST_RESPONSE_INFORMATION
682
15.6k
        || p->identifier == MQTT_PROP_MAXIMUM_QOS
683
15.6k
        || p->identifier == MQTT_PROP_RETAIN_AVAILABLE
684
15.5k
        || p->identifier == MQTT_PROP_WILDCARD_SUB_AVAILABLE
685
15.5k
        || p->identifier == MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE
686
15.5k
        || p->identifier == MQTT_PROP_SHARED_SUB_AVAILABLE){
687
688
2.14k
      if(p->value.i8 > 1){
689
88
        return MOSQ_ERR_PROTOCOL;
690
88
      }
691
15.4k
    }else if(p->identifier == MQTT_PROP_MAXIMUM_PACKET_SIZE){
692
409
      if(p->value.i32 == 0){
693
9
        return MOSQ_ERR_PROTOCOL;
694
9
      }
695
15.0k
    }else if(p->identifier == MQTT_PROP_RECEIVE_MAXIMUM
696
14.9k
        || p->identifier == MQTT_PROP_TOPIC_ALIAS){
697
698
1.40k
      if(p->value.i16 == 0){
699
9
        return MOSQ_ERR_PROTOCOL;
700
9
      }
701
13.6k
    }else if(p->identifier == MQTT_PROP_RESPONSE_TOPIC){
702
1.58k
      if(mosquitto_pub_topic_check(p->value.s.v) != MOSQ_ERR_SUCCESS){
703
31
        return MOSQ_ERR_PROTOCOL;
704
31
      }
705
1.58k
    }
706
707
    /* Check for properties on incorrect commands */
708
17.4k
    rc = mosquitto_property_check_command(command, p->identifier);
709
17.4k
    if(rc){
710
787
      return rc;
711
787
    }
712
713
    /* Check for duplicates */
714
16.6k
    if(p->identifier != MQTT_PROP_USER_PROPERTY){
715
10.8k
      tail = p->next;
716
24.1k
      while(tail){
717
13.2k
        if(p->identifier == tail->identifier){
718
20
          return MOSQ_ERR_DUPLICATE_PROPERTY;
719
20
        }
720
13.2k
        tail = tail->next;
721
13.2k
      }
722
10.8k
    }
723
724
16.6k
    p = p->next;
725
16.6k
  }
726
727
8.64k
  return MOSQ_ERR_SUCCESS;
728
9.58k
}
729
730
731
static const mosquitto_property *property__get_property(const mosquitto_property *proplist, int identifier, bool skip_first)
732
1.06k
{
733
1.06k
  const mosquitto_property *p;
734
1.06k
  bool is_first = true;
735
736
1.06k
  p = proplist;
737
738
7.67k
  while(p){
739
7.06k
    if(p->identifier == identifier){
740
457
      if(!is_first || !skip_first){
741
457
        return p;
742
457
      }
743
0
      is_first = false;
744
0
    }
745
6.60k
    p = p->next;
746
6.60k
  }
747
606
  return NULL;
748
1.06k
}
749
750
751
BROKER_EXPORT int mosquitto_property_identifier(const mosquitto_property *property)
752
15.9k
{
753
15.9k
  if(property == NULL){
754
0
    return 0;
755
0
  }
756
757
15.9k
  return property->identifier;
758
15.9k
}
759
760
761
BROKER_EXPORT int mosquitto_property_type(const mosquitto_property *property)
762
0
{
763
0
  if(property == NULL){
764
0
    return 0;
765
0
  }
766
767
0
  return property->property_type;
768
0
}
769
770
771
BROKER_EXPORT mosquitto_property *mosquitto_property_next(const mosquitto_property *proplist)
772
15.0k
{
773
15.0k
  if(proplist == NULL){
774
0
    return NULL;
775
0
  }
776
777
15.0k
  return proplist->next;
778
15.0k
}
779
780
781
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_byte(const mosquitto_property *proplist, int identifier, uint8_t *value, bool skip_first)
782
146
{
783
146
  const mosquitto_property *p;
784
146
  if(!proplist){
785
4
    return NULL;
786
4
  }
787
788
142
  p = property__get_property(proplist, identifier, skip_first);
789
142
  if(!p){
790
110
    return NULL;
791
110
  }
792
32
  if(p->identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
793
32
      && p->identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION
794
32
      && p->identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION
795
32
      && p->identifier != MQTT_PROP_MAXIMUM_QOS
796
15
      && p->identifier != MQTT_PROP_RETAIN_AVAILABLE
797
0
      && p->identifier != MQTT_PROP_WILDCARD_SUB_AVAILABLE
798
0
      && p->identifier != MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE
799
0
      && p->identifier != MQTT_PROP_SHARED_SUB_AVAILABLE){
800
0
    return NULL;
801
0
  }
802
803
32
  if(value){
804
32
    *value = p->value.i8;
805
32
  }
806
807
32
  return p;
808
32
}
809
810
811
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_int16(const mosquitto_property *proplist, int identifier, uint16_t *value, bool skip_first)
812
219
{
813
219
  const mosquitto_property *p;
814
219
  if(!proplist){
815
6
    return NULL;
816
6
  }
817
818
213
  p = property__get_property(proplist, identifier, skip_first);
819
213
  if(!p){
820
140
    return NULL;
821
140
  }
822
73
  if(p->identifier != MQTT_PROP_SERVER_KEEP_ALIVE
823
54
      && p->identifier != MQTT_PROP_RECEIVE_MAXIMUM
824
29
      && p->identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM
825
0
      && p->identifier != MQTT_PROP_TOPIC_ALIAS){
826
0
    return NULL;
827
0
  }
828
829
73
  if(value){
830
73
    *value = p->value.i16;
831
73
  }
832
833
73
  return p;
834
73
}
835
836
837
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_int32(const mosquitto_property *proplist, int identifier, uint32_t *value, bool skip_first)
838
73
{
839
73
  const mosquitto_property *p;
840
73
  if(!proplist){
841
2
    return NULL;
842
2
  }
843
844
71
  p = property__get_property(proplist, identifier, skip_first);
845
71
  if(!p){
846
59
    return NULL;
847
59
  }
848
12
  if(p->identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL
849
12
      && p->identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL
850
12
      && p->identifier != MQTT_PROP_WILL_DELAY_INTERVAL
851
12
      && p->identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){
852
853
0
    return NULL;
854
0
  }
855
856
12
  if(value){
857
12
    *value = p->value.i32;
858
12
  }
859
860
12
  return p;
861
12
}
862
863
864
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_varint(const mosquitto_property *proplist, int identifier, uint32_t *value, bool skip_first)
865
154
{
866
154
  const mosquitto_property *p;
867
154
  if(!proplist){
868
105
    return NULL;
869
105
  }
870
871
49
  p = property__get_property(proplist, identifier, skip_first);
872
49
  if(!p){
873
9
    return NULL;
874
9
  }
875
40
  if(p->identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER){
876
0
    return NULL;
877
0
  }
878
879
40
  if(value){
880
40
    *value = p->value.varint;
881
40
  }
882
883
40
  return p;
884
40
}
885
886
887
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_binary(const mosquitto_property *proplist, int identifier, void **value, uint16_t *len, bool skip_first)
888
1.17k
{
889
1.17k
  const mosquitto_property *p;
890
1.17k
  if(!proplist || (value && !len) || (!value && len)){
891
880
    return NULL;
892
880
  }
893
894
294
  if(value){
895
294
    *value = NULL;
896
294
  }
897
898
294
  p = property__get_property(proplist, identifier, skip_first);
899
294
  if(!p){
900
147
    return NULL;
901
147
  }
902
147
  if(p->identifier != MQTT_PROP_CORRELATION_DATA
903
147
      && p->identifier != MQTT_PROP_AUTHENTICATION_DATA){
904
905
0
    return NULL;
906
0
  }
907
908
147
  if(value){
909
147
    *len = p->value.bin.len;
910
147
    if(p->value.bin.len){
911
83
      *value = mosquitto_calloc(1, *len + 1U);
912
83
      if(!(*value)){
913
0
        return NULL;
914
0
      }
915
916
83
      memcpy(*value, p->value.bin.v, *len);
917
83
    }else{
918
64
      *value = NULL;
919
64
    }
920
147
  }
921
922
147
  return p;
923
147
}
924
925
926
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_string(const mosquitto_property *proplist, int identifier, char **value, bool skip_first)
927
1.17k
{
928
1.17k
  const mosquitto_property *p;
929
1.17k
  if(!proplist){
930
880
    return NULL;
931
880
  }
932
933
294
  p = property__get_property(proplist, identifier, skip_first);
934
294
  if(!p){
935
141
    return NULL;
936
141
  }
937
153
  if(p->identifier != MQTT_PROP_CONTENT_TYPE
938
153
      && p->identifier != MQTT_PROP_RESPONSE_TOPIC
939
153
      && p->identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER
940
153
      && p->identifier != MQTT_PROP_AUTHENTICATION_METHOD
941
0
      && p->identifier != MQTT_PROP_RESPONSE_INFORMATION
942
0
      && p->identifier != MQTT_PROP_SERVER_REFERENCE
943
0
      && p->identifier != MQTT_PROP_REASON_STRING){
944
945
0
    return NULL;
946
0
  }
947
948
153
  if(value){
949
153
    if(p->value.s.len){
950
127
      *value = mosquitto_calloc(1, (size_t)p->value.s.len+1);
951
127
      if(!(*value)){
952
0
        return NULL;
953
0
      }
954
955
127
      memcpy(*value, p->value.s.v, p->value.s.len);
956
127
    }else{
957
26
      *value = NULL;
958
26
    }
959
153
  }
960
961
153
  return p;
962
153
}
963
964
965
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_string_pair(const mosquitto_property *proplist, int identifier, char **name, char **value, bool skip_first)
966
0
{
967
0
  const mosquitto_property *p;
968
0
  if(!proplist){
969
0
    return NULL;
970
0
  }
971
972
0
  if(name){
973
0
    *name = NULL;
974
0
  }
975
0
  if(value){
976
0
    *value = NULL;
977
0
  }
978
979
0
  p = property__get_property(proplist, identifier, skip_first);
980
0
  if(!p){
981
0
    return NULL;
982
0
  }
983
0
  if(p->identifier != MQTT_PROP_USER_PROPERTY){
984
0
    return NULL;
985
0
  }
986
987
0
  if(name){
988
0
    if(p->name.len){
989
0
      *name = mosquitto_calloc(1, (size_t)p->name.len+1);
990
0
      if(!(*name)){
991
0
        return NULL;
992
0
      }
993
0
      memcpy(*name, p->name.v, p->name.len);
994
0
    }else{
995
0
      *name = NULL;
996
0
    }
997
0
  }
998
999
0
  if(value){
1000
0
    if(p->value.s.len){
1001
0
      *value = mosquitto_calloc(1, (size_t)p->value.s.len+1);
1002
0
      if(!(*value)){
1003
0
        if(name){
1004
0
          mosquitto_FREE(*name);
1005
0
        }
1006
0
        return NULL;
1007
0
      }
1008
0
      memcpy(*value, p->value.s.v, p->value.s.len);
1009
0
    }else{
1010
0
      *value = NULL;
1011
0
    }
1012
0
  }
1013
1014
0
  return p;
1015
0
}
1016
1017
1018
BROKER_EXPORT int mosquitto_property_remove(mosquitto_property **proplist, const mosquitto_property *property)
1019
0
{
1020
0
  mosquitto_property *item, *item_prev = NULL;
1021
1022
0
  if(proplist == NULL || property == NULL){
1023
0
    return MOSQ_ERR_INVAL;
1024
0
  }
1025
1026
0
  item = *proplist;
1027
0
  while(item){
1028
0
    if(item == property){
1029
0
      if(item_prev == NULL){
1030
0
        *proplist = (*proplist)->next;
1031
0
      }else{
1032
0
        item_prev->next = item->next;
1033
0
      }
1034
0
      item->next = NULL;
1035
0
      return MOSQ_ERR_SUCCESS;
1036
0
    }
1037
0
    item_prev = item;
1038
0
    item = item->next;
1039
0
  }
1040
1041
0
  return MOSQ_ERR_NOT_FOUND;
1042
0
}
1043
1044
1045
BROKER_EXPORT int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_property *src)
1046
1.51k
{
1047
1.51k
  mosquitto_property *pnew, *plast = NULL;
1048
1049
1.51k
  if(!src){
1050
1.51k
    return MOSQ_ERR_SUCCESS;
1051
1.51k
  }
1052
0
  if(!dest){
1053
0
    return MOSQ_ERR_INVAL;
1054
0
  }
1055
1056
0
  *dest = NULL;
1057
1058
0
  while(src){
1059
0
    pnew = mosquitto_calloc(1, sizeof(mosquitto_property));
1060
0
    if(!pnew){
1061
0
      mosquitto_property_free_all(dest);
1062
0
      return MOSQ_ERR_NOMEM;
1063
0
    }
1064
0
    if(plast){
1065
0
      plast->next = pnew;
1066
0
    }else{
1067
0
      *dest = pnew;
1068
0
    }
1069
0
    plast = pnew;
1070
1071
0
    pnew->client_generated = src->client_generated;
1072
0
    pnew->identifier = src->identifier;
1073
0
    pnew->property_type = src->property_type;
1074
0
    switch(pnew->property_type){
1075
0
      case MQTT_PROP_TYPE_BYTE:
1076
0
        pnew->value.i8 = src->value.i8;
1077
0
        break;
1078
1079
0
      case MQTT_PROP_TYPE_INT16:
1080
0
        pnew->value.i16 = src->value.i16;
1081
0
        break;
1082
1083
0
      case MQTT_PROP_TYPE_INT32:
1084
0
        pnew->value.i32 = src->value.i32;
1085
0
        break;
1086
1087
0
      case MQTT_PROP_TYPE_VARINT:
1088
0
        pnew->value.varint = src->value.varint;
1089
0
        break;
1090
1091
0
      case MQTT_PROP_TYPE_STRING:
1092
0
        pnew->value.s.len = src->value.s.len;
1093
0
        pnew->value.s.v = src->value.s.v ? mosquitto_strdup(src->value.s.v) : (char *)mosquitto_calloc(1, 1);
1094
0
        if(!pnew->value.s.v){
1095
0
          mosquitto_property_free_all(dest);
1096
0
          return MOSQ_ERR_NOMEM;
1097
0
        }
1098
0
        break;
1099
1100
0
      case MQTT_PROP_TYPE_BINARY:
1101
0
        pnew->value.bin.len = src->value.bin.len;
1102
0
        if(src->value.bin.len){
1103
0
          pnew->value.bin.v = mosquitto_malloc(pnew->value.bin.len);
1104
0
          if(!pnew->value.bin.v){
1105
0
            mosquitto_property_free_all(dest);
1106
0
            return MOSQ_ERR_NOMEM;
1107
0
          }
1108
0
          memcpy(pnew->value.bin.v, src->value.bin.v, pnew->value.bin.len);
1109
0
        }
1110
0
        break;
1111
1112
0
      case MQTT_PROP_TYPE_STRING_PAIR:
1113
0
        pnew->value.s.len = src->value.s.len;
1114
0
        pnew->value.s.v = src->value.s.v ? mosquitto_strdup(src->value.s.v) : (char *)mosquitto_calloc(1, 1);
1115
0
        if(!pnew->value.s.v){
1116
0
          mosquitto_property_free_all(dest);
1117
0
          return MOSQ_ERR_NOMEM;
1118
0
        }
1119
1120
0
        pnew->name.len = src->name.len;
1121
0
        pnew->name.v = src->name.v ? mosquitto_strdup(src->name.v) : (char *)mosquitto_calloc(1, 1);
1122
0
        if(!pnew->name.v){
1123
0
          mosquitto_property_free_all(dest);
1124
0
          return MOSQ_ERR_NOMEM;
1125
0
        }
1126
0
        break;
1127
1128
0
      default:
1129
0
        mosquitto_property_free_all(dest);
1130
0
        return MOSQ_ERR_INVAL;
1131
0
    }
1132
1133
0
    src = mosquitto_property_next(src);
1134
0
  }
1135
1136
0
  return MOSQ_ERR_SUCCESS;
1137
0
}
1138
1139
1140
uint8_t mosquitto_property_byte_value(const mosquitto_property *property)
1141
313
{
1142
313
  if(property && property->property_type == MQTT_PROP_TYPE_BYTE){
1143
313
    return property->value.i8;
1144
313
  }else{
1145
0
    return 0;
1146
0
  }
1147
313
}
1148
1149
1150
uint16_t mosquitto_property_int16_value(const mosquitto_property *property)
1151
169
{
1152
169
  if(property && property->property_type == MQTT_PROP_TYPE_INT16){
1153
169
    return property->value.i16;
1154
169
  }else{
1155
0
    return 0;
1156
0
  }
1157
169
}
1158
1159
1160
uint32_t mosquitto_property_int32_value(const mosquitto_property *property)
1161
186
{
1162
186
  if(property && property->property_type == MQTT_PROP_TYPE_INT32){
1163
186
    return property->value.i32;
1164
186
  }else{
1165
0
    return 0;
1166
0
  }
1167
186
}
1168
1169
1170
uint32_t mosquitto_property_varint_value(const mosquitto_property *property)
1171
1.44k
{
1172
1.44k
  if(property && property->property_type == MQTT_PROP_TYPE_VARINT){
1173
1.44k
    return property->value.varint;
1174
1.44k
  }else{
1175
0
    return 0;
1176
0
  }
1177
1.44k
}
1178
1179
1180
const void *mosquitto_property_binary_value(const mosquitto_property *property)
1181
402
{
1182
402
  if(property && property->property_type == MQTT_PROP_TYPE_BINARY){
1183
402
    return property->value.bin.v;
1184
402
  }else{
1185
0
    return NULL;
1186
0
  }
1187
402
}
1188
1189
1190
uint16_t mosquitto_property_binary_value_length(const mosquitto_property *property)
1191
1.01k
{
1192
1.01k
  if(property && property->property_type == MQTT_PROP_TYPE_BINARY){
1193
1.01k
    return property->value.bin.len;
1194
1.01k
  }else{
1195
0
    return 0;
1196
0
  }
1197
1.01k
}
1198
1199
1200
const char *mosquitto_property_string_value(const mosquitto_property *property)
1201
894
{
1202
894
  if(property && (property->property_type == MQTT_PROP_TYPE_STRING || property->property_type == MQTT_PROP_TYPE_STRING_PAIR)){
1203
894
    return property->value.s.v;
1204
894
  }else{
1205
0
    return NULL;
1206
0
  }
1207
894
}
1208
1209
1210
uint16_t mosquitto_property_string_value_length(const mosquitto_property *property)
1211
0
{
1212
0
  if(property && (property->property_type == MQTT_PROP_TYPE_STRING || property->property_type == MQTT_PROP_TYPE_STRING_PAIR)){
1213
0
    return property->value.s.len;
1214
0
  }else{
1215
0
    return 0;
1216
0
  }
1217
0
}
1218
1219
1220
const char *mosquitto_property_string_name(const mosquitto_property *property)
1221
195
{
1222
195
  if(property && property->property_type == MQTT_PROP_TYPE_STRING_PAIR){
1223
195
    return property->name.v;
1224
195
  }else{
1225
0
    return NULL;
1226
0
  }
1227
195
}
1228
1229
1230
uint16_t mosquitto_property_string_name_length(const mosquitto_property *property)
1231
0
{
1232
0
  if(property && property->property_type == MQTT_PROP_TYPE_STRING_PAIR){
1233
0
    return property->name.len;
1234
0
  }else{
1235
0
    return 0;
1236
0
  }
1237
0
}
1238
1239
1240
/* Return the number of bytes we need to add on to the remaining length when
1241
 * encoding these properties. */
1242
unsigned int mosquitto_property_get_remaining_length(const mosquitto_property *props)
1243
1.62k
{
1244
1.62k
  unsigned int proplen, varbytes;
1245
1246
1.62k
  proplen = mosquitto_property_get_length_all(props);
1247
1.62k
  varbytes = mosquitto_varint_bytes(proplen);
1248
1.62k
  return proplen + varbytes;
1249
1.62k
}
1250
1251