libcoap 4.3.1
uri.c
Go to the documentation of this file.
1/* uri.c -- helper functions for URI treatment
2 *
3 * Copyright (C) 2010--2012,2015-2016 Olaf Bergmann <bergmann@tzi.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 *
7 * This file is part of the CoAP library libcoap. Please see
8 * README for terms of use.
9 */
10
16#include "coap3/coap_internal.h"
17
18#if defined(HAVE_LIMITS_H)
19#include <limits.h>
20#endif
21
22#include <stdint.h>
23#include <stdio.h>
24#include <string.h>
25#include <ctype.h>
26
38COAP_STATIC_INLINE const uint8_t *
39strnchr(const uint8_t *s, size_t len, unsigned char c) {
40 while (len && *s++ != c)
41 --len;
42
43 return len ? s : NULL;
44}
45
46#define ISEQUAL_CI(a,b) \
47 ((a) == (b) || (islower(b) && ((a) == ((b) - 0x20))))
48
49typedef enum coap_uri_check_t {
53
54static int
55coap_split_uri_sub(const uint8_t *str_var,
56 size_t len,
57 coap_uri_t *uri,
58 coap_uri_check_t check_proxy) {
59 const uint8_t *p, *q;
60 int res = 0;
61 int is_http_proxy_scheme = 0;
62 size_t keep_len = len;
63
64 if (!str_var || !uri || len == 0)
65 return -1;
66
67 memset(uri, 0, sizeof(coap_uri_t));
69
70 /* search for scheme */
71 p = str_var;
72 if (*p == '/') {
73 if (check_proxy == COAP_URI_CHECK_PROXY)
74 return -1;
75 q = p;
76 goto path;
77 }
78
79 q = (const uint8_t *)COAP_DEFAULT_SCHEME;
80 while (len && *q && ISEQUAL_CI(*p, *q)) {
81 ++p; ++q; --len;
82 }
83 if (*q && check_proxy == COAP_URI_CHECK_PROXY) {
84 /* Scheme could be something other than coap */
85 len = keep_len;
86 p = str_var;
87 q = (const uint8_t *)"http";
88 while (len && *q && ISEQUAL_CI(*p, *q)) {
89 ++p; ++q; --len;
90 }
91 if (*q == 0) {
92 if (len && ISEQUAL_CI(*p, 's')) {
93 /* https:// */
94 ++p; --len;
96 uri->port = 443;
97 }
98 else {
99 /* http:// */
101 uri->port = 80;
102 }
103 }
104 else {
105 /* Unknown scheme */
106 res = -1;
107 goto error;
108 }
109 is_http_proxy_scheme = 1;
110 }
111
112 /* If q does not point to the string end marker '\0', the schema
113 * identifier is wrong. */
114 if (*q) {
115 res = -1;
116 goto error;
117 }
118
119 if (is_http_proxy_scheme == 0) {
120 /* There might be an additional 's', indicating the secure version: */
121 if (len && (*p == 's')) {
122 ++p; --len;
125 } else {
127 }
128
129 /* There might be an addition "+tcp", indicating reliable transport: */
130 if (len>=4 && p[0] == '+' && p[1] == 't' && p[2] == 'c' && p[3] == 'p' ) {
131 p += 4;
132 len -= 4;
133 if (uri->scheme == COAP_URI_SCHEME_COAPS)
135 else
137 }
138 }
139 q = (const uint8_t *)"://";
140 while (len && *q && *p == *q) {
141 ++p; ++q; --len;
142 }
143
144 if (*q) {
145 res = -2;
146 goto error;
147 }
148
149 /* p points to beginning of Uri-Host */
150 q = p;
151 if (len && *p == '[') { /* IPv6 address reference */
152 ++p;
153
154 while (len && *q != ']') {
155 ++q; --len;
156 }
157
158 if (!len || *q != ']' || p == q) {
159 res = -3;
160 goto error;
161 }
162
163 COAP_SET_STR(&uri->host, q - p, p);
164 ++q; --len;
165 } else { /* IPv4 address or FQDN */
166 while (len && *q != ':' && *q != '/' && *q != '?') {
167 ++q;
168 --len;
169 }
170
171 if (p == q) {
172 res = -3;
173 goto error;
174 }
175
176 COAP_SET_STR(&uri->host, q - p, p);
177 }
178
179 /* check for Uri-Port */
180 if (len && *q == ':') {
181 p = ++q;
182 --len;
183
184 while (len && isdigit(*q)) {
185 ++q;
186 --len;
187 }
188
189 if (p < q) { /* explicit port number given */
190 int uri_port = 0;
191
192 while ((p < q) && (uri_port <= UINT16_MAX))
193 uri_port = uri_port * 10 + (*p++ - '0');
194
195 /* check if port number is in allowed range */
196 if (uri_port > UINT16_MAX) {
197 res = -4;
198 goto error;
199 }
200
201 uri->port = (uint16_t)uri_port;
202 }
203 }
204
205 path: /* at this point, p must point to an absolute path */
206
207 if (!len)
208 goto end;
209
210 if (*q == '/') {
211 p = ++q;
212 --len;
213
214 while (len && *q != '?') {
215 ++q;
216 --len;
217 }
218
219 if (p < q) {
220 COAP_SET_STR(&uri->path, q - p, p);
221 p = q;
222 }
223 }
224
225 /* Uri_Query */
226 if (len && *p == '?') {
227 ++p;
228 --len;
229 COAP_SET_STR(&uri->query, len, p);
230 len = 0;
231 }
232
233 end:
234 return len ? -1 : 0;
235
236 error:
237 return res;
238}
239
240int
241coap_split_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri) {
242 return coap_split_uri_sub(str_var, len, uri, COAP_URI_CHECK_URI);
243}
244
245int
246coap_split_proxy_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri) {
247 return coap_split_uri_sub(str_var, len, uri, COAP_URI_CHECK_PROXY);
248}
249
250int
252 coap_optlist_t **optlist_chain, int create_port_opt,
253 uint8_t *_buf, size_t _buflen) {
254 int res;
255 unsigned char *buf = _buf;
256 size_t buflen = _buflen;
257
258 if (uri->port != (coap_uri_scheme_is_secure(uri) ?
259 COAPS_DEFAULT_PORT : COAP_DEFAULT_PORT) && create_port_opt) {
260 coap_insert_optlist(optlist_chain,
263 (uri->port & 0xffff)),
264 buf));
265 }
266
267 if (uri->path.length) {
268 if (uri->path.length > buflen)
269 coap_log_warn("URI path will be truncated (max buffer %zu)\n",
270 buflen);
271 res = coap_split_path(uri->path.s, uri->path.length, buf, &buflen);
272 if (res < 0)
273 return -1;
274
275 while (res--) {
276 coap_insert_optlist(optlist_chain,
278 coap_opt_length(buf),
279 coap_opt_value(buf)));
280
281 buf += coap_opt_size(buf);
282 }
283 }
284
285 if (uri->query.length) {
286 buflen = _buflen;
287 buf = _buf;
288 if (uri->query.length > buflen)
289 coap_log_warn("URI query will be truncated (max buffer %zu)\n",
290 buflen);
291 res = coap_split_query(uri->query.s, uri->query.length, buf, &buflen);
292 if (res < 0)
293 return -1;
294
295 while (res--) {
296 coap_insert_optlist(optlist_chain,
298 coap_opt_length(buf),
299 coap_opt_value(buf)));
300
301 buf += coap_opt_size(buf);
302 }
303 }
304 return 0;
305}
306
314#define hexchar_to_dec(c) ((c) & 0x40 ? ((c) & 0x0F) + 9 : ((c) & 0x0F))
315
328static void
329decode_segment(const uint8_t *seg, size_t length, unsigned char *buf) {
330
331 while (length--) {
332
333 if (*seg == '%') {
334 *buf = (hexchar_to_dec(seg[1]) << 4) + hexchar_to_dec(seg[2]);
335
336 seg += 2; length -= 2;
337 } else {
338 *buf = *seg;
339 }
340
341 ++buf; ++seg;
342 }
343}
344
350static int
351check_segment(const uint8_t *s, size_t length, size_t *segment_size) {
352 size_t n = 0;
353
354 while (length) {
355 if (*s == '%') {
356 if (length < 2 || !(isxdigit(s[1]) && isxdigit(s[2])))
357 return -1;
358
359 s += 2;
360 length -= 2;
361 }
362
363 ++s; ++n; --length;
364 }
365
366 *segment_size = n;
367
368 return 0;
369}
370
391static int
392make_decoded_option(const uint8_t *s, size_t length,
393 unsigned char *buf, size_t buflen, size_t* optionsize) {
394 int res;
395 size_t segmentlen;
396 size_t written;
397
398 if (!buflen) {
399 coap_log_debug("make_decoded_option(): buflen is 0!\n");
400 return -1;
401 }
402
403 res = check_segment(s, length, &segmentlen);
404 if (res < 0)
405 return -1;
406
407 /* write option header using delta 0 and length res */
408 written = coap_opt_setheader(buf, buflen, 0, segmentlen);
409
410 assert(written <= buflen);
411
412 if (!written) /* encoding error */
413 return -1;
414
415 buf += written; /* advance past option type/length */
416 buflen -= written;
417
418 if (buflen < segmentlen) {
419 coap_log_debug("buffer too small for option\n");
420 return -1;
421 }
422
423 decode_segment(s, length, buf);
424
425 *optionsize = written + segmentlen;
426
427 return 0;
428}
429
430
431#ifndef min
432#define min(a,b) ((a) < (b) ? (a) : (b))
433#endif
434
435typedef void (*segment_handler_t)(const uint8_t *, size_t, void *);
436
441dots(const uint8_t *s, size_t len) {
442 return len && *s == '.' && (len == 1 || (len == 2 && *(s+1) == '.'));
443}
444
456static size_t
457coap_split_path_impl(const uint8_t *s, size_t length,
458 segment_handler_t h, void *data) {
459
460 const uint8_t *p, *q;
461
462 p = q = s;
463 while (length > 0 && !strnchr((const uint8_t *)"?#", 2, *q)) {
464 if (*q == '/') { /* start new segment */
465
466 if (!dots(p, q - p)) {
467 h(p, q - p, data);
468 }
469
470 p = q + 1;
471 }
472
473 q++;
474 length--;
475 }
476
477 /* write last segment */
478 if (!dots(p, q - p)) {
479 h(p, q - p, data);
480 }
481
482 return q - s;
483}
484
485struct cnt_str {
487 int n;
488};
489
490static void
491write_option(const uint8_t *s, size_t len, void *data) {
492 struct cnt_str *state = (struct cnt_str *)data;
493 int res;
494 size_t optionsize;
495 assert(state);
496
497 res = make_decoded_option(s, len, state->buf.s, state->buf.length, &optionsize);
498 if (res == 0) {
499 state->buf.s += optionsize;
500 state->buf.length -= optionsize;
501 state->n++;
502 }
503}
504
505int
506coap_split_path(const uint8_t *s, size_t length,
507 unsigned char *buf, size_t *buflen) {
508 struct cnt_str tmp = { { *buflen, buf }, 0 };
509
510 coap_split_path_impl(s, length, write_option, &tmp);
511
512 *buflen = *buflen - tmp.buf.length;
513
514 return tmp.n;
515}
516
517int
518coap_split_query(const uint8_t *s, size_t length,
519 unsigned char *buf, size_t *buflen) {
520 struct cnt_str tmp = { { *buflen, buf }, 0 };
521 const uint8_t *p;
522
523 p = s;
524 while (length > 0 && *s != '#') {
525 if (*s == '&') { /* start new query element */
526 write_option(p, s - p, &tmp);
527 p = s + 1;
528 }
529
530 s++;
531 length--;
532 }
533
534 /* write last query element */
535 write_option(p, s - p, &tmp);
536
537 *buflen = *buflen - tmp.buf.length;
538 return tmp.n;
539}
540
541#define URI_DATA(uriobj) ((unsigned char *)(uriobj) + sizeof(coap_uri_t))
542
544coap_new_uri(const uint8_t *uri, unsigned int length) {
545 unsigned char *result;
546
547 result = (unsigned char*)coap_malloc_type(COAP_STRING, length + 1 + sizeof(coap_uri_t));
548
549 if (!result)
550 return NULL;
551
552 memcpy(URI_DATA(result), uri, length);
553 URI_DATA(result)[length] = '\0'; /* make it zero-terminated */
554
555 if (coap_split_uri(URI_DATA(result), length, (coap_uri_t *)result) < 0) {
557 return NULL;
558 }
559 return (coap_uri_t *)result;
560}
561
564 coap_uri_t *result;
565 uint8_t *p;
566
567 if ( !uri )
568 return NULL;
569
571 uri->path.length + sizeof(coap_uri_t) + 1);
572
573 if ( !result )
574 return NULL;
575
576 memset( result, 0, sizeof(coap_uri_t) );
577
578 result->port = uri->port;
579
580 if ( uri->host.length ) {
581 result->host.s = p = URI_DATA(result);
582 result->host.length = uri->host.length;
583
584 memcpy(p, uri->host.s, uri->host.length);
585 }
586
587 if ( uri->path.length ) {
588 result->path.s = p = URI_DATA(result) + uri->host.length;
589 result->path.length = uri->path.length;
590
591 memcpy(p, uri->path.s, uri->path.length);
592 }
593
594 if ( uri->query.length ) {
595 result->query.s = p = URI_DATA(result) + uri->host.length + uri->path.length;
596 result->query.length = uri->query.length;
597
598 memcpy (p, uri->query.s, uri->query.length);
599 }
600
601 return result;
602}
603
604void
607}
608
610is_unescaped_in_path(const uint8_t c) {
611 return ( c >= 'A' && c <= 'Z' ) || ( c >= 'a' && c <= 'z' )
612 || ( c >= '0' && c <= '9' ) || c == '-' || c == '.' || c == '_'
613 || c == '~' || c == '!' || c == '$' || c == '\'' || c == '('
614 || c == ')' || c == '*' || c == '+' || c == ',' || c == ';' || c=='='
615 || c==':' || c=='@' || c == '&';
616}
617
619is_unescaped_in_query(const uint8_t c) {
620 return is_unescaped_in_path(c) || c=='/' || c=='?';
621}
622
624 coap_opt_iterator_t opt_iter;
626 coap_opt_t *q;
627 coap_string_t *query = NULL;
628 size_t length = 0;
629 static const uint8_t hex[] = "0123456789ABCDEF";
630
633 coap_option_iterator_init(request, &opt_iter, &f);
634 while ((q = coap_option_next(&opt_iter))) {
635 uint16_t seg_len = coap_opt_length(q), i;
636 const uint8_t *seg= coap_opt_value(q);
637 for (i = 0; i < seg_len; i++) {
638 if (is_unescaped_in_query(seg[i]))
639 length += 1;
640 else
641 length += 3;
642 }
643 length += 1;
644 }
645 if (length > 0)
646 length -= 1;
647 if (length > 0) {
648 query = coap_new_string(length);
649 if (query) {
650 query->length = length;
651 unsigned char *s = query->s;
652 coap_option_iterator_init(request, &opt_iter, &f);
653 while ((q = coap_option_next(&opt_iter))) {
654 if (s != query->s)
655 *s++ = '&';
656 uint16_t seg_len = coap_opt_length(q), i;
657 const uint8_t *seg= coap_opt_value(q);
658 for (i = 0; i < seg_len; i++) {
659 if (is_unescaped_in_query(seg[i])) {
660 *s++ = seg[i];
661 } else {
662 *s++ = '%';
663 *s++ = hex[seg[i]>>4];
664 *s++ = hex[seg[i]&0x0F];
665 }
666 }
667 }
668 }
669 }
670 return query;
671}
672
674 coap_opt_iterator_t opt_iter;
676 coap_opt_t *q;
677 coap_string_t *uri_path = NULL;
678 size_t length = 0;
679 static const uint8_t hex[] = "0123456789ABCDEF";
680
681 q = coap_check_option(request, COAP_OPTION_PROXY_URI, &opt_iter);
682 if (q) {
683 coap_uri_t uri;
684
686 coap_opt_length(q), &uri) < 0) {
687 return NULL;
688 }
689 uri_path = coap_new_string(uri.path.length);
690 if (uri_path) {
691 memcpy(uri_path->s, uri.path.s, uri.path.length);
692 }
693 return uri_path;
694 }
695
698 coap_option_iterator_init(request, &opt_iter, &f);
699 while ((q = coap_option_next(&opt_iter))) {
700 uint16_t seg_len = coap_opt_length(q), i;
701 const uint8_t *seg= coap_opt_value(q);
702 for (i = 0; i < seg_len; i++) {
703 if (is_unescaped_in_path(seg[i]))
704 length += 1;
705 else
706 length += 3;
707 }
708 /* bump for the leading "/" */
709 length += 1;
710 }
711 /* The first entry does not have a leading "/" */
712 if (length > 0)
713 length -= 1;
714
715 /* if 0, either no URI_PATH Option, or the first one was empty */
716 uri_path = coap_new_string(length);
717 if (uri_path) {
718 uri_path->length = length;
719 unsigned char *s = uri_path->s;
720 int n = 0;
721 coap_option_iterator_init(request, &opt_iter, &f);
722 while ((q = coap_option_next(&opt_iter))) {
723 if (n++) {
724 *s++ = '/';
725 }
726 uint16_t seg_len = coap_opt_length(q), i;
727 const uint8_t *seg= coap_opt_value(q);
728 for (i = 0; i < seg_len; i++) {
729 if (is_unescaped_in_path(seg[i])) {
730 *s++ = seg[i];
731 } else {
732 *s++ = '%';
733 *s++ = hex[seg[i]>>4];
734 *s++ = hex[seg[i]&0x0F];
735 }
736 }
737 }
738 }
739 return uri_path;
740}
741
Pulls together all the internal only header files.
size_t coap_opt_size(const coap_opt_t *opt)
Returns the size of the given option, taking into account a possible option jump.
Definition: coap_option.c:283
uint8_t coap_opt_t
Use byte-oriented access methods here because sliding a complex struct coap_opt_t over the data buffe...
Definition: coap_option.h:26
unsigned int coap_encode_var_safe(uint8_t *buf, size_t length, unsigned int val)
Encodes multiple-length byte sequences.
Definition: encode.c:45
#define coap_log_debug(...)
Definition: coap_debug.h:48
#define coap_log_warn(...)
Definition: coap_debug.h:45
coap_opt_t * coap_option_next(coap_opt_iterator_t *oi)
Updates the iterator oi to point to the next option.
Definition: coap_option.c:152
coap_optlist_t * coap_new_optlist(uint16_t number, size_t length, const uint8_t *data)
Create a new optlist entry.
Definition: coap_option.c:508
uint32_t coap_opt_length(const coap_opt_t *opt)
Returns the length of the given option.
Definition: coap_option.c:211
coap_opt_iterator_t * coap_option_iterator_init(const coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_opt_filter_t *filter)
Initializes the given option iterator oi to point to the beginning of the pdu's option list.
Definition: coap_option.c:116
void coap_option_filter_clear(coap_opt_filter_t *filter)
Clears filter filter.
Definition: coap_option.c:488
coap_opt_t * coap_check_option(const coap_pdu_t *pdu, coap_option_num_t number, coap_opt_iterator_t *oi)
Retrieves the first option of number number from pdu.
Definition: coap_option.c:198
int coap_insert_optlist(coap_optlist_t **head, coap_optlist_t *node)
Adds optlist to the given optlist_chain.
Definition: coap_option.c:570
const uint8_t * coap_opt_value(const coap_opt_t *opt)
Returns a pointer to the value of the given option.
Definition: coap_option.c:248
int coap_option_filter_set(coap_opt_filter_t *filter, coap_option_num_t option)
Sets the corresponding entry for number in filter.
Definition: coap_option.c:493
size_t coap_opt_setheader(coap_opt_t *opt, size_t maxlen, uint16_t delta, size_t length)
Encodes the given delta and length values into opt.
Definition: coap_option.c:291
#define COAP_DEFAULT_PORT
Definition: pdu.h:37
#define COAP_OPTION_URI_QUERY
Definition: pdu.h:124
#define COAP_OPTION_URI_PATH
Definition: pdu.h:119
#define COAP_DEFAULT_SCHEME
Definition: pdu.h:50
#define COAPS_DEFAULT_PORT
Definition: pdu.h:38
#define COAP_OPTION_URI_PORT
Definition: pdu.h:116
#define COAP_OPTION_PROXY_URI
Definition: pdu.h:131
#define COAP_SET_STR(st, l, v)
Definition: coap_str.h:51
coap_string_t * coap_new_string(size_t size)
Returns a new string object with at least size+1 bytes storage allocated.
Definition: str.c:20
coap_string_t * coap_get_uri_path(const coap_pdu_t *request)
Extract uri_path string from request PDU.
Definition: uri.c:673
int coap_split_path(const uint8_t *s, size_t length, unsigned char *buf, size_t *buflen)
Splits the given URI path into segments.
Definition: uri.c:506
int coap_split_query(const uint8_t *s, size_t length, unsigned char *buf, size_t *buflen)
Splits the given URI query into segments.
Definition: uri.c:518
int coap_uri_into_options(coap_uri_t *uri, coap_optlist_t **optlist_chain, int create_port_opt, uint8_t *_buf, size_t _buflen)
Takes a coap_uri_t and then adds CoAP options into the optlist_chain.
Definition: uri.c:251
int coap_split_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri)
Parses a given string into URI components.
Definition: uri.c:241
int coap_split_proxy_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri)
Parses a given string into URI components.
Definition: uri.c:246
coap_string_t * coap_get_query(const coap_pdu_t *request)
Extract query string from request PDU according to escape rules in 6.5.8.
Definition: uri.c:623
#define COAP_STATIC_INLINE
Definition: libcoap.h:45
@ COAP_STRING
Definition: mem.h:37
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
Definition: uri.c:485
int n
Definition: uri.c:487
coap_string_t buf
Definition: uri.c:486
Iterator to run through PDU options.
Definition: coap_option.h:169
Representation of chained list of CoAP options to install.
Definition: coap_option.h:326
structure for CoAP PDUs
const uint8_t * s
read-only string data
Definition: coap_str.h:48
size_t length
length of string
Definition: coap_str.h:47
CoAP string data definition.
Definition: coap_str.h:38
uint8_t * s
string data
Definition: coap_str.h:40
size_t length
length of string
Definition: coap_str.h:39
Representation of parsed URI.
Definition: uri.h:46
enum coap_uri_scheme_t scheme
The parsed scheme specifier.
Definition: uri.h:56
coap_str_const_t path
The complete path if present or {0, NULL}.
Definition: uri.h:49
uint16_t port
The port in host byte order.
Definition: uri.h:48
coap_str_const_t query
The complete query if present or {0, NULL}.
Definition: uri.h:52
coap_str_const_t host
The host part of the URI.
Definition: uri.h:47
COAP_STATIC_INLINE int is_unescaped_in_path(const uint8_t c)
Definition: uri.c:610
static void decode_segment(const uint8_t *seg, size_t length, unsigned char *buf)
Decodes percent-encoded characters while copying the string seg of size length to buf.
Definition: uri.c:329
COAP_STATIC_INLINE int is_unescaped_in_query(const uint8_t c)
Definition: uri.c:619
COAP_STATIC_INLINE int dots(const uint8_t *s, size_t len)
Checks if path segment s consists of one or two dots.
Definition: uri.c:441
static size_t coap_split_path_impl(const uint8_t *s, size_t length, segment_handler_t h, void *data)
Splits the given string into segments.
Definition: uri.c:457
COAP_STATIC_INLINE const uint8_t * strnchr(const uint8_t *s, size_t len, unsigned char c)
A length-safe version of strchr().
Definition: uri.c:39
static int check_segment(const uint8_t *s, size_t length, size_t *segment_size)
Runs through the given path (or query) segment and checks if percent-encodings are correct.
Definition: uri.c:351
#define ISEQUAL_CI(a, b)
Definition: uri.c:46
static void write_option(const uint8_t *s, size_t len, void *data)
Definition: uri.c:491
void coap_delete_uri(coap_uri_t *uri)
Removes the specified coap_uri_t object.
Definition: uri.c:605
static int coap_split_uri_sub(const uint8_t *str_var, size_t len, coap_uri_t *uri, coap_uri_check_t check_proxy)
Definition: uri.c:55
#define hexchar_to_dec(c)
Calculates decimal value from hexadecimal ASCII character given in c.
Definition: uri.c:314
static int make_decoded_option(const uint8_t *s, size_t length, unsigned char *buf, size_t buflen, size_t *optionsize)
Writes a coap option from given string s to buf.
Definition: uri.c:392
coap_uri_check_t
Definition: uri.c:49
@ COAP_URI_CHECK_URI
Definition: uri.c:50
@ COAP_URI_CHECK_PROXY
Definition: uri.c:51
coap_uri_t * coap_clone_uri(const coap_uri_t *uri)
Clones the specified coap_uri_t object.
Definition: uri.c:563
#define URI_DATA(uriobj)
Definition: uri.c:541
coap_uri_t * coap_new_uri(const uint8_t *uri, unsigned int length)
Creates a new coap_uri_t object from the specified URI.
Definition: uri.c:544
void(* segment_handler_t)(const uint8_t *, size_t, void *)
Definition: uri.c:435
static int coap_uri_scheme_is_secure(const coap_uri_t *uri)
Definition: uri.h:60
@ COAP_URI_SCHEME_COAPS_TCP
Definition: uri.h:32
@ COAP_URI_SCHEME_COAPS
Definition: uri.h:30
@ COAP_URI_SCHEME_COAP_TCP
Definition: uri.h:31
@ COAP_URI_SCHEME_HTTPS
Definition: uri.h:34
@ COAP_URI_SCHEME_COAP
Definition: uri.h:29
@ COAP_URI_SCHEME_HTTP
Definition: uri.h:33