Coverage Report

Created: 2026-08-25 07:15

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
36.5M
{
35
36.5M
  if(!property || !(*property)){
36
0
    return;
37
0
  }
38
39
36.5M
  switch((*property)->property_type){
40
1.02M
    case MQTT_PROP_TYPE_STRING:
41
1.02M
      mosquitto_FREE((*property)->value.s.v);
42
1.02M
      break;
43
44
2.86M
    case MQTT_PROP_TYPE_BINARY:
45
2.86M
      mosquitto_FREE((*property)->value.bin.v);
46
2.86M
      break;
47
48
17.4k
    case MQTT_PROP_TYPE_STRING_PAIR:
49
17.4k
      mosquitto_FREE((*property)->name.v);
50
17.4k
      mosquitto_FREE((*property)->value.s.v);
51
17.4k
      break;
52
53
29.5M
    case MQTT_PROP_TYPE_BYTE:
54
31.1M
    case MQTT_PROP_TYPE_INT16:
55
31.7M
    case MQTT_PROP_TYPE_INT32:
56
32.6M
    case MQTT_PROP_TYPE_VARINT:
57
      /* Nothing to free */
58
32.6M
      break;
59
36.5M
  }
60
61
36.5M
  mosquitto_FREE(*property);
62
36.5M
}
63
64
65
BROKER_EXPORT void mosquitto_property_free_all(mosquitto_property **property)
66
149k
{
67
149k
  mosquitto_property *p, *next;
68
69
149k
  if(!property){
70
0
    return;
71
0
  }
72
73
149k
  p = *property;
74
36.6M
  while(p){
75
36.5M
    next = p->next;
76
36.5M
    mosquitto_property_free(&p);
77
36.5M
    p = next;
78
36.5M
  }
79
149k
  *property = NULL;
80
149k
}
81
82
83
unsigned int mosquitto_property_get_length(const mosquitto_property *property)
84
2.33k
{
85
2.33k
  if(!property){
86
0
    return 0;
87
0
  }
88
89
2.33k
  switch(property->property_type){
90
2.33k
    case MQTT_PROP_TYPE_BYTE:
91
2.33k
      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.33k
  }
124
0
  return 0;
125
2.33k
}
126
127
128
unsigned int mosquitto_property_get_length_all(const mosquitto_property *property)
129
2.81k
{
130
2.81k
  const mosquitto_property *p;
131
2.81k
  unsigned int len = 0;
132
133
2.81k
  p = property;
134
5.15k
  while(p){
135
2.33k
    len += mosquitto_property_get_length(p);
136
2.33k
    p = p->next;
137
2.33k
  }
138
2.81k
  return len;
139
2.81k
}
140
141
142
BROKER_EXPORT int mosquitto_property_check_command(int command, int identifier)
143
23.9k
{
144
23.9k
  switch(identifier){
145
1.75k
    case MQTT_PROP_PAYLOAD_FORMAT_INDICATOR:
146
2.71k
    case MQTT_PROP_MESSAGE_EXPIRY_INTERVAL:
147
4.19k
    case MQTT_PROP_CONTENT_TYPE:
148
5.74k
    case MQTT_PROP_RESPONSE_TOPIC:
149
9.56k
    case MQTT_PROP_CORRELATION_DATA:
150
9.56k
      if(command != CMD_PUBLISH && command != CMD_WILL){
151
249
        return MOSQ_ERR_PROTOCOL;
152
249
      }
153
9.31k
      break;
154
155
9.31k
    case MQTT_PROP_SUBSCRIPTION_IDENTIFIER:
156
1.70k
      if(command != CMD_PUBLISH && command != CMD_SUBSCRIBE){
157
29
        return MOSQ_ERR_PROTOCOL;
158
29
      }
159
1.67k
      break;
160
161
1.67k
    case MQTT_PROP_SESSION_EXPIRY_INTERVAL:
162
96
      if(command != CMD_CONNECT && command != CMD_CONNACK && command != CMD_DISCONNECT){
163
15
        return MOSQ_ERR_PROTOCOL;
164
15
      }
165
81
      break;
166
167
178
    case MQTT_PROP_AUTHENTICATION_METHOD:
168
298
    case MQTT_PROP_AUTHENTICATION_DATA:
169
298
      if(command != CMD_CONNECT && command != CMD_CONNACK && command != CMD_AUTH){
170
61
        return MOSQ_ERR_PROTOCOL;
171
61
      }
172
237
      break;
173
174
237
    case MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER:
175
69
    case MQTT_PROP_SERVER_KEEP_ALIVE:
176
102
    case MQTT_PROP_RESPONSE_INFORMATION:
177
136
    case MQTT_PROP_MAXIMUM_QOS:
178
181
    case MQTT_PROP_RETAIN_AVAILABLE:
179
225
    case MQTT_PROP_WILDCARD_SUB_AVAILABLE:
180
272
    case MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE:
181
325
    case MQTT_PROP_SHARED_SUB_AVAILABLE:
182
325
      if(command != CMD_CONNACK){
183
171
        return MOSQ_ERR_PROTOCOL;
184
171
      }
185
154
      break;
186
187
154
    case MQTT_PROP_WILL_DELAY_INTERVAL:
188
26
      if(command != CMD_WILL){
189
13
        return MOSQ_ERR_PROTOCOL;
190
13
      }
191
13
      break;
192
193
86
    case MQTT_PROP_REQUEST_PROBLEM_INFORMATION:
194
176
    case MQTT_PROP_REQUEST_RESPONSE_INFORMATION:
195
176
      if(command != CMD_CONNECT){
196
43
        return MOSQ_ERR_PROTOCOL;
197
43
      }
198
133
      break;
199
200
133
    case MQTT_PROP_SERVER_REFERENCE:
201
74
      if(command != CMD_CONNACK && command != CMD_DISCONNECT){
202
46
        return MOSQ_ERR_PROTOCOL;
203
46
      }
204
28
      break;
205
206
153
    case MQTT_PROP_REASON_STRING:
207
153
      if(command == CMD_CONNECT || command == CMD_PUBLISH || command == CMD_SUBSCRIBE || command == CMD_UNSUBSCRIBE){
208
35
        return MOSQ_ERR_PROTOCOL;
209
35
      }
210
118
      break;
211
212
158
    case MQTT_PROP_RECEIVE_MAXIMUM:
213
311
    case MQTT_PROP_TOPIC_ALIAS_MAXIMUM:
214
726
    case MQTT_PROP_MAXIMUM_PACKET_SIZE:
215
726
      if(command != CMD_CONNECT && command != CMD_CONNACK){
216
336
        return MOSQ_ERR_PROTOCOL;
217
336
      }
218
390
      break;
219
220
1.19k
    case MQTT_PROP_TOPIC_ALIAS:
221
1.19k
      if(command != CMD_PUBLISH){
222
45
        return MOSQ_ERR_PROTOCOL;
223
45
      }
224
1.14k
      break;
225
226
9.62k
    case MQTT_PROP_USER_PROPERTY:
227
9.62k
      break;
228
229
0
    default:
230
0
      return MOSQ_ERR_PROTOCOL;
231
23.9k
  }
232
22.9k
  return MOSQ_ERR_SUCCESS;
233
23.9k
}
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
10.7k
{
395
10.7k
  mosquitto_property *p;
396
397
10.7k
  if(!(*proplist)){
398
1.70k
    *proplist = prop;
399
1.70k
  }
400
401
10.7k
  p = *proplist;
402
380k
  while(p->next){
403
370k
    p = p->next;
404
370k
  }
405
10.7k
  p->next = prop;
406
10.7k
  prop->next = NULL;
407
10.7k
}
408
409
410
BROKER_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value)
411
3.74k
{
412
3.74k
  mosquitto_property *prop;
413
414
3.74k
  if(!proplist){
415
0
    return MOSQ_ERR_INVAL;
416
0
  }
417
3.74k
  if(identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
418
2.93k
      && identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION
419
2.73k
      && identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION
420
2.54k
      && identifier != MQTT_PROP_MAXIMUM_QOS
421
1.17k
      && identifier != MQTT_PROP_RETAIN_AVAILABLE
422
980
      && identifier != MQTT_PROP_WILDCARD_SUB_AVAILABLE
423
786
      && identifier != MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE
424
592
      && identifier != MQTT_PROP_SHARED_SUB_AVAILABLE){
425
398
    return MOSQ_ERR_INVAL;
426
398
  }
427
428
3.34k
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
429
3.34k
  if(!prop){
430
0
    return MOSQ_ERR_NOMEM;
431
0
  }
432
433
3.34k
  prop->client_generated = true;
434
3.34k
  prop->identifier = identifier;
435
3.34k
  prop->value.i8 = value;
436
3.34k
  prop->property_type = MQTT_PROP_TYPE_BYTE;
437
438
3.34k
  property__add(proplist, prop);
439
3.34k
  return MOSQ_ERR_SUCCESS;
440
3.34k
}
441
442
443
BROKER_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value)
444
1.31k
{
445
1.31k
  mosquitto_property *prop;
446
447
1.31k
  if(!proplist){
448
0
    return MOSQ_ERR_INVAL;
449
0
  }
450
1.31k
  if(identifier != MQTT_PROP_SERVER_KEEP_ALIVE
451
1.09k
      && identifier != MQTT_PROP_RECEIVE_MAXIMUM
452
748
      && identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM
453
549
      && identifier != MQTT_PROP_TOPIC_ALIAS){
454
315
    return MOSQ_ERR_INVAL;
455
315
  }
456
457
1.00k
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
458
1.00k
  if(!prop){
459
0
    return MOSQ_ERR_NOMEM;
460
0
  }
461
462
1.00k
  prop->client_generated = true;
463
1.00k
  prop->identifier = identifier;
464
1.00k
  prop->value.i16 = value;
465
1.00k
  prop->property_type = MQTT_PROP_TYPE_INT16;
466
467
1.00k
  property__add(proplist, prop);
468
1.00k
  return MOSQ_ERR_SUCCESS;
469
1.00k
}
470
471
472
BROKER_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value)
473
1.47k
{
474
1.47k
  mosquitto_property *prop;
475
476
1.47k
  if(!proplist){
477
0
    return MOSQ_ERR_INVAL;
478
0
  }
479
1.47k
  if(identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL
480
1.05k
      && identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL
481
857
      && identifier != MQTT_PROP_WILL_DELAY_INTERVAL
482
663
      && identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){
483
484
469
    return MOSQ_ERR_INVAL;
485
469
  }
486
487
1.00k
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
488
1.00k
  if(!prop){
489
0
    return MOSQ_ERR_NOMEM;
490
0
  }
491
492
1.00k
  prop->client_generated = true;
493
1.00k
  prop->identifier = identifier;
494
1.00k
  prop->value.i32 = value;
495
1.00k
  prop->property_type = MQTT_PROP_TYPE_INT32;
496
497
1.00k
  property__add(proplist, prop);
498
1.00k
  return MOSQ_ERR_SUCCESS;
499
1.00k
}
500
501
502
BROKER_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value)
503
791
{
504
791
  mosquitto_property *prop;
505
506
791
  if(!proplist || value > MQTT_MAX_PAYLOAD){
507
200
    return MOSQ_ERR_INVAL;
508
200
  }
509
591
  if(identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER){
510
331
    return MOSQ_ERR_INVAL;
511
331
  }
512
513
260
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
514
260
  if(!prop){
515
0
    return MOSQ_ERR_NOMEM;
516
0
  }
517
518
260
  prop->client_generated = true;
519
260
  prop->identifier = identifier;
520
260
  prop->value.varint = value;
521
260
  prop->property_type = MQTT_PROP_TYPE_VARINT;
522
523
260
  property__add(proplist, prop);
524
260
  return MOSQ_ERR_SUCCESS;
525
260
}
526
527
528
BROKER_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len)
529
2.33k
{
530
2.33k
  mosquitto_property *prop;
531
532
2.33k
  if(!proplist){
533
0
    return MOSQ_ERR_INVAL;
534
0
  }
535
2.33k
  if(identifier != MQTT_PROP_CORRELATION_DATA
536
669
      && identifier != MQTT_PROP_AUTHENTICATION_DATA){
537
538
470
    return MOSQ_ERR_INVAL;
539
470
  }
540
541
1.86k
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
542
1.86k
  if(!prop){
543
0
    return MOSQ_ERR_NOMEM;
544
0
  }
545
546
1.86k
  prop->client_generated = true;
547
1.86k
  prop->identifier = identifier;
548
1.86k
  prop->property_type = MQTT_PROP_TYPE_BINARY;
549
550
1.86k
  if(len){
551
1.16k
    prop->value.bin.v = mosquitto_malloc(len);
552
1.16k
    if(!prop->value.bin.v){
553
0
      mosquitto_FREE(prop);
554
0
      return MOSQ_ERR_NOMEM;
555
0
    }
556
557
1.16k
    memcpy(prop->value.bin.v, value, len);
558
1.16k
    prop->value.bin.len = len;
559
1.16k
  }
560
561
1.86k
  property__add(proplist, prop);
562
1.86k
  return MOSQ_ERR_SUCCESS;
563
1.86k
}
564
565
566
BROKER_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value)
567
4.99k
{
568
4.99k
  mosquitto_property *prop;
569
4.99k
  size_t slen = 0;
570
571
4.99k
  if(!proplist){
572
0
    return MOSQ_ERR_INVAL;
573
0
  }
574
4.99k
  if(value){
575
4.99k
    slen = strlen(value);
576
4.99k
    if(mosquitto_validate_utf8(value, (int)slen)){
577
1.87k
      return MOSQ_ERR_MALFORMED_UTF8;
578
1.87k
    }
579
4.99k
  }
580
581
3.12k
  if(identifier != MQTT_PROP_CONTENT_TYPE
582
2.15k
      && identifier != MQTT_PROP_RESPONSE_TOPIC
583
1.50k
      && identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER
584
1.30k
      && identifier != MQTT_PROP_AUTHENTICATION_METHOD
585
1.11k
      && identifier != MQTT_PROP_RESPONSE_INFORMATION
586
917
      && identifier != MQTT_PROP_SERVER_REFERENCE
587
722
      && identifier != MQTT_PROP_REASON_STRING){
588
589
527
    return MOSQ_ERR_INVAL;
590
527
  }
591
592
2.59k
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
593
2.59k
  if(!prop){
594
0
    return MOSQ_ERR_NOMEM;
595
0
  }
596
597
2.59k
  prop->client_generated = true;
598
2.59k
  prop->identifier = identifier;
599
2.59k
  prop->property_type = MQTT_PROP_TYPE_STRING;
600
2.59k
  if(value && slen > 0){
601
544
    prop->value.s.v = mosquitto_strdup(value);
602
544
    if(!prop->value.s.v){
603
0
      mosquitto_FREE(prop);
604
0
      return MOSQ_ERR_NOMEM;
605
0
    }
606
544
    prop->value.s.len = (uint16_t)slen;
607
544
  }
608
609
2.59k
  property__add(proplist, prop);
610
2.59k
  return MOSQ_ERR_SUCCESS;
611
2.59k
}
612
613
614
BROKER_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value)
615
1.52k
{
616
1.52k
  mosquitto_property *prop;
617
1.52k
  size_t slen_name = 0, slen_value = 0;
618
619
1.52k
  if(!proplist){
620
0
    return MOSQ_ERR_INVAL;
621
0
  }
622
1.52k
  if(identifier != MQTT_PROP_USER_PROPERTY){
623
609
    return MOSQ_ERR_INVAL;
624
609
  }
625
914
  if(name){
626
914
    slen_name = strlen(name);
627
914
    if(mosquitto_validate_utf8(name, (int)slen_name)){
628
214
      return MOSQ_ERR_MALFORMED_UTF8;
629
214
    }
630
914
  }
631
700
  if(value){
632
700
    if(mosquitto_validate_utf8(value, (int)slen_value)){
633
0
      return MOSQ_ERR_MALFORMED_UTF8;
634
0
    }
635
700
  }
636
637
700
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
638
700
  if(!prop){
639
0
    return MOSQ_ERR_NOMEM;
640
0
  }
641
642
700
  prop->client_generated = true;
643
700
  prop->identifier = identifier;
644
700
  prop->property_type = MQTT_PROP_TYPE_STRING_PAIR;
645
646
700
  if(name){
647
700
    prop->name.v = mosquitto_strdup(name);
648
700
    if(!prop->name.v){
649
0
      mosquitto_FREE(prop);
650
0
      return MOSQ_ERR_NOMEM;
651
0
    }
652
700
    prop->name.len = (uint16_t)strlen(name);
653
700
  }
654
655
700
  if(value){
656
700
    prop->value.s.v = mosquitto_strdup(value);
657
700
    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
700
    prop->value.s.len = (uint16_t)strlen(value);
663
700
  }
664
665
700
  property__add(proplist, prop);
666
700
  return MOSQ_ERR_SUCCESS;
667
700
}
668
669
670
BROKER_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties)
671
13.1k
{
672
13.1k
  const mosquitto_property *p, *tail;
673
13.1k
  int rc;
674
675
13.1k
  p = properties;
676
677
36.0k
  while(p){
678
    /* Validity checks */
679
24.1k
    if(p->identifier == MQTT_PROP_REQUEST_PROBLEM_INFORMATION
680
24.0k
        || p->identifier == MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
681
22.2k
        || p->identifier == MQTT_PROP_REQUEST_RESPONSE_INFORMATION
682
22.1k
        || p->identifier == MQTT_PROP_MAXIMUM_QOS
683
22.1k
        || p->identifier == MQTT_PROP_RETAIN_AVAILABLE
684
22.0k
        || p->identifier == MQTT_PROP_WILDCARD_SUB_AVAILABLE
685
22.0k
        || p->identifier == MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE
686
21.9k
        || p->identifier == MQTT_PROP_SHARED_SUB_AVAILABLE){
687
688
2.26k
      if(p->value.i8 > 1){
689
104
        return MOSQ_ERR_PROTOCOL;
690
104
      }
691
21.8k
    }else if(p->identifier == MQTT_PROP_MAXIMUM_PACKET_SIZE){
692
425
      if(p->value.i32 == 0){
693
10
        return MOSQ_ERR_PROTOCOL;
694
10
      }
695
21.4k
    }else if(p->identifier == MQTT_PROP_RECEIVE_MAXIMUM
696
21.2k
        || p->identifier == MQTT_PROP_TOPIC_ALIAS){
697
698
1.36k
      if(p->value.i16 == 0){
699
10
        return MOSQ_ERR_PROTOCOL;
700
10
      }
701
20.0k
    }else if(p->identifier == MQTT_PROP_RESPONSE_TOPIC){
702
1.60k
      if(mosquitto_pub_topic_check(p->value.s.v) != MOSQ_ERR_SUCCESS){
703
54
        return MOSQ_ERR_PROTOCOL;
704
54
      }
705
1.60k
    }
706
707
    /* Check for properties on incorrect commands */
708
23.9k
    rc = mosquitto_property_check_command(command, p->identifier);
709
23.9k
    if(rc){
710
1.04k
      return rc;
711
1.04k
    }
712
713
    /* Check for duplicates */
714
22.9k
    if(p->identifier != MQTT_PROP_USER_PROPERTY){
715
13.2k
      tail = p->next;
716
31.9k
      while(tail){
717
18.6k
        if(p->identifier == tail->identifier){
718
28
          return MOSQ_ERR_DUPLICATE_PROPERTY;
719
28
        }
720
18.6k
        tail = tail->next;
721
18.6k
      }
722
13.2k
    }
723
724
22.8k
    p = p->next;
725
22.8k
  }
726
727
11.9k
  return MOSQ_ERR_SUCCESS;
728
13.1k
}
729
730
731
static const mosquitto_property *property__get_property(const mosquitto_property *proplist, int identifier, bool skip_first)
732
1.11k
{
733
1.11k
  const mosquitto_property *p;
734
1.11k
  bool is_first = true;
735
736
1.11k
  p = proplist;
737
738
8.92k
  while(p){
739
8.18k
    if(p->identifier == identifier){
740
372
      if(!is_first || !skip_first){
741
372
        return p;
742
372
      }
743
0
      is_first = false;
744
0
    }
745
7.81k
    p = p->next;
746
7.81k
  }
747
741
  return NULL;
748
1.11k
}
749
750
751
BROKER_EXPORT int mosquitto_property_identifier(const mosquitto_property *property)
752
20.3k
{
753
20.3k
  if(property == NULL){
754
0
    return 0;
755
0
  }
756
757
20.3k
  return property->identifier;
758
20.3k
}
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
29.8k
{
773
29.8k
  if(proplist == NULL){
774
0
    return NULL;
775
0
  }
776
777
29.8k
  return proplist->next;
778
29.8k
}
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
262
{
783
262
  const mosquitto_property *p;
784
262
  if(!proplist){
785
86
    return NULL;
786
86
  }
787
788
176
  p = property__get_property(proplist, identifier, skip_first);
789
176
  if(!p){
790
142
    return NULL;
791
142
  }
792
34
  if(p->identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
793
34
      && p->identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION
794
34
      && p->identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION
795
34
      && p->identifier != MQTT_PROP_MAXIMUM_QOS
796
18
      && 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
34
  if(value){
804
34
    *value = p->value.i8;
805
34
  }
806
807
34
  return p;
808
34
}
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
393
{
813
393
  const mosquitto_property *p;
814
393
  if(!proplist){
815
129
    return NULL;
816
129
  }
817
818
264
  p = property__get_property(proplist, identifier, skip_first);
819
264
  if(!p){
820
179
    return NULL;
821
179
  }
822
85
  if(p->identifier != MQTT_PROP_SERVER_KEEP_ALIVE
823
67
      && p->identifier != MQTT_PROP_RECEIVE_MAXIMUM
824
37
      && p->identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM
825
0
      && p->identifier != MQTT_PROP_TOPIC_ALIAS){
826
0
    return NULL;
827
0
  }
828
829
85
  if(value){
830
85
    *value = p->value.i16;
831
85
  }
832
833
85
  return p;
834
85
}
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
131
{
839
131
  const mosquitto_property *p;
840
131
  if(!proplist){
841
43
    return NULL;
842
43
  }
843
844
88
  p = property__get_property(proplist, identifier, skip_first);
845
88
  if(!p){
846
80
    return NULL;
847
80
  }
848
8
  if(p->identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL
849
8
      && p->identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL
850
8
      && p->identifier != MQTT_PROP_WILL_DELAY_INTERVAL
851
8
      && p->identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){
852
853
0
    return NULL;
854
0
  }
855
856
8
  if(value){
857
8
    *value = p->value.i32;
858
8
  }
859
860
8
  return p;
861
8
}
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
248
{
866
248
  const mosquitto_property *p;
867
248
  if(!proplist){
868
143
    return NULL;
869
143
  }
870
871
105
  p = property__get_property(proplist, identifier, skip_first);
872
105
  if(!p){
873
28
    return NULL;
874
28
  }
875
77
  if(p->identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER){
876
0
    return NULL;
877
0
  }
878
879
77
  if(value){
880
77
    *value = p->value.varint;
881
77
  }
882
883
77
  return p;
884
77
}
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.04k
{
889
1.04k
  const mosquitto_property *p;
890
1.04k
  if(!proplist || (value && !len) || (!value && len)){
891
840
    return NULL;
892
840
  }
893
894
202
  if(value){
895
202
    *value = NULL;
896
202
  }
897
898
202
  p = property__get_property(proplist, identifier, skip_first);
899
202
  if(!p){
900
145
    return NULL;
901
145
  }
902
57
  if(p->identifier != MQTT_PROP_CORRELATION_DATA
903
57
      && p->identifier != MQTT_PROP_AUTHENTICATION_DATA){
904
905
0
    return NULL;
906
0
  }
907
908
57
  if(value){
909
57
    *len = p->value.bin.len;
910
57
    if(p->value.bin.len){
911
26
      *value = mosquitto_calloc(1, *len + 1U);
912
26
      if(!(*value)){
913
0
        return NULL;
914
0
      }
915
916
26
      memcpy(*value, p->value.bin.v, *len);
917
31
    }else{
918
31
      *value = NULL;
919
31
    }
920
57
  }
921
922
57
  return p;
923
57
}
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.11k
{
928
1.11k
  const mosquitto_property *p;
929
1.11k
  if(!proplist){
930
841
    return NULL;
931
841
  }
932
933
278
  p = property__get_property(proplist, identifier, skip_first);
934
278
  if(!p){
935
167
    return NULL;
936
167
  }
937
111
  if(p->identifier != MQTT_PROP_CONTENT_TYPE
938
111
      && p->identifier != MQTT_PROP_RESPONSE_TOPIC
939
111
      && p->identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER
940
111
      && 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
111
  if(value){
949
111
    if(p->value.s.len){
950
80
      *value = mosquitto_calloc(1, (size_t)p->value.s.len+1);
951
80
      if(!(*value)){
952
0
        return NULL;
953
0
      }
954
955
80
      memcpy(*value, p->value.s.v, p->value.s.len);
956
80
    }else{
957
31
      *value = NULL;
958
31
    }
959
111
  }
960
961
111
  return p;
962
111
}
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
2.87k
{
1047
2.87k
  mosquitto_property *pnew, *plast = NULL;
1048
1049
2.87k
  if(!src){
1050
2.34k
    return MOSQ_ERR_SUCCESS;
1051
2.34k
  }
1052
533
  if(!dest){
1053
0
    return MOSQ_ERR_INVAL;
1054
0
  }
1055
1056
533
  *dest = NULL;
1057
1058
10.1k
  while(src){
1059
9.60k
    pnew = mosquitto_calloc(1, sizeof(mosquitto_property));
1060
9.60k
    if(!pnew){
1061
0
      mosquitto_property_free_all(dest);
1062
0
      return MOSQ_ERR_NOMEM;
1063
0
    }
1064
9.60k
    if(plast){
1065
9.06k
      plast->next = pnew;
1066
9.06k
    }else{
1067
533
      *dest = pnew;
1068
533
    }
1069
9.60k
    plast = pnew;
1070
1071
9.60k
    pnew->client_generated = src->client_generated;
1072
9.60k
    pnew->identifier = src->identifier;
1073
9.60k
    pnew->property_type = src->property_type;
1074
9.60k
    switch(pnew->property_type){
1075
2.16k
      case MQTT_PROP_TYPE_BYTE:
1076
2.16k
        pnew->value.i8 = src->value.i8;
1077
2.16k
        break;
1078
1079
1.00k
      case MQTT_PROP_TYPE_INT16:
1080
1.00k
        pnew->value.i16 = src->value.i16;
1081
1.00k
        break;
1082
1083
1.00k
      case MQTT_PROP_TYPE_INT32:
1084
1.00k
        pnew->value.i32 = src->value.i32;
1085
1.00k
        break;
1086
1087
260
      case MQTT_PROP_TYPE_VARINT:
1088
260
        pnew->value.varint = src->value.varint;
1089
260
        break;
1090
1091
2.59k
      case MQTT_PROP_TYPE_STRING:
1092
2.59k
        pnew->value.s.len = src->value.s.len;
1093
2.59k
        pnew->value.s.v = src->value.s.v ? mosquitto_strdup(src->value.s.v) : (char *)mosquitto_calloc(1, 1);
1094
2.59k
        if(!pnew->value.s.v){
1095
0
          mosquitto_property_free_all(dest);
1096
0
          return MOSQ_ERR_NOMEM;
1097
0
        }
1098
2.59k
        break;
1099
1100
2.59k
      case MQTT_PROP_TYPE_BINARY:
1101
1.86k
        pnew->value.bin.len = src->value.bin.len;
1102
1.86k
        if(src->value.bin.len){
1103
1.16k
          pnew->value.bin.v = mosquitto_malloc(pnew->value.bin.len);
1104
1.16k
          if(!pnew->value.bin.v){
1105
0
            mosquitto_property_free_all(dest);
1106
0
            return MOSQ_ERR_NOMEM;
1107
0
          }
1108
1.16k
          memcpy(pnew->value.bin.v, src->value.bin.v, pnew->value.bin.len);
1109
1.16k
        }
1110
1.86k
        break;
1111
1112
1.86k
      case MQTT_PROP_TYPE_STRING_PAIR:
1113
700
        pnew->value.s.len = src->value.s.len;
1114
700
        pnew->value.s.v = src->value.s.v ? mosquitto_strdup(src->value.s.v) : (char *)mosquitto_calloc(1, 1);
1115
700
        if(!pnew->value.s.v){
1116
0
          mosquitto_property_free_all(dest);
1117
0
          return MOSQ_ERR_NOMEM;
1118
0
        }
1119
1120
700
        pnew->name.len = src->name.len;
1121
700
        pnew->name.v = src->name.v ? mosquitto_strdup(src->name.v) : (char *)mosquitto_calloc(1, 1);
1122
700
        if(!pnew->name.v){
1123
0
          mosquitto_property_free_all(dest);
1124
0
          return MOSQ_ERR_NOMEM;
1125
0
        }
1126
700
        break;
1127
1128
700
      default:
1129
0
        mosquitto_property_free_all(dest);
1130
0
        return MOSQ_ERR_INVAL;
1131
9.60k
    }
1132
1133
9.60k
    src = mosquitto_property_next(src);
1134
9.60k
  }
1135
1136
533
  return MOSQ_ERR_SUCCESS;
1137
533
}
1138
1139
1140
uint8_t mosquitto_property_byte_value(const mosquitto_property *property)
1141
539
{
1142
539
  if(property && property->property_type == MQTT_PROP_TYPE_BYTE){
1143
539
    return property->value.i8;
1144
539
  }else{
1145
0
    return 0;
1146
0
  }
1147
539
}
1148
1149
1150
uint16_t mosquitto_property_int16_value(const mosquitto_property *property)
1151
192
{
1152
192
  if(property && property->property_type == MQTT_PROP_TYPE_INT16){
1153
192
    return property->value.i16;
1154
192
  }else{
1155
0
    return 0;
1156
0
  }
1157
192
}
1158
1159
1160
uint32_t mosquitto_property_int32_value(const mosquitto_property *property)
1161
282
{
1162
282
  if(property && property->property_type == MQTT_PROP_TYPE_INT32){
1163
282
    return property->value.i32;
1164
282
  }else{
1165
0
    return 0;
1166
0
  }
1167
282
}
1168
1169
1170
uint32_t mosquitto_property_varint_value(const mosquitto_property *property)
1171
1.37k
{
1172
1.37k
  if(property && property->property_type == MQTT_PROP_TYPE_VARINT){
1173
1.37k
    return property->value.varint;
1174
1.37k
  }else{
1175
0
    return 0;
1176
0
  }
1177
1.37k
}
1178
1179
1180
const void *mosquitto_property_binary_value(const mosquitto_property *property)
1181
2.86k
{
1182
2.86k
  if(property && property->property_type == MQTT_PROP_TYPE_BINARY){
1183
2.86k
    return property->value.bin.v;
1184
2.86k
  }else{
1185
0
    return NULL;
1186
0
  }
1187
2.86k
}
1188
1189
1190
uint16_t mosquitto_property_binary_value_length(const mosquitto_property *property)
1191
8.65k
{
1192
8.65k
  if(property && property->property_type == MQTT_PROP_TYPE_BINARY){
1193
8.65k
    return property->value.bin.len;
1194
8.65k
  }else{
1195
0
    return 0;
1196
0
  }
1197
8.65k
}
1198
1199
1200
const char *mosquitto_property_string_value(const mosquitto_property *property)
1201
1.00k
{
1202
1.00k
  if(property && (property->property_type == MQTT_PROP_TYPE_STRING || property->property_type == MQTT_PROP_TYPE_STRING_PAIR)){
1203
1.00k
    return property->value.s.v;
1204
1.00k
  }else{
1205
0
    return NULL;
1206
0
  }
1207
1.00k
}
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
307
{
1222
307
  if(property && property->property_type == MQTT_PROP_TYPE_STRING_PAIR){
1223
307
    return property->name.v;
1224
307
  }else{
1225
0
    return NULL;
1226
0
  }
1227
307
}
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.41k
{
1244
1.41k
  unsigned int proplen, varbytes;
1245
1246
1.41k
  proplen = mosquitto_property_get_length_all(props);
1247
1.41k
  varbytes = mosquitto_varint_bytes(proplen);
1248
1.41k
  return proplen + varbytes;
1249
1.41k
}
1250
1251