From 8b1fe26a7c84a2efca6c9e2ed669f635d8a38487 Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Mon, 12 Feb 2018 11:08:04 +0000 Subject: [PATCH] man/coap_resource.txt.in: New man page covering resources --- man/coap_resource.txt.in | 368 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 368 insertions(+) create mode 100644 man/coap_resource.txt.in diff --git a/man/coap_resource.txt.in b/man/coap_resource.txt.in new file mode 100644 index 00000000..7ddfd3ca --- /dev/null +++ b/man/coap_resource.txt.in @@ -0,0 +1,368 @@ +// -*- mode:doc; -*- +// vim: set syntax=asciidoc,tw=0: + +coap_resource(3) +================= +:doctype: manpage +:man source: coap_resource +:man version: @PACKAGE_VERSION@ +:man manual: libcoap Manual + +NAME +---- +coap_resource, coap_resource_init, coap_resource_unknown_init, +coap_add_resource, coap_delete_resource, coap_delete_all_resources, +coap_resource_set_mode - work with CoAP resources + +SYNOPSIS +-------- +*#include * + +*coap_resource_t *coap_resource_init(const unsigned char *_uri_path_, +size_t _len_, int _flags_);* + +*coap_resource_t *coap_resource_unknown_init(coap_method_handler_t +_put_handler_);* + +*void coap_add_resource(coap_context_t *_context_, +coap_resource_t *_resource_);* + +*int coap_delete_resource(coap_context_t _context_, +coap_resource_t _resource_);* + +*void coap_delete_all_resources(coap_context_t *_context_);* + +*void coap_resource_set_mode(coap_resource_t *_resource_, int _mode_);* + +Link with -lcoap-@LIBCOAP_API_VERSION@. + +DESCRIPTION +----------- +CoAP Resources on a CoAP Server need to be created and updated etc. The URI in +the request packet defines the resource to work with, with possibly the Query +referring to a sub-resource. + +When resources are configured on the CoAP server, the URI to match against +in the request packet is specified. + +Callback Handlers are then added to the resource to handle the different +request methods. + +Adding Attributes allows textual information to be added to the resource +which can then be reported back to any client doing a "GET .well-known/core" +request. + +If an incoming packet request matches a resource's URI and Method, then +the appropriate callback resource handler is invoked to process the packet +which then should update a suitable response packet for sending back to the +requester. + +There is support for handling incoming packets where the URI is unknown. +This could, for example, happen when a PUT request is trying to create a new +resource. It is the responsibility of the unknown resource callback handler +to either create a new resource for the URI or just manage things separately. + +CoAP Observe (RFC 7641) is not supported for unknown resources, so a new +resource with GET handler must be created by the unknown resource callback +handle matching the URI which then can be Observable. + +The *coap_resource_init*() function returns a newly created _resource_ of +type _coap_resource_t_ *. _uri_path_ specifies the uri path to match against. +_len_ is the length of _uri_path_. _flags_ is used to define whether the +_resource_ is of type Confirmable Message or Non-Confirmable Message, as well +as if _uri_path_ is to be freed when the _resource_ is freed. _flags_ can be +one of the first two and optionally the third of the following definitions +or'ed together. +It is imperative that _uri_path_ points to data that is valid during the +lifetime of the resource. + +*COAP_RESOURCE_FLAGS_NOTIFY_NON*:: +Set the notification message type to non-confirmable. + +*COAP_RESOURCE_FLAGS_NOTIFY_CON*:: +Set the notification message type to confirmable. + +*COAP_RESOURCE_FLAGS_RELEASE_URI*:: +Free off the contents of _uri_path_ when the _resource_ is deleted. + +The *coap_resource_unknown_init*() returns a newly created _resource_ of +type _coap_resource_t_ *. _put_handler_ is automatically added to the +_resource_ to handle PUT requests to resources that are unknown. + +The *coap_add_resource*() function registers the given _resource_ with the +_context_. The _resource_ must have been created by *coap_resource_init*() or +*coap_resource_unknown_init*(), the storage allocated for the _resource_ +will be released by *coap_delete_resource*(). + +As the _uri_path_ of the resource has to be unique across all of the resources +associated with a _context_, *coap_add_resource*() will delete any previous +_resource_ with the same _uri_path_ before adding in the new _resource_. + +The *coap_delete_resource*() function deletes a _resource_ identified by +_resource_ from _context_. The storage allocated for that _resource_ is freed. + +The *coap_delete_all_resources*() function deletes all resources from +_context_ and frees their storage. + +The *coap_resource_set_mode*() changes the notification message type of +_resource_ to the given _mode_ which must be one of +COAP_RESOURCE_FLAGS_NOTIFY_NON or COAP_RESOURCE_FLAGS_NOTIFY_CON. + +RETURN VALUES +------------- +The *coap_resource_init*() and *coap_resource_unknown_init*() functions +return a newly created resource or NULL if there is a malloc failure. + +The *coap_delete_resource*() function return 0 on failure (_resource_ not +found), 1 on success. + +EXAMPLES +-------- +*Fixed Resources Set Up* + +[source, c] +-- +#include + +static void +init_resources(coap_context_t *ctx) { + + coap_resource_t *r; + + /* Create a resource to return general information */ + r = coap_resource_init(NULL, 0, 0); + coap_register_handler(r, COAP_REQUEST_GET, hnd_get_index); + + coap_add_attr(r, (unsigned char *)"ct", 2, (unsigned char *)"0", 1, 0); + coap_add_attr(r, (unsigned char *)"title", 5, + (unsigned char *)"\"General Info\"", 14, 0); + + coap_add_resource(ctx, r); + + /* Create a resource to return return or update time */ + r = coap_resource_init((unsigned char *)"time", 4, + COAP_RESOURCE_FLAGS_NOTIFY_CON); + coap_register_handler(r, COAP_REQUEST_GET, hnd_get_time); + coap_register_handler(r, COAP_REQUEST_PUT, hnd_put_time); + coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_time); + + coap_add_attr(r, (unsigned char *)"ct", 2, (unsigned char *)"0", 1, 0); + coap_add_attr(r, (unsigned char *)"title", 5, + (unsigned char *)"\"Internal Clock\"", 16, 0); + coap_add_attr(r, (unsigned char *)"rt", 2, (unsigned char *)"\"secs\"", + 6, 0); + coap_resource_set_get_observable(r, 1); + coap_add_attr(r, (unsigned char *)"if", 2, (unsigned char *)"\"clock\"", + 7, 0); + + coap_add_resource(ctx, r); + +} +-- + +*GET Time Callback Handler* + +[source, c] +-- +#include + +static void +hnd_get_time(coap_context_t *ctx, coap_resource_t *resource, +coap_session_t *session, coap_pdu_t *request, str *token, str *query, +coap_pdu_t *response) { + + unsigned char buf[40]; + size_t len; + time_t now; + coap_tick_t t; + + /* Define what the response code is going to be */ + response->code = COAP_RESPONSE_CODE(205); + + /* If the resource is being Observed, return with Observe set */ + if (coap_find_observer(resource, session, token)) { + coap_add_option(response, + COAP_OPTION_OBSERVE, + coap_encode_var_bytes(buf, resource->observe), buf); + } + + /* Response is in plain text format */ + coap_add_option(response, + COAP_OPTION_CONTENT_FORMAT, + coap_encode_var_bytes(buf, COAP_MEDIATYPE_TEXT_PLAIN), buf); + + /* Report on how long this response is valid for */ + coap_add_option(response, + COAP_OPTION_MAXAGE, + coap_encode_var_bytes(buf, 0x01), buf); + + now = time(NULL); + + if (query != NULL && memcmp(query->s, "secs", min(4, query->length)) == 0) { + /* Output secs since Jan 1 1970 */ + len = snprintf((char *)buf, sizeof(buf), "%lu", now); + coap_add_data(response, len, buf); + } else { + /* Output human-readable time */ + struct tm *tmp; + tmp = gmtime(&now); + len = strftime((char *)buf, sizeof(buf), "%b %d %H:%M:%S", tmp); + coap_add_data(response, len, buf); + } + +} +-- + +*Dynamic Resources Set Up* + +[source, c] +-- +#include + +static void +init_resources(coap_context_t *ctx) { + + coap_resource_t *r; + + /* Create a resource to handle PUTs to unknown URIs */ + r = coap_resource_unknown_init(hnd_unknown_put); + coap_add_resource(ctx, r); + +} +-- + +*PUT Unknown Resource Callback Handler* + +[source, c] +-- +#include + +void +hnd_unknown_put(coap_context_t *ctx, coap_resource_t *resource, +coap_session_t *session, coap_pdu_t *request, str *token, str *query, +coap_pdu_t *response) { + + coap_resource_t *r; + int len; + str *uri_path; + + /* get the uri_path */ + uri_path = coap_get_uripath(request); + if (!uri_path) { + response->code = COAP_RESPONSE_CODE(404); + return; + } + + /* Check if new URI Path is valid */ + if (!check_url_fn (uri_path, request->code)) { + response->code = COAP_RESPONSE_CODE(404); + return; + } + + /* Create a resource to handle the new URI */ + r = coap_resource_init((unsigned char *)uri_path->s, uri_path->length, + COAP_RESOURCE_FLAGS_RELEASE_URI|COAP_RESOURCE_FLAGS_NOTIFY_NON); + coap_register_handler(r, COAP_REQUEST_PUT, hnd_put); + coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete); + /* We possibly want to Observe the GETs */ + coap_resource_set_get_observable(r, 1); + coap_register_handler(r, COAP_REQUEST_GET, hnd_get); + coap_add_resource(ctx, r); + + /* Do the PUT for this first instance */ + hnd_put(ctx, resource, session, request, token, query, response); + return; + +} +-- + +*PUT Dynamic Resource Callback Handler* + +[source, c] +-- +#include + +void +hnd_put(coap_context_t *ctx, coap_resource_t *resource, +coap_session_t *session, coap_pdu_t *request, str *token, str *query, +coap_pdu_t *response) { + + str *put_uri_path; + + /* get the uri_path */ + put_uri_path = coap_get_uri_pathpath(request); + if (!put_uri_path) { + response->code = COAP_RESPONSE_CODE(404); + return; + } + + /* .. code .. */ + + /* Need to do this as coap_get_uripath() created it */ + coap_free(put_uri_path); + +} +-- + +*GET Dynamic Resource Callback Handler* + +[source, c] +-- +#include + +void +hnd_get(coap_context_t *ctx, coap_resource_t *resource, +coap_session_t *session, coap_pdu_t *request, str *token, str *query, +coap_pdu_t *response) { + + str get_uri_path; + str *get_query; + coap_opt_iterator_t opt_iter; + coap_opt_filter_t filter; + coap_opt_t *option; + int len; + + get_uri_path = resource->uri_path; + get_query = query; + + /* .. code .. */ + +} +-- + +*DELETE Dynamic Resource Callback Handler* + +[source, c] +-- +#include + +void +hnd_delete(coap_context_t *ctx, coap_resource_t *resource, +coap_session_t *session, coap_pdu_t *request, str *token, str *query, +coap_pdu_t *response) { + + /* .. code .. */ + + /* Dynamic resource no longer required - delete it */ + coap_delete_resource (ctx, resource); + +} +-- + +SEE ALSO +-------- +*coap_attribute*(3), *coap_context*(3) and *coap_handler*(3) + +FURTHER INFORMATION +------------------- +See "RFC7252: The Constrained Application Protocol (CoAP)" for further +information. + +BUGS +---- +Please report bugs on the mailing list for libcoap: +libcoap-developers@lists.sourceforge.net + +AUTHORS +------- +The libcoap project