Allows to add the CoAP functionality for embedded device.
-
very small memory consumption (in the common case it may be about of 200 bytes for both rx/tx buffers, you can tune a PDU size)
-
implemented CoAP over UDP rfc7252
-
implemented CoAP over TCP draft-coap-tcp-tls-07
-
retransmition/acknowledgment functionality
-
parsing of responses. Received data will be return to the user via callback.
-
helpers for block-wise mode. The block-wise mode is located at a higher level of abstraction than this implementation. See wiki for example.
- Include
tcoap.h
in your code.
#include "tcoap.h"
There are several functions in the tcoap.h
which are declared how external
. You should provide it implementation in your code. See wiki for common case of their implementation.
/**
* @brief In this function user should implement a transmission given data via
* hardware interface (e.g. serial port)
*
*/
extern tcoap_error
tcoap_tx_data(tcoap_handle * const handle, const uint8_t * buf, const uint32_t len);
/**
* @brief In this function user should implement a functionality of waiting response.
* This function has to return a control when timeout will expired or
* when response from server will be received.
*/
extern tcoap_error
tcoap_wait_event(tcoap_handle * const handle, const uint32_t timeout_ms);
/**
* @brief Through this function the 'tcoap' lib will be notifying about events.
* See possible events here 'tcoap_out_signal'.
*/
extern tcoap_error
tcoap_tx_signal(tcoap_handle * const handle, const tcoap_out_signal signal);
/**
* @brief In this function user should implement a generating of message id.
*
*/
extern uint16_t
tcoap_get_message_id(tcoap_handle * const handle);
/**
* @brief In this function user should implement a generating of token.
*
*/
extern tcoap_error
tcoap_fill_token(tcoap_handle * const handle, uint8_t * token, const uint32_t tkl);
/**
* @brief These functions are using for debug purpose, if user will enable debug mode.
*
*/
extern void tcoap_debug_print_packet(tcoap_handle * const handle, const char * msg, uint8_t * data, const uint32_t len);
extern void tcoap_debug_print_options(tcoap_handle * const handle, const char * msg, const tcoap_option_data * options);
extern void tcoap_debug_print_payload(tcoap_handle * const handle, const char * msg, const tcoap_data * const payload);
/**
* @brief In this function user should implement an allocating block of memory.
* In the simple case it may be a static buffer. The 'TCOAP' will make
* two calls of this function before starting work (for rx and tx buffer).
* So, you should have minimum two separate blocks of memory.
*
*/
extern tcoap_error tcoap_alloc_mem_block(uint8_t ** block, const uint32_t min_len);
/**
* @brief In this function user should implement a freeing block of memory.
*
*/
extern tcoap_error tcoap_free_mem_block(uint8_t * block, const uint32_t min_len);
extern void mem_copy(void * dst, const void * src, uint32_t cnt);
extern bool mem_cmp(const void * dst, const void * src, uint32_t cnt);
- Define a
tcoap_handle
object, e.g.
tcoap_handle tc_handle = {
.name = "coap_over_gsm",
.transport = TCOAP_UDP
};
- Implement a transfer of incoming data from your hardware interface (e.g. serial port) to the
tcoap
eithertcoap_rx_byte
ortcoap_rx_packet
. E.g.
void uart1_rx_irq_handler()
{
uint8_t byte = UART1->DR;
tcoap_rx_byte(&tc_handle, byte);
}
void eth_rx_irq_handler(uint8_t * data, uint32_t len)
{
tcoap_rx_packet(&tc_handle, data, len);
}
- Send a coap request and get back response data in the provided callback:
static void data_resource_response_callback(const struct tcoap_request_descriptor * const reqd, const tcoap_result_data * const result)
{
// ... check response
}
void send_request_to_data_resource(uint32_t *token_etag, uint8_t * data, uint32_t len)
{
tcoap_error err;
tcoap_request_descriptor data_request;
tcoap_option_data opt_etag;
tcoap_option_data opt_path;
tcoap_option_data opt_content;
/* fill options - we should adhere an order of options */
opt_content.num = TCOAP_CONTENT_FORMAT_OPT;
opt_content.value = (uint8_t *)"\x2A"; /* 42 = TCOAP_APPLICATION_OCTET_STREAM */
opt_content.len = 1;
opt_content.next = NULL;
opt_path.num = TCOAP_URI_PATH_OPT;
opt_path.value = (uint8_t *)"data";
opt_path.len = 4;
opt_path.next = &opt_content;
opt_etag.num = TCOAP_ETAG_OPT;
opt_etag.value = (uint8_t *)token_etag;
opt_etag.len = 4;
opt_etag.next = &opt_path;
/* fill the request descriptor */
data_request.payload.buf = data;
data_request.payload.len = len;
data_request.code = TCOAP_REQ_POST;
data_request.tkl = 2;
data_request.type = tc_handle.transport == TCOAP_UDP ? TCOAP_MESSAGE_CON : TCOAP_MESSAGE_NON;
data_request.options = &opt_etag;
/* define the callback for response data */
data_request.response_callback = data_resource_response_callback;
/* enable debug */
tcoap_debug(&tc_handle, true);
/* send request */
err = tcoap_send_coap_request(&tc_handle, &data_request);
if (err != TCOAP_OK) {
// error handling
}
}