1// -*- mode:doc; -*- 2// vim: set syntax=asciidoc,tw=0: 3 4coap_handler(3) 5================= 6:doctype: manpage 7:man source: coap_handler 8:man version: @PACKAGE_VERSION@ 9:man manual: libcoap Manual 10 11NAME 12---- 13coap_handler, 14coap_register_handler, 15coap_register_response_handler, 16coap_register_nack_handler, 17coap_register_ping_handler, 18coap_register_pong_handler, 19coap_register_event_handler 20- Work with CoAP handlers 21 22SYNOPSIS 23-------- 24*#include <coap@LIBCOAP_API_VERSION@/coap.h>* 25 26*void coap_register_handler(coap_resource_t *_resource_, coap_request_t 27_method_, coap_method_handler_t _handler_);* 28 29*void coap_register_response_handler(coap_context_t *_context_, 30coap_response_handler_t _handler_)*; 31 32*void coap_register_nack_handler(coap_context_t *_context_, 33coap_nack_handler_t _handler_)*; 34 35*void coap_register_ping_handler(coap_context_t *_context_, 36coap_ping_handler_t _handler_)*; 37 38*void coap_register_pong_handler(coap_context_t *_context_, 39coap_pong_handler_t _handler_)*; 40 41*void coap_register_event_handler(coap_context_t *_context_, 42coap_event_handler_t _handler_)*; 43 44For specific (D)TLS library support, link with 45*-lcoap-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*, 46*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls* 47or *-lcoap-@LIBCOAP_API_VERSION@-tinydtls*. Otherwise, link with 48*-lcoap-@LIBCOAP_API_VERSION@* to get the default (D)TLS library support. 49 50DESCRIPTION 51----------- 52 53The *coap_register_handler*() function registers a callback handler _handler_ 54that is called when there is a URI match against the _resource_ and there is 55a _method_ (e.g. PUT, POST etc.) match. _method_ can be one of the following. 56---- 57COAP_REQUEST_GET 58COAP_REQUEST_POST 59COAP_REQUEST_PUT 60COAP_REQUEST_DELETE 61COAP_REQUEST_FETCH 62COAP_REQUEST_PATCH 63COAP_REQUEST_IPATCH 64---- 65 66The method handler function prototype is defined as: 67[source, c] 68---- 69typedef void (*coap_method_handler_t)(coap_resource_t *resource, 70 coap_session_t *session, 71 const coap_pdu_t *incoming_pdu, 72 const coap_string_t *query, 73 coap_pdu_t *response_pdu); 74---- 75 76*NOTE:* _incoming_pdu_ will be NULL for the GET Handler if this is an 77internally generated Observe Response. *coap_resource_get_uri_path*() 78can be used to determine the URI in this case. 79 80*NOTE:* Any data associated with _incoming_pdu_ is no longer be available after 81exiting this function as _incoming_pdu_ is deleted, unless *coap_add_data*() 82was used to update _response_pdu_ where a copy of the data is taken. In 83particular _incoming_pdu_'s data must not be used if calling 84*coap_add_data_large_response*(). 85 86The *coap_register_response_handler*() function defines a request's response 87_handler_ for traffic associated with the _context_. The application can use 88this for handling any response packets, including sending a RST packet if this 89response was unexpected. If _handler_ is NULL, then the handler is 90de-registered. 91 92The response handler function prototype is defined as: 93[source, c] 94---- 95typedef enum coap_response_t { 96 COAP_RESPONSE_FAIL, /* Response not liked - send CoAP RST packet */ 97 COAP_RESPONSE_OK /* Response is fine */ 98} coap_response_t; 99 100typedef coap_response_t (*coap_response_handler_t)(coap_session_t *session, 101 const coap_pdu_t *sent, 102 const coap_pdu_t *received, 103 const coap_mid_t id); 104---- 105 106*NOTE:* _sent_ will only be non NULL when the request PDU is Confirmable and 107this is an ACK or RST response to the request. In general, matching of 108Requests and Responses whould be done by generating unique Tokens for each Request 109and then matching up based on the Token in _received_ Response. 110 111*NOTE:* If the returned value is COAP_RESPONSE_FAIL, then a CoAP RST packet will get 112sent to the server by libcoap. The returned value of COAP_RESPONSE_OK indicates 113that all is OK. 114 115The *coap_register_nack_handler*() function defines a request's negative 116response _handler_ for traffic associated with the _context_. 117If _handler_ is NULL, then the handler is de-registered. 118 119The nack handler function prototype is defined as: 120[source, c] 121---- 122typedef void (*coap_nack_handler_t)(coap_session_t *session, 123 const coap_pdu_t *sent, 124 const coap_nack_reason_t reason, 125 const coap_mid_t mid); 126---- 127NACKs can be one of the following 128---- 129COAP_NACK_TOO_MANY_RETRIES 130COAP_NACK_NOT_DELIVERABLE 131COAP_NACK_RST 132COAP_NACK_TLS_FAILED 133COAP_NACK_ICMP_ISSUE 134---- 135 136The *coap_register_ping_handler*() function defines a _handler_ for tracking 137receipt of CoAP ping traffic associated with the _context_. If _handler_ is 138NULL, then the handler is de-registered. 139 140The ping handler function prototype is defined as: 141[source, c] 142---- 143typedef void (*coap_ping_handler_t)(coap_session_t *session, 144 const coap_pdu_t *received, 145 const coap_mid_t mid); 146---- 147 148The *coap_register_pong_handler*() function defines a _handler_ for tracking 149receipt of CoAP ping response traffic associated with the _context_. 150If _handler_ is NULL, then the handler is de-registered. 151 152The pong handler function prototype is defined as: 153[source, c] 154---- 155typedef void (*coap_pong_handler_t)(coap_session_t *session, 156 const coap_pdu_t *received, 157 const coap_mid_t mid); 158---- 159 160The *coap_register_event_handler*() function defines a _handler_ for tracking 161(D)TLS events associated with the _context_. If _handler_ is NULL, then 162the handler is de-registered. 163 164The event handler function prototype is defined as: 165[source, c] 166---- 167typedef void (*coap_event_handler_t)(coap_session_t *session, 168 const coap_event_t event); 169---- 170Events can be one of the following 171---- 172/** 173 * (D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS 174 */ 175COAP_EVENT_DTLS_CLOSED 0x0000 176COAP_EVENT_DTLS_CONNECTED 0x01DE 177COAP_EVENT_DTLS_RENEGOTIATE 0x01DF 178COAP_EVENT_DTLS_ERROR 0x0200 179/** 180 * TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS 181 */ 182COAP_EVENT_TCP_CONNECTED 0x1001 183COAP_EVENT_TCP_CLOSED 0x1002 184COAP_EVENT_TCP_FAILED 0x1003 185/** 186 * CSM exchange events for reliable protocols only 187 */ 188COAP_EVENT_SESSION_CONNECTED 0x2001 189COAP_EVENT_SESSION_CLOSED 0x2002 190COAP_EVENT_SESSION_FAILED 0x2003 191---- 192 193EXAMPLES 194-------- 195*GET Resource Callback Handler* 196 197[source, c] 198---- 199#include <coap@LIBCOAP_API_VERSION@/coap.h> 200 201#include <stdio.h> 202 203static void 204hnd_get_time(coap_resource_t *resource, coap_session_t *session, 205coap_pdu_t *request, coap_string_t *query, coap_pdu_t *response) { 206 207 unsigned char buf[40]; 208 size_t len; 209 time_t now; 210 211 /* ... Additional analysis code for resource, request pdu etc. ... */ 212 213 /* After analysis, generate a suitable response */ 214 215 now = time(NULL); 216 217 if (query != NULL && coap_string_equal(query, coap_make_str_const("secs"))) { 218 /* Output secs since Jan 1 1970 */ 219 len = snprintf((char *)buf, sizeof(buf), "%lu", now); 220 } 221 else { 222 /* Output human-readable time */ 223 struct tm *tmp; 224 tmp = gmtime(&now); 225 if (!tmp) { 226 /* If 'now' is not valid */ 227 coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND); 228 return; 229 } 230 len = strftime((char *)buf, sizeof(buf), "%b %d %H:%M:%S", tmp); 231 } 232 coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT); 233 /* 234 * Invoke coap_add_data_large_response() to do all the hard work. 235 * 236 * Define the format - COAP_MEDIATYPE_TEXT_PLAIN - to add in 237 * Define how long this response is valid for (secs) - 1 - to add in. 238 * 239 * OBSERVE Option added internally if needed within the function 240 * BLOCK2 Option added internally if output too large 241 * ETAG Option added internally 242 */ 243 coap_add_data_large_response(resource, session, request, response, 244 query, COAP_MEDIATYPE_TEXT_PLAIN, 1, 0, 245 len, 246 buf, NULL, 0); 247 248} 249---- 250*Packet Response Handler* 251 252[source, c] 253---- 254#include <coap@LIBCOAP_API_VERSION@/coap.h> 255 256static int check_token(coap_pdu_t *received) { 257 /* Remove (void) definition if variable is used */ 258 (void)received; 259 260 /* Code to validate the token is what we expect */ 261 262 return 1; 263} 264 265static coap_response_t 266response_handler(coap_context_t *ctx, coap_session_t *session, 267coap_pdu_t *sent, coap_pdu_t *received, const coap_mid_t mid) { 268 /* Remove (void) definition if variable is used */ 269 (void)ctx; 270 (void)session; 271 (void)mid; 272 coap_pdu_type_t rcv_type = coap_pdu_get_type(received); 273 coap_pdu_code_t rcv_code = coap_pdu_get_code(received); 274 275 /* check if this is a response to our original request */ 276 if (!check_token(received)) { 277 /* drop if this was just some message, or send RST in case of notification */ 278 if (!sent && (rcv_type == COAP_MESSAGE_CON || 279 rcv_type == COAP_MESSAGE_NON)) { 280 /* Cause a CoAP RST to be sent */ 281 return COAP_RESPONSE_FAIL; 282 } 283 return COAP_RESPONSE_OK; 284 } 285 286 if (rcv_type == COAP_MESSAGE_RST) { 287 coap_log(LOG_INFO, "got RST\n"); 288 return COAP_RESPONSE_OK; 289 } 290 291 /* Output the received data, if any */ 292 if (COAP_RESPONSE_CLASS(rcv_code) == 2) { 293 /* Additional code to deal with the response */ 294 295 } 296 return COAP_RESPONSE_OK; 297 298} 299---- 300 301SEE ALSO 302-------- 303*coap_block*(3), *coap_observe*(3) and *coap_resource*(3) 304 305FURTHER INFORMATION 306------------------- 307See "RFC7252: The Constrained Application Protocol (CoAP)" for further 308information. 309 310BUGS 311---- 312Please report bugs on the mailing list for libcoap: 313libcoap-developers@lists.sourceforge.net or raise an issue on GitHub at 314https://github.com/obgm/libcoap/issues 315 316AUTHORS 317------- 318The libcoap project <libcoap-developers@lists.sourceforge.net> 319