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