'\" t .\" Title: coap_handler .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 06/27/2021 .\" Manual: libcoap Manual .\" Source: coap_handler 4.3.0 .\" Language: English .\" .TH "COAP_HANDLER" "3" "06/27/2021" "coap_handler 4\&.3\&.0" "libcoap Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" coap_handler, coap_register_handler, coap_register_response_handler, coap_register_nack_handler, coap_register_ping_handler, coap_register_pong_handler, coap_register_event_handler \- Work with CoAP handlers .SH "SYNOPSIS" .sp \fB#include \fR .sp \fBvoid coap_register_handler(coap_resource_t *\fR\fB\fIresource\fR\fR\fB, coap_request_t \fR\fB\fImethod\fR\fR\fB, coap_method_handler_t \fR\fB\fIhandler\fR\fR\fB);\fR .sp \fBvoid coap_register_response_handler(coap_context_t *\fR\fB\fIcontext\fR\fR\fB, coap_response_handler_t \fR\fB\fIhandler\fR\fR\fB)\fR; .sp \fBvoid coap_register_nack_handler(coap_context_t *\fR\fB\fIcontext\fR\fR\fB, coap_nack_handler_t \fR\fB\fIhandler\fR\fR\fB)\fR; .sp \fBvoid coap_register_ping_handler(coap_context_t *\fR\fB\fIcontext\fR\fR\fB, coap_ping_handler_t \fR\fB\fIhandler\fR\fR\fB)\fR; .sp \fBvoid coap_register_pong_handler(coap_context_t *\fR\fB\fIcontext\fR\fR\fB, coap_pong_handler_t \fR\fB\fIhandler\fR\fR\fB)\fR; .sp \fBvoid coap_register_event_handler(coap_context_t *\fR\fB\fIcontext\fR\fR\fB, coap_event_handler_t \fR\fB\fIhandler\fR\fR\fB)\fR; .sp For specific (D)TLS library support, link with \fB\-lcoap\-3\-notls\fR, \fB\-lcoap\-3\-gnutls\fR, \fB\-lcoap\-3\-openssl\fR, \fB\-lcoap\-3\-mbedtls\fR or \fB\-lcoap\-3\-tinydtls\fR\&. Otherwise, link with \fB\-lcoap\-3\fR to get the default (D)TLS library support\&. .SH "DESCRIPTION" .sp The \fBcoap_register_handler\fR() function registers a callback handler \fIhandler\fR that is called when there is a URI match against the \fIresource\fR and there is a \fImethod\fR (e\&.g\&. PUT, POST etc\&.) match\&. \fImethod\fR can be one of the following\&. .sp .if n \{\ .RS 4 .\} .nf COAP_REQUEST_GET COAP_REQUEST_POST COAP_REQUEST_PUT COAP_REQUEST_DELETE COAP_REQUEST_FETCH COAP_REQUEST_PATCH COAP_REQUEST_IPATCH .fi .if n \{\ .RE .\} .sp The method handler function prototype is defined as: .sp .if n \{\ .RS 4 .\} .nf typedef void (*coap_method_handler_t)(coap_resource_t *resource, coap_session_t *session, const coap_pdu_t *incoming_pdu, const coap_string_t *query, coap_pdu_t *response_pdu); .fi .if n \{\ .RE .\} .sp \fBNOTE:\fR \fIincoming_pdu\fR will be NULL for the GET Handler if this is an internally generated Observe Response\&. \fBcoap_resource_get_uri_path\fR() can be used to determine the URI in this case\&. .sp \fBNOTE:\fR Any data associated with \fIincoming_pdu\fR is no longer be available after exiting this function as \fIincoming_pdu\fR is deleted, unless \fBcoap_add_data\fR() was used to update \fIresponse_pdu\fR where a copy of the data is taken\&. In particular \fIincoming_pdu\fR\*(Aqs data must not be used if calling \fBcoap_add_data_large_response\fR()\&. .sp The \fBcoap_register_response_handler\fR() function defines a request\(cqs response \fIhandler\fR for traffic associated with the \fIcontext\fR\&. The application can use this for handling any response packets, including sending a RST packet if this response was unexpected\&. If \fIhandler\fR is NULL, then the handler is de\-registered\&. .sp The response handler function prototype is defined as: .sp .if n \{\ .RS 4 .\} .nf typedef enum coap_response_t { COAP_RESPONSE_FAIL, /* Response not liked \- send CoAP RST packet */ COAP_RESPONSE_OK /* Response is fine */ } coap_response_t; typedef coap_response_t (*coap_response_handler_t)(coap_session_t *session, const coap_pdu_t *sent, const coap_pdu_t *received, const coap_mid_t id); .fi .if n \{\ .RE .\} .sp \fBNOTE:\fR \fIsent\fR will only be non NULL when the request PDU is Confirmable and this is an ACK or RST response to the request\&. In general, matching of Requests and Responses whould be done by generating unique Tokens for each Request and then matching up based on the Token in \fIreceived\fR Response\&. .sp \fBNOTE:\fR If the returned value is COAP_RESPONSE_FAIL, then a CoAP RST packet will get sent to the server by libcoap\&. The returned value of COAP_RESPONSE_OK indicates that all is OK\&. .sp The \fBcoap_register_nack_handler\fR() function defines a request\(cqs negative response \fIhandler\fR for traffic associated with the \fIcontext\fR\&. If \fIhandler\fR is NULL, then the handler is de\-registered\&. .sp The nack handler function prototype is defined as: .sp .if n \{\ .RS 4 .\} .nf typedef void (*coap_nack_handler_t)(coap_session_t *session, const coap_pdu_t *sent, const coap_nack_reason_t reason, const coap_mid_t mid); .fi .if n \{\ .RE .\} .sp NACKs can be one of the following .sp .if n \{\ .RS 4 .\} .nf COAP_NACK_TOO_MANY_RETRIES COAP_NACK_NOT_DELIVERABLE COAP_NACK_RST COAP_NACK_TLS_FAILED COAP_NACK_ICMP_ISSUE .fi .if n \{\ .RE .\} .sp The \fBcoap_register_ping_handler\fR() function defines a \fIhandler\fR for tracking receipt of CoAP ping traffic associated with the \fIcontext\fR\&. If \fIhandler\fR is NULL, then the handler is de\-registered\&. .sp The ping handler function prototype is defined as: .sp .if n \{\ .RS 4 .\} .nf typedef void (*coap_ping_handler_t)(coap_session_t *session, const coap_pdu_t *received, const coap_mid_t mid); .fi .if n \{\ .RE .\} .sp The \fBcoap_register_pong_handler\fR() function defines a \fIhandler\fR for tracking receipt of CoAP ping response traffic associated with the \fIcontext\fR\&. If \fIhandler\fR is NULL, then the handler is de\-registered\&. .sp The pong handler function prototype is defined as: .sp .if n \{\ .RS 4 .\} .nf typedef void (*coap_pong_handler_t)(coap_session_t *session, const coap_pdu_t *received, const coap_mid_t mid); .fi .if n \{\ .RE .\} .sp The \fBcoap_register_event_handler\fR() function defines a \fIhandler\fR for tracking (D)TLS events associated with the \fIcontext\fR\&. If \fIhandler\fR is NULL, then the handler is de\-registered\&. .sp The event handler function prototype is defined as: .sp .if n \{\ .RS 4 .\} .nf typedef void (*coap_event_handler_t)(coap_session_t *session, const coap_event_t event); .fi .if n \{\ .RE .\} .sp Events can be one of the following .sp .if n \{\ .RS 4 .\} .nf /** * (D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS */ COAP_EVENT_DTLS_CLOSED 0x0000 COAP_EVENT_DTLS_CONNECTED 0x01DE COAP_EVENT_DTLS_RENEGOTIATE 0x01DF COAP_EVENT_DTLS_ERROR 0x0200 /** * TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS */ COAP_EVENT_TCP_CONNECTED 0x1001 COAP_EVENT_TCP_CLOSED 0x1002 COAP_EVENT_TCP_FAILED 0x1003 /** * CSM exchange events for reliable protocols only */ COAP_EVENT_SESSION_CONNECTED 0x2001 COAP_EVENT_SESSION_CLOSED 0x2002 COAP_EVENT_SESSION_FAILED 0x2003 .fi .if n \{\ .RE .\} .SH "EXAMPLES" .sp \fBGET Resource Callback Handler\fR .sp .if n \{\ .RS 4 .\} .nf #include #include static void hnd_get_time(coap_resource_t *resource, coap_session_t *session, coap_pdu_t *request, coap_string_t *query, coap_pdu_t *response) { unsigned char buf[40]; size_t len; time_t now; /* \&.\&.\&. Additional analysis code for resource, request pdu etc\&. \&.\&.\&. */ /* After analysis, generate a suitable response */ now = time(NULL); if (query != NULL && coap_string_equal(query, coap_make_str_const("secs"))) { /* Output secs since Jan 1 1970 */ len = snprintf((char *)buf, sizeof(buf), "%lu", now); } else { /* Output human\-readable time */ struct tm *tmp; tmp = gmtime(&now); if (!tmp) { /* If \*(Aqnow\*(Aq is not valid */ coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_FOUND); return; } len = strftime((char *)buf, sizeof(buf), "%b %d %H:%M:%S", tmp); } coap_pdu_set_code(response, COAP_RESPONSE_CODE_CONTENT); /* * Invoke coap_add_data_large_response() to do all the hard work\&. * * Define the format \- COAP_MEDIATYPE_TEXT_PLAIN \- to add in * Define how long this response is valid for (secs) \- 1 \- to add in\&. * * OBSERVE Option added internally if needed within the function * BLOCK2 Option added internally if output too large * ETAG Option added internally */ coap_add_data_large_response(resource, session, request, response, query, COAP_MEDIATYPE_TEXT_PLAIN, 1, 0, len, buf, NULL, 0); } .fi .if n \{\ .RE .\} .sp \fBPacket Response Handler\fR .sp .if n \{\ .RS 4 .\} .nf #include static int check_token(coap_pdu_t *received) { /* Remove (void) definition if variable is used */ (void)received; /* Code to validate the token is what we expect */ return 1; } static coap_response_t response_handler(coap_context_t *ctx, coap_session_t *session, coap_pdu_t *sent, coap_pdu_t *received, const coap_mid_t mid) { /* Remove (void) definition if variable is used */ (void)ctx; (void)session; (void)mid; coap_pdu_type_t rcv_type = coap_pdu_get_type(received); coap_pdu_code_t rcv_code = coap_pdu_get_code(received); /* check if this is a response to our original request */ if (!check_token(received)) { /* drop if this was just some message, or send RST in case of notification */ if (!sent && (rcv_type == COAP_MESSAGE_CON || rcv_type == COAP_MESSAGE_NON)) { /* Cause a CoAP RST to be sent */ return COAP_RESPONSE_FAIL; } return COAP_RESPONSE_OK; } if (rcv_type == COAP_MESSAGE_RST) { coap_log(LOG_INFO, "got RST\en"); return COAP_RESPONSE_OK; } /* Output the received data, if any */ if (COAP_RESPONSE_CLASS(rcv_code) == 2) { /* Additional code to deal with the response */ } return COAP_RESPONSE_OK; } .fi .if n \{\ .RE .\} .SH "SEE ALSO" .sp \fBcoap_block\fR(3), \fBcoap_observe\fR(3) and \fBcoap_resource\fR(3) .SH "FURTHER INFORMATION" .sp See "RFC7252: The Constrained Application Protocol (CoAP)" for further information\&. .SH "BUGS" .sp Please report bugs on the mailing list for libcoap: libcoap\-developers@lists\&.sourceforge\&.net or raise an issue on GitHub at https://github\&.com/obgm/libcoap/issues .SH "AUTHORS" .sp The libcoap project