Line data Source code
1 1 : /** @file
2 : * @brief CoAP client API
3 : *
4 : * An API for applications to do CoAP requests
5 : */
6 :
7 : /*
8 : * Copyright (c) 2023 Nordic Semiconductor ASA
9 : *
10 : * SPDX-License-Identifier: Apache-2.0
11 : */
12 : #ifndef ZEPHYR_INCLUDE_NET_COAP_CLIENT_H_
13 : #define ZEPHYR_INCLUDE_NET_COAP_CLIENT_H_
14 :
15 : /**
16 : * @brief CoAP client API
17 : * @defgroup coap_client CoAP client API
18 : * @since 3.4
19 : * @version 0.1.0
20 : * @ingroup networking
21 : * @{
22 : */
23 :
24 : #include <zephyr/net/coap.h>
25 : #include <zephyr/kernel.h>
26 :
27 : #ifdef __cplusplus
28 : extern "C" {
29 : #endif
30 :
31 : /** Maximum size of a CoAP message */
32 1 : #define MAX_COAP_MSG_LEN (CONFIG_COAP_CLIENT_MESSAGE_HEADER_SIZE + \
33 : CONFIG_COAP_CLIENT_MESSAGE_SIZE)
34 :
35 : /**
36 : * @typedef coap_client_response_cb_t
37 : * @brief Callback for CoAP request.
38 : *
39 : * This callback is called for responses to CoAP client requests.
40 : * It is used to indicate errors, response codes from server or to deliver payload.
41 : * Blockwise transfers cause this callback to be called sequentially with increasing payload offset
42 : * and only partial content in buffer pointed by payload parameter.
43 : *
44 : * @param result_code Result code of the response. Negative if there was a failure in send.
45 : * @ref coap_response_code for positive.
46 : * @param offset Payload offset from the beginning of a blockwise transfer.
47 : * @param payload Buffer containing the payload from the response. NULL for empty payload.
48 : * @param len Size of the payload.
49 : * @param last_block Indicates the last block of the response.
50 : * @param user_data User provided context.
51 : */
52 1 : typedef void (*coap_client_response_cb_t)(int16_t result_code,
53 : size_t offset, const uint8_t *payload, size_t len,
54 : bool last_block, void *user_data);
55 :
56 : /**
57 : * @brief Representation of a CoAP client request.
58 : */
59 1 : struct coap_client_request {
60 1 : enum coap_method method; /**< Method of the request */
61 1 : bool confirmable; /**< CoAP Confirmable/Non-confirmable message */
62 1 : const char *path; /**< Path of the requested resource */
63 1 : enum coap_content_format fmt; /**< Content format to be used */
64 1 : const uint8_t *payload; /**< User allocated buffer for send request */
65 1 : size_t len; /**< Length of the payload */
66 1 : coap_client_response_cb_t cb; /**< Callback when response received */
67 1 : const struct coap_client_option *options; /**< Extra options to be added to request */
68 1 : uint8_t num_options; /**< Number of extra options */
69 1 : void *user_data; /**< User provided context */
70 : };
71 :
72 : /**
73 : * @brief Representation of extra options for the CoAP client request
74 : */
75 1 : struct coap_client_option {
76 : /** Option code */
77 1 : uint16_t code;
78 : #if defined(CONFIG_COAP_EXTENDED_OPTIONS_LEN)
79 : /** Option len */
80 : uint16_t len;
81 : /** Buffer for the length */
82 : uint8_t value[CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE];
83 : #else
84 : /** Option len */
85 1 : uint8_t len;
86 : /** Buffer for the length */
87 1 : uint8_t value[12];
88 : #endif
89 : };
90 :
91 : /** @cond INTERNAL_HIDDEN */
92 : struct coap_client_internal_request {
93 : uint8_t request_token[COAP_TOKEN_MAX_LEN];
94 : uint32_t offset;
95 : uint16_t last_id;
96 : uint8_t request_tkl;
97 : bool request_ongoing;
98 : atomic_t in_callback;
99 : struct coap_block_context recv_blk_ctx;
100 : struct coap_block_context send_blk_ctx;
101 : struct coap_pending pending;
102 : struct coap_client_request coap_request;
103 : struct coap_packet request;
104 : uint8_t request_tag[COAP_TOKEN_MAX_LEN];
105 :
106 : /* For GETs with observe option set */
107 : bool is_observe;
108 : int last_response_id;
109 : };
110 :
111 : struct coap_client {
112 : int fd;
113 : struct sockaddr address;
114 : socklen_t socklen;
115 : struct k_mutex lock;
116 : uint8_t send_buf[MAX_COAP_MSG_LEN];
117 : uint8_t recv_buf[MAX_COAP_MSG_LEN];
118 : struct coap_client_internal_request requests[CONFIG_COAP_CLIENT_MAX_REQUESTS];
119 : struct coap_option echo_option;
120 : bool send_echo;
121 : };
122 : /** @endcond */
123 :
124 : /**
125 : * @brief Initialize the CoAP client.
126 : *
127 : * @param[in] client Client instance.
128 : * @param[in] info Name for the receiving thread of the client. Setting this NULL will result as
129 : * default name of "coap_client".
130 : *
131 : * @return int Zero on success, otherwise a negative error code.
132 : */
133 1 : int coap_client_init(struct coap_client *client, const char *info);
134 :
135 : /**
136 : * @brief Send CoAP request
137 : *
138 : * Operation is handled asynchronously using a background thread.
139 : * If the socket isn't connected to a destination address, user must provide a destination address,
140 : * otherwise the address should be set as NULL.
141 : * Once the callback is called with last block set as true, socket can be closed or
142 : * used for another query.
143 : *
144 : * @param client Client instance.
145 : * @param sock Open socket file descriptor.
146 : * @param addr the destination address of the request, NULL if socket is already connected.
147 : * @param req CoAP request structure
148 : * @param params Pointer to transmission parameters structure or NULL to use default values.
149 : * @return zero when operation started successfully or negative error code otherwise.
150 : */
151 :
152 1 : int coap_client_req(struct coap_client *client, int sock, const struct sockaddr *addr,
153 : struct coap_client_request *req, struct coap_transmission_parameters *params);
154 :
155 : /**
156 : * @brief Cancel all current requests.
157 : *
158 : * This is intended for canceling long-running requests (e.g. GETs with the OBSERVE option set)
159 : * which has gone stale for some reason.
160 : * The function should also be called before the corresponding client socket is closed,
161 : * to prevent the socket from being monitored by the internal polling thread.
162 : *
163 : * @param client Client instance.
164 : */
165 1 : void coap_client_cancel_requests(struct coap_client *client);
166 :
167 : /**
168 : * @brief Cancel matching requests.
169 : *
170 : * This function cancels all CoAP client request that matches the given request.
171 : * The request is matched based on the method, path, callback and user_data, if provided.
172 : * Any field set to NULL is considered a wildcard.
173 : *
174 : * (struct coap_client_request){0} cancels all requests.
175 : * (struct coap_client_request){.method = COAP_METHOD_GET} cancels all GET requests.
176 : *
177 : * @param client Pointer to the CoAP client instance.
178 : * @param req Pointer to the CoAP client request to be canceled.
179 : */
180 1 : void coap_client_cancel_request(struct coap_client *client, struct coap_client_request *req);
181 :
182 : /**
183 : * @brief Initialise a Block2 option to be added to a request
184 : *
185 : * If the application expects a request to require a blockwise transfer, it may pre-emptively
186 : * suggest a maximum block size to the server - see RFC7959 Figure 3: Block-Wise GET with Early
187 : * Negotiation.
188 : *
189 : * This helper function returns a Block2 option to send with the initial request.
190 : *
191 : * @return CoAP client initial Block2 option structure
192 : */
193 1 : struct coap_client_option coap_client_option_initial_block2(void);
194 :
195 : /**
196 : * @brief Check if client has ongoing exchange.
197 : *
198 : * @note Function not only considers ongoing requests, but also lifetime of completed requests
199 : * (which provides graceful duplicates handling).
200 : *
201 : * @note For socket handling.
202 : * Function does no consider a socket POLL that has started before this call,
203 : * therefore it is recommended to wait out POLL timeout before closing socket
204 : * (e.g. call coap_client_cancel_requests() which applies delay for timeout).
205 : *
206 : * @param client Pointer to the CoAP client instance.
207 : *
208 : * @return true if there is an ongoing exchange, false otherwise.
209 : */
210 1 : bool coap_client_has_ongoing_exchange(struct coap_client *client);
211 :
212 : #ifdef __cplusplus
213 : }
214 : #endif
215 :
216 : /**
217 : * @}
218 : */
219 :
220 : #endif /* ZEPHYR_INCLUDE_NET_COAP_CLIENT_H_ */
|