Skip to content

Commit

Permalink
coap_net.c: New coap_send_recv() function
Browse files Browse the repository at this point in the history
Supports sending a PDU and waiting for the response PDU for subsequent analysis.

Handles multiple block transfers.
  • Loading branch information
mrdeep1 committed Oct 28, 2024
1 parent 466f1e0 commit a748d78
Show file tree
Hide file tree
Showing 18 changed files with 732 additions and 44 deletions.
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1353,6 +1353,7 @@ man/coap_observe.txt
man/coap_oscore.txt
man/coap_pdu_access.txt
man/coap_pdu_setup.txt
man/coap_pdu_transmit.txt
man/coap_persist.txt
man/coap_proxy.txt
man/coap_recovery.txt
Expand Down
60 changes: 53 additions & 7 deletions examples/coap-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ static int quit = 0;
static void
handle_sigint(int signum COAP_UNUSED) {
quit = 1;
coap_send_recv_terminate();
}

static int
Expand Down Expand Up @@ -387,10 +388,10 @@ nack_handler(coap_session_t *session COAP_UNUSED,
* Response handler used for coap_send() responses
*/
static coap_response_t
message_handler(coap_session_t *session COAP_UNUSED,
const coap_pdu_t *sent,
const coap_pdu_t *received,
const coap_mid_t id COAP_UNUSED) {
response_handler(coap_session_t *session COAP_UNUSED,
const coap_pdu_t *sent,
const coap_pdu_t *received,
const coap_mid_t id COAP_UNUSED) {

coap_opt_t *block_opt;
coap_opt_iterator_t opt_iter;
Expand Down Expand Up @@ -1672,6 +1673,7 @@ main(int argc, char **argv) {
size_t data_len = 0;
coap_addr_info_t *info_list = NULL;
uint8_t cid_every = 0;
coap_pdu_t *resp_pdu;
#ifndef _WIN32
struct sigaction sa;
#endif
Expand Down Expand Up @@ -1924,7 +1926,7 @@ main(int argc, char **argv) {
coap_context_set_block_mode(ctx, block_mode);
if (csm_max_message_size)
coap_context_set_csm_max_message_size(ctx, csm_max_message_size);
coap_register_response_handler(ctx, message_handler);
coap_register_response_handler(ctx, response_handler);
coap_register_event_handler(ctx, event_handler);
coap_register_nack_handler(ctx, nack_handler);
if (the_token.length > COAP_TOKEN_DEFAULT_MAX)
Expand Down Expand Up @@ -1997,8 +1999,52 @@ main(int argc, char **argv) {
if (coap_get_log_level() < COAP_LOG_DEBUG)
coap_show_pdu(COAP_LOG_INFO, pdu);

if (coap_send(session, pdu) == COAP_INVALID_MID) {
coap_log_err("cannot send CoAP pdu\n");
resp_pdu = NULL;
result = coap_send_recv(session, pdu, &resp_pdu, wait_ms);
if (result >= 0) {
if (response_handler(session, pdu, resp_pdu, coap_pdu_get_mid(resp_pdu))
!= COAP_RESPONSE_OK) {
coap_log_err("Response PDU issue\n");
}
if (result < (int)wait_ms) {
wait_ms -= result;
} else {
wait_ms = 0;
quit = 1;
}
} else {
switch (result) {
case -1:
coap_log_info("coap_send_recv: Invalid timeout value %u\n", wait_ms);
break;
case -2:
coap_log_info("coap_send_recv: Failed to transmit PDU\n");
break;
case -3:
/* Nack / Event handler already reported issue */
break;
case -4:
coap_log_info("coap_send_recv: Internal coap_io_process() failed\n");
break;
case -5:
coap_log_info("coap_send_recv: No response received within the timeout\n");
break;
case -6:
coap_log_info("coap_send_recv: Terminated by user\n");
break;
case -7:
coap_log_info("coap_send_recv: Client Mode code not enabled\n");
break;
default:
coap_log_info("coap_send_recv: Invalid return value %d\n", result);
break;
}
quit = 1;
}
coap_delete_pdu(pdu);
coap_delete_pdu(resp_pdu);

if (!doing_observe && repeat_count == 1) {
quit = 1;
}
repeat_count--;
Expand Down
1 change: 1 addition & 0 deletions examples/coap-rd.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ static int quit = 0;
static void
handle_sigint(int signum COAP_UNUSED) {
quit = 1;
coap_send_recv_terminate();
}

static void
Expand Down
1 change: 1 addition & 0 deletions examples/coap-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ static int example_data_media_type = COAP_MEDIATYPE_TEXT_PLAIN;
static void
handle_sigint(int signum COAP_UNUSED) {
quit = 1;
coap_send_recv_terminate();
}

#ifndef _WIN32
Expand Down
32 changes: 32 additions & 0 deletions include/coap3/coap_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,38 @@ COAP_API coap_mid_t coap_send(coap_session_t *session, coap_pdu_t *pdu);

#define coap_send_large(session, pdu) coap_send(session, pdu)

/*
* Send a request PDU and wait for the response PDU.
*
* @param session The CoAP session.
* @param request_pdu The requesting PDU. If this PDU contains the Observe
* option, the unsolocited responses will get handled by the
* defined response handler. This PDU must be freed off by the
* caller after processing.
* @param response_pdu If there is a response, the response PDU is put here.
* This PDU must be freed off by the caller after processing.
* @param timeout_ms Positive maximum number of milliseconds to wait for response
* packet following the request. If there is a large block transfer
* this timeout is for between each request and response.
*
* @return 0 or +ve Time in function in ms after successful transfer (which can be
* bigger than timeout_ms).
* -1 Invalid timeout parameter
* -2 Failed to transmit PDU
* -3 Nack or Event handler invoked, cancelling request
* -4 coap_io_process returned error (fail to re-lock or select())
* -5 Response not received in the given time
* -6 Terminated by user
* -7 Client mode code not enabled
*/
COAP_API int coap_send_recv(coap_session_t *session, coap_pdu_t *request_pdu,
coap_pdu_t **response_pdu, uint32_t timeout_ms);

/**
* Terminate any active coap_send_recv() sessions
*/
void coap_send_recv_terminate(void);

/**
* Invokes the event handler of @p context for the given @p event and
* @p data.
Expand Down
29 changes: 29 additions & 0 deletions include/coap3/coap_net_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,35 @@ int coap_io_process_with_fds_lkd(coap_context_t *ctx, uint32_t timeout_ms,
*/
coap_mid_t coap_send_lkd(coap_session_t *session, coap_pdu_t *pdu);

/*
* Send a request PDU and wait for the response PDU.
*
* Note: This function must be called in the locked state.
*
* @param session The CoAP session.
* @param request_pdu The requesting PDU. If this PDU contains the Observe
* option, the unsolocited responses will get handled by the
* defined response handler. This PDU must be freed off by the
* caller after processing.
* @param response_pdu If there is a response, the response PDU is put here.
* This PDU must be freed off by the caller after processing.
* @param timeout_ms Positive maximum number of milliseconds to wait for response
* packet following the request. If there is a large block transfer
* this timeout is for between each request and response.
*
* @return 0 or +ve Time in function in ms after successful transfer (which can be
* bigger than timeout_ms).
* -1 Invalid timeout parameter
* -2 Failed to transmit PDU
* -3 Nack or Event handler invoked, cancelling request
* -4 coap_io_process returned error (fail to re-lock or select())
* -5 Response not received in the given time
* -6 Terminated by user
* -7 Client mode code not enabled
*/
int coap_send_recv_lkd(coap_session_t *session, coap_pdu_t *request_pdu,
coap_pdu_t **response_pdu, uint32_t timeout_ms);

/**
* Sends an error response with code @p code for request @p request to @p dst.
* @p opts will be passed to coap_new_error_response() to copy marked options
Expand Down
5 changes: 4 additions & 1 deletion include/coap3/coap_pdu_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ struct coap_pdu_t {
uint16_t max_opt; /**< highest option number in PDU */
uint32_t e_token_length; /**< length of Token space (includes leading
extended bytes */
unsigned ref; /**< reference count */
coap_bin_const_t actual_token; /**< Actual token in pdu */
size_t alloc_size; /**< allocated storage for token, options and
payload */
Expand All @@ -165,13 +166,15 @@ struct coap_pdu_t {
* to the pdu, and the pbuf stays exclusive to
* this pdu. */
#endif
const uint8_t *body_data; /**< Holds ptr to re-assembled data or NULL */
const uint8_t *body_data; /**< Holds ptr to re-assembled data or NULL. This
does not get released by coap_delete_pdu() */
size_t body_length; /**< Holds body data length */
size_t body_offset; /**< Holds body data offset */
size_t body_total; /**< Holds body data total size */
coap_lg_xmit_t *lg_xmit; /**< Holds ptr to lg_xmit if sending a set of
blocks */
coap_session_t *session; /**< Session responsible for PDU or NULL */
coap_binary_t *data_free; /**< Data to be freed off by coap_delete_pdu() */
};

/**
Expand Down
5 changes: 5 additions & 0 deletions include/coap3/coap_session_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ struct coap_session_t {
coap_ext_token_check_t */
#if COAP_CLIENT_SUPPORT
uint8_t negotiated_cid; /**< Set for a client if CID negotiated */
uint8_t doing_send_recv; /**< Set if coap_send_recv() active */
#endif /* COAP_CLIENT_SUPPORT */
uint8_t is_dtls13; /**< Set if session is DTLS1.3 */
coap_mid_t remote_test_mid; /**< mid used for checking remote
Expand All @@ -222,6 +223,10 @@ struct coap_session_t {
#if COAP_SERVER_SUPPORT
coap_bin_const_t *client_cid; /**< Contains client CID or NULL */
#endif /* COAP_SERVER_SUPPORT */
#if COAP_CLIENT_SUPPORT
coap_pdu_t *resp_pdu; /**< PDU returned in coap_send_recv() call */
coap_bin_const_t *req_token; /**< Token in request pdu of coap_send_recv() */
#endif /* COAP_CLIENT_SUPPORT */
};

#if COAP_SERVER_SUPPORT
Expand Down
2 changes: 2 additions & 0 deletions libcoap-3.map
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ global:
coap_send_ack;
coap_send_error;
coap_send_message_type;
coap_send_recv;
coap_send_recv_terminate;
coap_send_rst;
coap_server_is_supported;
coap_session_disconnected;
Expand Down
2 changes: 2 additions & 0 deletions libcoap-3.sym
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ coap_send
coap_send_ack
coap_send_error
coap_send_message_type
coap_send_recv
coap_send_recv_terminate
coap_send_rst
coap_server_is_supported
coap_session_disconnected
Expand Down
2 changes: 1 addition & 1 deletion man/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ TXT3 = coap_address.txt \
coap_oscore.txt \
coap_pdu_access.txt \
coap_pdu_setup.txt \
coap_pdu_transmit.txt \
coap_persist.txt \
coap_proxy.txt \
coap_recovery.txt \
Expand Down Expand Up @@ -175,7 +176,6 @@ install-man: install-man3 install-man5 install-man7
@echo ".so man3/coap_pdu_setup.3" > coap_add_option.3
@echo ".so man3/coap_pdu_setup.3" > coap_add_data.3
@echo ".so man3/coap_pdu_setup.3" > coap_add_data_blocked_response.3
@echo ".so man3/coap_pdu_setup.3" > coap_send.3
@echo ".so man3/coap_pdu_setup.3" > coap_path_into_optlist.3
@echo ".so man3/coap_pdu_setup.3" > coap_split_path.3
@echo ".so man3/coap_pdu_setup.3" > coap_query_into_optlist.3
Expand Down
2 changes: 1 addition & 1 deletion man/coap_pdu_access.txt.in
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ get_pdu_information(coap_pdu_t *pdu) {

SEE ALSO
--------
*coap_block*(3) and *coap_pdu_setup*(3)
*coap_block*(3), *coap_pdu_setup*(3) and *coap_pdu_transmit*(3)

FURTHER INFORMATION
-------------------
Expand Down
23 changes: 2 additions & 21 deletions man/coap_pdu_setup.txt.in
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ coap_add_optlist_pdu,
coap_add_option,
coap_add_data,
coap_add_data_blocked_response,
coap_send,
coap_path_into_optlist,
coap_split_path,
coap_query_into_optlist,
Expand Down Expand Up @@ -82,8 +81,6 @@ const uint8_t *_data_);*
coap_pdu_t *_response_, uint16_t _media_type_, int _maxage_, size_t _length_,
const uint8_t *_data_);*

*coap_mid_t coap_send(coap_session_t *_session_, coap_pdu_t *_pdu_);*

*int coap_path_into_optlist(const uint8_t *_path_, size_t _length_,
coap_option_num_t _optnum_, coap_optlist_t **_optlist_chain_);*

Expand Down Expand Up @@ -558,19 +555,6 @@ by this function.
*NOTE:* This function has been superseded by *coap_add_data_large_response*().
See *coap_block*(3).

PDU TRANSMIT FUNCTIONS
----------------------

*Function: coap_send()*

The *coap_send*() function is used to initiate the transmission of the _pdu_
associated with the _session_. The caller must not access or delete _pdu_
after calling *coap_send*() - even if there is a return error.

*NOTE:* For request handlers, returning from the request handler will cause
the response PDU to be transmitted as appropriate and there is no need to call
*coap_send*() to do this.

RETURN VALUES
-------------
*coap_new_pdu*() and *coap_pdu_init*() return a newly created
Expand All @@ -591,9 +575,6 @@ encoded (which can be 0 when encoding 0) or 0 on failure.
*coap_add_option*() returns the size of option added, or 0 on
failure.

*coap_send*() returns the CoAP message ID on success or
COAP_INVALID_MID on failure.

*coap_path_into_optlist*() and *coap_query_into_optlist*() return 1 on
success or 0 on failure.

Expand Down Expand Up @@ -752,8 +733,8 @@ hnd_get_time(coap_resource_t *resource, coap_session_t *session,

SEE ALSO
--------
*coap_block*(3), *coap_observe*(3), *coap_oscore*(3), *coap_pdu_access*(3)
and *coap_resource*(3)
*coap_block*(3), *coap_observe*(3), *coap_oscore*(3), *coap_pdu_access*(3),
*coap_pdu_transmit*(3) and *coap_resource*(3)

FURTHER INFORMATION
-------------------
Expand Down
Loading

0 comments on commit a748d78

Please sign in to comment.