21#include <lwip/timeouts.h>
22#include <lwip/tcpip.h>
26 return !COAP_DISABLE_TCP;
34extern sys_sem_t coap_io_timeout_sem;
35extern uint32_t coap_lwip_in_call_back_ref;
40 struct tcp_pcb *tcp_pcb;
46do_tcp_err(
void *arg, err_t err) {
56 coap_lwip_in_call_back_ref++;
64 session->
sock.tcp_pcb = NULL;
67 coap_lwip_in_call_back_ref--;
71 sys_sem_signal(&coap_io_timeout_sem);
81coap_tcp_recv(
void *arg,
struct tcp_pcb *tpcb,
struct pbuf *p, err_t err) {
92 tcp_close(sock->tcp_pcb);
93 tcp_arg(sock->tcp_pcb, NULL);
94 tcp_recv(sock->tcp_pcb, NULL);
100 sys_sem_signal(&coap_io_timeout_sem);
103 }
else if (err != ERR_OK) {
108 tcp_recved(sock->tcp_pcb, p->tot_len);
110 sys_sem_signal(&coap_io_timeout_sem);
119 coap_lwip_in_call_back_ref++;
123 coap_lwip_in_call_back_ref--;
127 sys_sem_signal(&coap_io_timeout_sem);
132#if COAP_CLIENT_SUPPORT
135do_tcp_connected(
void *arg,
struct tcp_pcb *tpcb, err_t err) {
143 coap_lwip_in_call_back_ref++;
148 tcp_recv(tpcb, coap_tcp_recv);
152 coap_lwip_in_call_back_ref--;
156 sys_sem_signal(&coap_io_timeout_sem);
179 sock->tcp_pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
180 if (sock->tcp_pcb == NULL) {
184 tcp_arg(sock->tcp_pcb, sock->
session);
185 tcp_recv(sock->tcp_pcb, coap_tcp_recv);
186 tcp_err(sock->tcp_pcb, do_tcp_err);
189#if LWIP_IPV6 && LWIP_IPV4
190 if (l_local_if.
addr.type == IPADDR_TYPE_V6)
191 l_local_if.
addr.type = IPADDR_TYPE_ANY;
193 err = tcp_bind(sock->tcp_pcb, &l_local_if.
addr, l_local_if.port);
195 tcp_arg(sock->tcp_pcb, NULL);
196 tcp_recv(sock->tcp_pcb, NULL);
197 tcp_close(sock->tcp_pcb);
198 sock->tcp_pcb = NULL;
203 if (connect_addr.port == 0)
204 connect_addr.port = htons(default_port);
206 err = tcp_connect(sock->tcp_pcb, &connect_addr.
addr, connect_addr.port,
231#if COAP_SERVER_SUPPORT
234do_tcp_accept(
void *arg,
struct tcp_pcb *newpcb, err_t err) {
238 err_t ret_err = ERR_OK;
240 if ((err != ERR_OK) || (newpcb == NULL)) {
247 coap_lwip_in_call_back_ref++;
252 session->
sock.tcp_pcb = newpcb;
254 tcp_arg(newpcb, session);
255 tcp_setprio(newpcb, TCP_PRIO_MIN);
256 tcp_recv(newpcb, coap_tcp_recv);
257 tcp_err(newpcb, do_tcp_err);
262 coap_lwip_in_call_back_ref--;
266 sys_sem_signal(&coap_io_timeout_sem);
277 struct tcp_pcb *tcp_pcb;
279 sock->tcp_pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
280 if (sock->tcp_pcb == NULL)
283#if LWIP_IPV6 && LWIP_IPV4
284 if (l_listen.
addr.type == IPADDR_TYPE_V6)
285 l_listen.
addr.type = IPADDR_TYPE_ANY;
287 tcp_arg(sock->tcp_pcb, sock->
endpoint);
288 err = tcp_bind(sock->tcp_pcb, &l_listen.
addr, l_listen.port);
290 tcp_arg(sock->tcp_pcb, NULL);
291 tcp_recv(sock->tcp_pcb, NULL);
292 tcp_close(sock->tcp_pcb);
293 sock->tcp_pcb = NULL;
296 tcp_pcb = tcp_listen(sock->tcp_pcb);
298 sock->tcp_pcb = tcp_pcb;
299 tcp_accept(sock->tcp_pcb, do_tcp_accept);
301 tcp_arg(sock->tcp_pcb, NULL);
302 tcp_recv(sock->tcp_pcb, NULL);
303 tcp_close(sock->tcp_pcb);
304 sock->tcp_pcb = NULL;
308 *bound_addr = l_listen;
318 struct tcp_pcb *tcp_pcb = (
struct tcp_pcb *)extra;
322 new_client->tcp_pcb = tcp_pcb;
323 local_addr->
addr = tcp_pcb->local_ip;
324 local_addr->port = tcp_pcb->local_port;
325 remote_addr->
addr = tcp_pcb->remote_ip;
326 remote_addr->port = tcp_pcb->remote_port;
333coap_lwip_tcp_write(
void *ctx) {
334 coap_lwip_tcp_t *cb_ctx = (coap_lwip_tcp_t *)ctx;
337 if (cb_ctx && cb_ctx->pbuf) {
338 err = tcp_write(cb_ctx->tcp_pcb, cb_ctx->pbuf->payload, cb_ctx->pbuf->len, 1);
343 pbuf_free(cb_ctx->pbuf);
345 sys_sem_signal(&coap_io_timeout_sem);
360 pbuf = pbuf_alloc(PBUF_TRANSPORT, data_len, PBUF_RAM);
363 memcpy(pbuf->payload, data, data_len);
366 if (coap_lwip_in_call_back_ref == 0) {
376 cb_ctx->session = sock->
session;
378 cb_ctx->tcp_pcb = sock->tcp_pcb;
379 err = tcpip_try_callback(coap_lwip_tcp_write, cb_ctx);
389 err = tcp_write(sock->tcp_pcb, pbuf->payload, pbuf->len, 1);
411 if (data_len < sock->p->len) {
412 uint8_t *ptr = (uint8_t *)sock->p->payload;
415 memcpy(data, sock->p->payload, data_len);
416 sock->p->payload = &ptr[data_len];
417 sock->p->len -= data_len;
418 tcp_recved(sock->tcp_pcb, data_len);
421 data_len = sock->p->len;
422 memcpy(data, sock->p->payload, sock->p->len);
425 tcp_recved(sock->tcp_pcb, data_len);
434coap_lwip_tcp_close(
void *ctx) {
435 struct tcp_pcb *tcp_pcb = (
struct tcp_pcb *)ctx;
438 tcp_err(tcp_pcb, NULL);
439 tcp_arg(tcp_pcb, NULL);
440 tcp_recv(tcp_pcb, NULL);
444#if COAP_SERVER_SUPPORT
446coap_lwip_endpoint_tcp_close(
void *ctx) {
447 struct tcp_pcb *tcp_pcb = (
struct tcp_pcb *)ctx;
450 tcp_accept(tcp_pcb, NULL);
451 tcp_err(tcp_pcb, NULL);
452 tcp_arg(tcp_pcb, NULL);
453 tcp_recv(tcp_pcb, NULL);
462 struct tcp_pcb *tcp_pcb = sock->tcp_pcb;
464 sock->tcp_pcb = NULL;
469 if (coap_lwip_in_call_back_ref == 0) {
470#if COAP_SERVER_SUPPORT
472 err = tcpip_try_callback(coap_lwip_endpoint_tcp_close, tcp_pcb);
475 err = tcpip_try_callback(coap_lwip_tcp_close, tcp_pcb);
484#if COAP_SERVER_SUPPORT
486 tcp_accept(tcp_pcb, NULL);
488 tcp_recv(tcp_pcb, NULL);
489 tcp_arg(tcp_pcb, NULL);
490 tcp_err(tcp_pcb, NULL);
506#pragma GCC diagnostic ignored "-Wunused-function"
void coap_address_copy(coap_address_t *dst, const coap_address_t *src)
@ COAP_NACK_NOT_DELIVERABLE
#define COAP_SOCKET_CAN_CONNECT
non blocking client socket can now connect without blocking
#define COAP_SOCKET_WANT_CONNECT
non blocking client socket is waiting for connect
#define COAP_SOCKET_CONNECTED
the socket is connected
Library specific build wrapper for coap_internal.h.
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
int coap_handle_event_lkd(coap_context_t *context, coap_event_t event, coap_session_t *session)
Invokes the event handler of context for the given event and data.
void coap_ticks(coap_tick_t *t)
Returns the current value of an internal tick counter.
@ COAP_EVENT_TCP_FAILED
Triggered when TCP layer fails for some reason.
#define coap_lock_invert(alt_lock, failed)
Dummy for no thread-safe code.
#define coap_lock_unlock()
Dummy for no thread-safe code.
#define coap_lock_lock(failed)
Dummy for no thread-safe code.
const char * coap_session_str(const coap_session_t *session)
Get session description.
#define coap_log_warn(...)
void coap_connect_session(coap_session_t *session, coap_tick_t now)
void coap_read_session(coap_context_t *ctx, coap_session_t *session, coap_tick_t now)
void coap_session_disconnected_lkd(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
coap_session_t * coap_new_server_session(coap_context_t *ctx, coap_endpoint_t *ep, void *extra)
Creates a new server session for the specified endpoint.
int coap_socket_bind_tcp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
Create a new TCP socket and then listen for new incoming TCP sessions.
ssize_t coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len)
Function interface for data stream receiving off a socket.
ssize_t coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len)
Function interface for data stream sending off a socket.
int coap_socket_connect_tcp1(coap_socket_t *sock, const coap_address_t *local_if, const coap_address_t *server, int default_port, coap_address_t *local_addr, coap_address_t *remote_addr)
Create a new TCP socket and initiate the connection.
int coap_socket_accept_tcp(coap_socket_t *server, coap_socket_t *new_client, coap_address_t *local_addr, coap_address_t *remote_addr, void *extra)
Accept a new incoming TCP session.
void coap_socket_strm_close(coap_socket_t *sock)
Function interface to close off a stream socket.
int coap_socket_connect_tcp2(coap_socket_t *sock, coap_address_t *local_addr, coap_address_t *remote_addr)
Complete the TCP Connection.
int coap_tcp_is_supported(void)
Check whether TCP is available.
coap_address_t local
local address and port
Multi-purpose address abstraction.
union coap_address_t::@0 addr
Abstraction of virtual endpoint that can be attached to coap_context_t.
coap_context_t * context
endpoint's context
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
coap_socket_t sock
socket object for the session, if any
coap_addr_tuple_t addr_info
remote/local address info
coap_context_t * context
session's context
coap_session_t * session
Used to determine session owner.
coap_endpoint_t * endpoint
Used by the epoll logic for a listening endpoint.
coap_socket_flags_t flags
1 or more of COAP_SOCKET* flag values