1COAP_RESOURCE(3) libcoap Manual COAP_RESOURCE(3)
2
3
4
6 coap_resource, coap_resource_init, coap_resource_unknown_init,
7 coap_resource_proxy_uri_init, coap_add_resource, coap_delete_resource,
8 coap_resource_set_mode, coap_resource_set_userdata,
9 coap_resource_get_userdata - Work with CoAP resources
10
12 #include <coap3/coap.h>
13
14 coap_resource_t *coap_resource_init(coap_str_const_t *uri_path, int
15 flags);
16
17 coap_resource_t *coap_resource_unknown_init(coap_method_handler_t
18 put_handler);
19
20 coap_resource_t *coap_resource_proxy_uri_init(coap_method_handler_t
21 proxy_handler, size_t host_name_count, const char *host_name_list[]);
22
23 void coap_add_resource(coap_context_t *context, coap_resource_t
24 *resource);
25
26 int coap_delete_resource(coap_context_t *context, coap_resource_t
27 *resource);
28
29 void coap_resource_set_mode(coap_resource_t *resource, int mode);
30
31 void coap_resource_set_userdata(coap_resource_t *resource, void *data);
32
33 void *coap_resource_get_userdata(coap_resource_t *resource);
34
35 void coap_resource_release_userdata_handler(coap_context_t *context,
36 coap_resource_release_userdata_handler_t callback);
37
38 coap_str_const_t *coap_resource_get_uri_path(coap_resource_t
39 *resource);
40
41 For specific (D)TLS library support, link with -lcoap-3-notls,
42 -lcoap-3-gnutls, -lcoap-3-openssl, -lcoap-3-mbedtls or
43 -lcoap-3-tinydtls. Otherwise, link with -lcoap-3 to get the default
44 (D)TLS library support.
45
47 CoAP Resources on a CoAP Server need to be created and updated etc. The
48 URI in the request packet defines the resource to work with, with
49 possibly the Query referring to a sub-resource.
50
51 When resources are configured on the CoAP server, the URI to match
52 against in the request packet is specified.
53
54 Callback Handlers are then added to the resource to handle the
55 different request methods.
56
57 Adding Attributes allows textual information to be added to the
58 resource which can then be reported back to any client doing a "GET
59 .well-known/core" request.
60
61 If an incoming packet request matches a resource’s URI and Method, then
62 the appropriate callback resource handler is invoked to process the
63 packet which then should update a suitable response packet for sending
64 back to the requester.
65
66 There is support for handling incoming packets where the URI is
67 unknown. This could, for example, happen when a PUT request is trying
68 to create a new resource. It is the responsibility of the unknown
69 resource callback handler to either create a new resource for the URI
70 or just manage things separately.
71
72 CoAP Observe (RFC 7641) is not supported for unknown resources, so a
73 new resource with GET handler must be created by the unknown resource
74 callback handle matching the URI which then can be Observable.
75
76 The coap_resource_init() function returns a newly created resource of
77 type coap_resource_t * . uri_path specifies the uri string path to
78 match against. flags is used to define whether the resource is of type
79 Confirmable Message or Non-Confirmable Message for any "observe"
80 responses. See coap_observe(3). flags can be one of the following
81 definitions or’ed together.
82
83
84 COAP_RESOURCE_FLAGS_NOTIFY_NON Set the notification
85 message type to
86 non-confirmable for any
87 trigggered "observe"
88 responses with type set to
89 confirmable every 5
90 packets as required by
91 RFC7641 section-4.5.
92
93 COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS Set the notification
94 message type to always
95 non-confirmable for any
96 trigggered "observe"
97 responses. This should
98 only be used if a upper
99 layer protocol requires
100 it.
101
102 COAP_RESOURCE_FLAGS_NOTIFY_CON Set the notification
103 message type to
104 confirmable for any
105 trigggered "observe"
106 responses.
107
108 COAP_RESOURCE_FLAGS_RELEASE_URI Free off the
109 coap_str_const_t for
110 uri_path when the resource
111 is deleted.
112
113
114 NOTE: uri_path, if not 7 bit readable ASCII, binary bytes must be hex
115 encoded according to the rules defined in RFC3968 Section 2.1.
116
117 The coap_resource_unknown_init() function returns a newly created
118 resource of type coap_resource_t *. put_handler is automatically added
119 to the resource to handle PUT requests to resources that are unknown.
120 Additional handlers can be added to this resource if required.
121
122 The coap_resource_proxy_uri_init() function returns a newly created
123 resource of type coap_resource_t *. proxy_handler is automatically
124 added to the resource to handle PUT/POST/GET etc. requests that use the
125 Proxy-Uri: option. There is no need to add explicit request type
126 handlers. One or more names by which the proxy is known by (IP address,
127 DNS name etc.) must be supplied in the array defined by
128 host_name_list[] which has a count of host_name_count. This is used to
129 check whether the current endpoint is the proxy target address.
130
131 The coap_add_resource() function registers the given resource with the
132 context. The resource must have been created by coap_resource_init(),
133 coap_resource_unknown_init() or coap_resource_proxy_uri_init(). The
134 storage allocated for the resource will be released by
135 coap_delete_resource().
136
137 As the uri_path of the resource has to be unique across all of the
138 resources associated with a context, coap_add_resource() (or
139 coap_add_resource_release()) will delete any previous resource with the
140 same uri_path before adding in the new resource.
141
142 The coap_delete_resource() function deletes a resource identified by
143 resource from context. The storage allocated for that resource is
144 freed, along with any attrigutes associated with the resource.
145
146 The coap_resource_set_mode() changes the notification message type of
147 resource to the given mode which must be one of
148 COAP_RESOURCE_FLAGS_NOTIFY_NON, COAP_RESOURCE_FLAGS_NOTIFY_NON_ALWAYS
149 or COAP_RESOURCE_FLAGS_NOTIFY_CON.
150
151 The coap_resource_set_userdata() function allows a pointer to user data
152 to be associated with a resource that can accessed in any callback that
153 includes resource as a parameter.
154
155 NOTE: data must point to a static, or allocated, block of memory.
156
157 The coap_resource_get_userdata() function obtains the user data pointer
158 from the resource that had previously been set up by
159 coap_resource_set_userdata().
160
161 The coap_resource_release_userdata_handler() function defines the
162 context wide callback handler to call to release the allocated user
163 data that has been added to the resource using
164 coap_resource_set_userdata() when the resource is deleted. callback can
165 be NULL (which is the default) if nothing needs to be freed off.
166
167 The coap_resource_get_uri_path() function is used to obtain the UriPath
168 of the resource definion.
169
171 The coap_resource_init(), coap_resource_unknown_init() and
172 coap_resource_proxy_uri_init() functions return a newly created
173 resource or NULL if there is a malloc failure.
174
175 The coap_delete_resource() function return 0 on failure (resource not
176 found), 1 on success.
177
178 The coap_resource_get_userdata() function returns the value previously
179 set by the coap_resource_set_userdata() function or NULL.
180
181 The coap_resource_get_uri_path() function returns the uri_path or NULL
182 if there was a failure.
183
185 Fixed Resources Set Up
186
187 #include <coap3/coap.h>
188
189 #define INDEX "This is an example server using libcoap\n"
190
191 static void
192 hnd_get_index(coap_resource_t *resource, coap_session_t *session,
193 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
194 unsigned char buf[3];
195 /* Remove (void) definition if variable is used */
196 (void)resource;
197 (void)session;
198 (void)request;
199 (void)query;
200
201 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
202
203 coap_add_option(response,
204 COAP_OPTION_CONTENT_TYPE,
205 coap_encode_var_safe(buf, sizeof(buf),
206 COAP_MEDIATYPE_TEXT_PLAIN),
207 buf);
208
209 coap_add_option(response,
210 COAP_OPTION_MAXAGE,
211 coap_encode_var_safe(buf, sizeof(buf), 0x2ffff), buf);
212
213 coap_add_data(response, strlen(INDEX), (const uint8_t *)INDEX);
214
215 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
216 }
217
218 static void
219 hnd_delete_time(coap_resource_t *resource, coap_session_t *session,
220 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
221 /* Remove (void) definition if variable is used */
222 (void)resource;
223 (void)session;
224 (void)request;
225 (void)query;
226
227 /* .. code .. */
228
229 coap_pdu_set_code(response, COAP_RESPONSE_CODE_DELETED);
230 }
231
232 static void
233 hnd_get_time(coap_resource_t *resource, coap_session_t *session,
234 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
235 /* Remove (void) definition if variable is used */
236 (void)resource;
237 (void)session;
238 (void)request;
239 (void)query;
240 (void)response;
241
242 /* .. code .. */
243
244 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
245 }
246
247 static void
248 hnd_put_time(coap_resource_t *resource, coap_session_t *session,
249 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
250 /* Remove (void) definition if variable is used */
251 (void)resource;
252 (void)session;
253 (void)request;
254 (void)query;
255 (void)response;
256
257 /* .. code .. */
258
259 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED);
260 }
261
262 static void
263 init_resources(coap_context_t *ctx) {
264
265 coap_resource_t *r;
266
267 /* Create a resource to return general information */
268 r = coap_resource_init(NULL, 0);
269 coap_register_handler(r, COAP_REQUEST_GET, hnd_get_index);
270
271 /* Document resource for '.well-known/core' request */
272 coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
273 coap_add_attr(r, coap_make_str_const("title"),
274 coap_make_str_const("\"General Info\""), 0);
275
276 coap_add_resource(ctx, r);
277
278 /* Create a resource to return return or update time */
279 r = coap_resource_init(coap_make_str_const("time"),
280 COAP_RESOURCE_FLAGS_NOTIFY_CON);
281 coap_resource_set_get_observable(r, 1);
282 coap_register_handler(r, COAP_REQUEST_GET, hnd_get_time);
283 coap_register_handler(r, COAP_REQUEST_PUT, hnd_put_time);
284 coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_time);
285
286 /* Document resource for 'time' request */
287 coap_add_attr(r, coap_make_str_const("ct"), coap_make_str_const("0"), 0);
288 coap_add_attr(r, coap_make_str_const("title"),
289 coap_make_str_const("\"Internal Clock\""), 0);
290 coap_add_attr(r, coap_make_str_const("rt"), coap_make_str_const("\"secs\""),
291 0);
292 coap_add_attr(r, coap_make_str_const("if"), coap_make_str_const("\"clock\""),
293 0);
294
295 coap_add_resource(ctx, r);
296
297 }
298
299 Dynamic Resources Set Up
300
301 #include <coap3/coap.h>
302
303 /* Regular DELETE handler - used by resources created by the
304 * Unknown Resource PUT handler */
305
306 static void
307 hnd_delete(coap_resource_t *resource, coap_session_t *session,
308 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
309 /* Remove (void) definition if variable is used */
310 (void)session;
311 (void)request;
312 (void)query;
313 (void)response;
314
315 /* .. code .. */
316
317 /* Dynamic resource no longer required - delete it */
318 coap_delete_resource(coap_session_get_context(session), resource);
319
320 coap_pdu_set_code(response, COAP_RESPONSE_CODE_DELETED);
321 }
322
323 /* Regular GET handler - used by resources created by the
324 * Unknown Resource PUT handler */
325
326 static void
327 hnd_get(coap_resource_t *resource, coap_session_t *session,
328 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
329
330 coap_str_const_t *get_uri_path;
331 /* Remove (void) definition if variable is used */
332 (void)resource;
333 (void)session;
334 (void)request;
335 (void)query;
336 (void)response;
337
338 /*
339 * request will be NULL if an Observe triggered request, so the uri_path,
340 * if needed, must be abstracted from the resource.
341 * The uri_path string is a const pointer
342 */
343
344 get_uri_path = coap_resource_get_uri_path(resource);
345
346 /* .. code .. */
347
348 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT);
349 }
350
351 /* Regular PUT handler - used by resources created by the
352 * Unknown Resource PUT handler */
353
354 static void
355 hnd_put(coap_resource_t *resource, coap_session_t *session,
356 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
357 /* Remove (void) definition if variable is used */
358 (void)resource;
359 (void)session;
360 (void)query;
361
362 coap_string_t *put_uri_path;
363 size_t length;
364 const uint8_t *data;
365 size_t offset;
366 size_t total;
367 int new_resource = 0;
368
369 /* get the uri_path */
370 put_uri_path = coap_get_uri_path(request);
371 if (!put_uri_path) {
372 coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
373 return;
374 }
375 coap_get_data_large(request, &length, &data, &offset, &total);
376
377 /* .. code .. */
378
379 /* Need to do this as coap_get_uri_path() created it */
380 coap_delete_string(put_uri_path);
381
382 if (length + offset < total)
383 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTINUE);
384 else if (new_resource)
385 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CREATED);
386 else
387 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED);
388 }
389
390 static int
391 check_url_fn(coap_string_t *uri_path, uint8_t code) {
392 /* Remove (void) definition if variable is used */
393 (void)uri_path;
394 (void)code;
395
396 /* Code to determine whether the uri is valid or not */
397
398 return 1;
399 }
400
401 /* Unknown Resource PUT handler */
402
403 static void
404 hnd_unknown_put(coap_resource_t *resource, coap_session_t *session,
405 const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) {
406 /* Remove (void) definition if variable is used */
407 (void)resource;
408 coap_pdu_code_t req_code = coap_pdu_get_code(request);
409
410 coap_resource_t *r;
411 coap_string_t *uri_path;
412
413 /* get the uri_path - which will get used by coap_resource_init() */
414 uri_path = coap_get_uri_path(request);
415 if (!uri_path) {
416 coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
417 return;
418 }
419
420 /* Check if new URI Path is valid */
421 if (!check_url_fn (uri_path, req_code)) {
422 coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND);
423 coap_delete_string(uri_path);
424 return;
425 }
426
427 /*
428 * Create a resource to handle the new URI
429 * uri_path will get deleted when the resource is removed
430 */
431 r = coap_resource_init((coap_str_const_t*)uri_path,
432 COAP_RESOURCE_FLAGS_RELEASE_URI | COAP_RESOURCE_FLAGS_NOTIFY_NON);
433 coap_register_handler(r, COAP_REQUEST_PUT, hnd_put);
434 coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete);
435 /* We possibly want to Observe the GETs */
436 coap_resource_set_get_observable(r, 1);
437 coap_register_handler(r, COAP_REQUEST_GET, hnd_get);
438 coap_add_resource(coap_session_get_context(session), r);
439
440 /* Do the PUT for this first call */
441 hnd_put(r, session, request, query, response);
442
443 return;
444
445 }
446
447 /* Initialize single Unknown Resource PUT handler */
448
449 static void
450 init_resources(coap_context_t *ctx) {
451
452 coap_resource_t *r;
453
454 /* Create a resource to handle PUTs to unknown URIs */
455 r = coap_resource_unknown_init(hnd_unknown_put);
456 /*
457 * Additional handlers can be added - for example
458 * coap_register_handler(r, COAP_REQUEST_POST, hnd_post_unknown);
459 * coap_register_handler(r, COAP_REQUEST_GET, hnd_get_unknown);
460 * coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_unknown);
461 */
462 coap_add_resource(ctx, r);
463
464 }
465
467 coap_attribute(3), coap_context(3), coap_observe(3) and coap_handler(3)
468
470 See "RFC7252: The Constrained Application Protocol (CoAP)" for further
471 information.
472
474 Please report bugs on the mailing list for libcoap:
475 libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at
476 https://github.com/obgm/libcoap/issues
477
479 The libcoap project <libcoap-developers@lists.sourceforge.net>
480
481
482
483coap_resource 4.3.0 07/22/2021 COAP_RESOURCE(3)