libcoap  4.2.0rc1
coap_session.c
Go to the documentation of this file.
1 /* session.c -- Session management for libcoap
2 *
3 * Copyright (C) 2017 Jean-Claue Michelou <jcm@spinetix.com>
4 *
5 * This file is part of the CoAP library libcoap. Please see
6 * README for terms of use.
7 */
8 
9 #ifndef _COAP_SESSION_H_
10 #define _COAP_SESSION_H_
11 
12 
13 #include "coap_config.h"
14 #include "coap_io.h"
15 #include "coap_session.h"
16 #include "net.h"
17 #include "debug.h"
18 #include "mem.h"
19 #include "resource.h"
20 #include "utlist.h"
21 #include "encode.h"
22 #include <stdio.h>
23 
24 
25 void
26 coap_session_set_max_retransmit (coap_session_t *session, unsigned int value) {
27  if (value > 0)
28  session->max_retransmit = value;
29  coap_log(LOG_DEBUG, "*** %s: session max_retransmit set to %d\n",
30  coap_session_str(session), session->max_retransmit);
31  return;
32 }
33 
34 void
36  if (value.integer_part > 0 && value.fractional_part < 1000)
37  session->ack_timeout = value;
38  coap_log(LOG_DEBUG, "*** %s: session ack_timeout set to %d.%03d\n",
39  coap_session_str(session), session->ack_timeout.integer_part,
40  session->ack_timeout.fractional_part);
41  return;
42 }
43 
44 void
46  coap_fixed_point_t value) {
47  if (value.integer_part > 0 && value.fractional_part < 1000)
48  session->ack_random_factor = value;
49  coap_log(LOG_DEBUG, "*** %s: session ack_random_factor set to %d.%03d\n",
52  return;
53 }
54 
55 unsigned int
57  return session->max_retransmit;
58 }
59 
62  return session->ack_timeout;
63 }
64 
67  return session->ack_random_factor;
68 }
69 
72  ++session->ref;
73  return session;
74 }
75 
76 void
78  if (session) {
79  assert(session->ref > 0);
80  if (session->ref > 0)
81  --session->ref;
82  if (session->ref == 0 && session->type == COAP_SESSION_TYPE_CLIENT)
83  coap_session_free(session);
84  }
85 }
86 
87 void
88 coap_session_set_app_data(coap_session_t *session, void *app_data) {
89  assert(session);
90  session->app = app_data;
91 }
92 
93 void *
95  assert(session);
96  return session->app;
97 }
98 
99 static coap_session_t *
101  const coap_address_t *local_if, const coap_address_t *local_addr,
102  const coap_address_t *remote_addr, int ifindex, coap_context_t *context,
103  coap_endpoint_t *endpoint) {
105  if (!session)
106  return NULL;
107  memset(session, 0, sizeof(*session));
108  session->proto = proto;
109  session->type = type;
110  if (local_if)
111  coap_address_copy(&session->local_if, local_if);
112  else
113  coap_address_init(&session->local_if);
114  if (local_addr)
115  coap_address_copy(&session->local_addr, local_addr);
116  else
117  coap_address_init(&session->local_addr);
118  if (remote_addr)
119  coap_address_copy(&session->remote_addr, remote_addr);
120  else
121  coap_address_init(&session->remote_addr);
122  session->ifindex = ifindex;
123  session->context = context;
124  session->endpoint = endpoint;
125  if (endpoint)
126  session->mtu = endpoint->default_mtu;
127  else
128  session->mtu = COAP_DEFAULT_MTU;
129  if (proto == COAP_PROTO_DTLS) {
130  session->tls_overhead = 29;
131  if (session->tls_overhead >= session->mtu) {
132  session->tls_overhead = session->mtu;
133  coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n");
134  }
135  }
139  session->dtls_event = -1;
140 
141  /* initialize message id */
142  prng((unsigned char *)&session->tx_mid, sizeof(session->tx_mid));
143 
144  return session;
145 }
146 
148  coap_queue_t *q, *tmp;
149 
150  if (!session)
151  return;
152  assert(session->ref == 0);
153  if (session->ref)
154  return;
155  if (session->partial_pdu)
156  coap_delete_pdu(session->partial_pdu);
157  if (session->proto == COAP_PROTO_DTLS)
158  coap_dtls_free_session(session);
159  else if (session->proto == COAP_PROTO_TLS)
160  coap_tls_free_session(session);
161  if (session->sock.flags != COAP_SOCKET_EMPTY)
162  coap_socket_close(&session->sock);
163  if (session->endpoint) {
164  if (session->endpoint->sessions)
165  LL_DELETE(session->endpoint->sessions, session);
166  } else if (session->context) {
167  if (session->context->sessions)
168  LL_DELETE(session->context->sessions, session);
169  }
170  if (session->psk_identity)
171  coap_free(session->psk_identity);
172  if (session->psk_key)
173  coap_free(session->psk_key);
174 
175  LL_FOREACH_SAFE(session->delayqueue, q, tmp) {
176  if (q->pdu->type==COAP_MESSAGE_CON && session->context && session->context->nack_handler)
177  session->context->nack_handler(session->context, session, q->pdu, session->proto == COAP_PROTO_DTLS ? COAP_NACK_TLS_FAILED : COAP_NACK_NOT_DELIVERABLE, q->id);
178  coap_delete_node(q);
179  }
180 
181  debug("*** %s: session closed\n", coap_session_str(session));
182 
183  coap_free_type(COAP_SESSION, session);
184 }
185 
187  size_t max_with_header = (size_t)(session->mtu - session->tls_overhead);
188  if (COAP_PROTO_NOT_RELIABLE(session->proto))
189  return max_with_header > 4 ? max_with_header - 4 : 0;
190  /* we must assume there is no token to be on the safe side */
191  if (max_with_header <= 2)
192  return 0;
193  else if (max_with_header <= COAP_MAX_MESSAGE_SIZE_TCP0 + 2)
194  return max_with_header - 2;
195  else if (max_with_header <= COAP_MAX_MESSAGE_SIZE_TCP8 + 3)
196  return max_with_header - 3;
197  else if (max_with_header <= COAP_MAX_MESSAGE_SIZE_TCP16 + 4)
198  return max_with_header - 4;
199  else
200  return max_with_header - 6;
201 }
202 
203 void coap_session_set_mtu(coap_session_t *session, unsigned mtu) {
204 #if defined(WITH_CONTIKI) || defined(WITH_LWIP)
205  if (mtu > COAP_MAX_MESSAGE_SIZE_TCP16 + 4)
206  mtu = COAP_MAX_MESSAGE_SIZE_TCP16 + 4;
207 #endif
208  session->mtu = mtu;
209  if (session->tls_overhead >= session->mtu) {
210  session->tls_overhead = session->mtu;
211  coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n");
212  }
213 }
214 
215 ssize_t coap_session_send(coap_session_t *session, const uint8_t *data, size_t datalen) {
216  ssize_t bytes_written;
217 
218  coap_socket_t *sock = &session->sock;
219  if (sock->flags == COAP_SOCKET_EMPTY) {
220  assert(session->endpoint != NULL);
221  sock = &session->endpoint->sock;
222  }
223 
224  bytes_written = coap_socket_send(sock, session, data, datalen);
225  if (bytes_written == (ssize_t)datalen) {
226  coap_ticks(&session->last_rx_tx);
227  debug("* %s: sent %zd bytes\n", coap_session_str(session), datalen);
228  } else {
229  debug("* %s: failed to send %zd bytes\n", coap_session_str(session), datalen);
230  }
231  return bytes_written;
232 }
233 
234 ssize_t coap_session_write(coap_session_t *session, const uint8_t *data, size_t datalen) {
235  ssize_t bytes_written = coap_socket_write(&session->sock, data, datalen);
236  if (bytes_written > 0) {
237  coap_ticks(&session->last_rx_tx);
238  debug("* %s: sent %zd bytes\n", coap_session_str(session), datalen);
239  } else if (bytes_written < 0) {
240  debug( "* %s: failed to send %zd bytes\n", coap_session_str(session), datalen );
241  }
242  return bytes_written;
243 }
244 
245 ssize_t
247  coap_queue_t *node)
248 {
249  if ( node ) {
250  coap_queue_t *removed = NULL;
251  coap_remove_from_queue(&session->context->sendqueue, session, node->id, &removed);
252  assert(removed == node);
254  node->session = NULL;
255  node->t = 0;
256  } else {
257  coap_queue_t *q = NULL;
258  /* Check that the same tid is not getting re-used in violation of RFC7252 */
259  LL_FOREACH(session->delayqueue, q) {
260  if (q->id == pdu->tid) {
261  coap_log(LOG_ERR, "** %s tid=%d: already in-use - dropped\n", coap_session_str(session), pdu->tid);
262  return COAP_INVALID_TID;
263  }
264  }
265  node = coap_new_node();
266  if (node == NULL)
267  return COAP_INVALID_TID;
268  node->id = pdu->tid;
269  node->pdu = pdu;
270  if (pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
271  uint8_t r;
272  prng(&r, sizeof(r));
273  /* add timeout in range [ACK_TIMEOUT...ACK_TIMEOUT * ACK_RANDOM_FACTOR] */
274  node->timeout = coap_calc_timeout(session, r);
275  }
276  }
277  LL_APPEND(session->delayqueue, node);
278  debug("** %s tid=%d: delayed\n", coap_session_str(session), node->id);
279  return COAP_PDU_DELAYED;
280 }
281 
283  coap_pdu_t *pdu;
284  uint8_t buf[4];
285  assert(COAP_PROTO_RELIABLE(session->proto));
286  debug("*** %s: sending CSM\n", coap_session_str(session));
287  session->state = COAP_SESSION_STATE_CSM;
288  session->partial_write = 0;
289  if (session->mtu == 0)
290  session->mtu = COAP_DEFAULT_MTU; /* base value */
292  if ( pdu == NULL
294  coap_encode_var_safe(buf, sizeof(buf),
295  COAP_DEFAULT_MAX_PDU_RX_SIZE), buf) == 0
296  || coap_pdu_encode_header(pdu, session->proto) == 0
297  ) {
299  } else {
300  ssize_t bytes_written = coap_session_send_pdu(session, pdu);
301  if (bytes_written != (ssize_t)pdu->used_size + pdu->hdr_size)
303  }
304  if (pdu)
305  coap_delete_pdu(pdu);
306 }
307 
309  coap_pdu_t *ping;
310  if (session->state != COAP_SESSION_STATE_ESTABLISHED)
311  return 0;
313  if (!ping)
314  return COAP_INVALID_TID;
315  return coap_send(session, ping);
316 }
317 
319  if (session->state != COAP_SESSION_STATE_ESTABLISHED) {
320  coap_log(LOG_DEBUG, "*** %s: session connected\n", coap_session_str(session));
321  if (session->state == COAP_SESSION_STATE_CSM)
323  }
324 
326  session->partial_write = 0;
327 
328  if ( session->proto==COAP_PROTO_DTLS) {
329  session->tls_overhead = coap_dtls_get_overhead(session);
330  if (session->tls_overhead >= session->mtu) {
331  session->tls_overhead = session->mtu;
332  coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n");
333  }
334  }
335 
336  while (session->delayqueue && session->state == COAP_SESSION_STATE_ESTABLISHED) {
337  ssize_t bytes_written;
338  coap_queue_t *q = session->delayqueue;
339  if (q->pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
340  if (session->con_active >= COAP_DEFAULT_NSTART)
341  break;
342  session->con_active++;
343  }
344  /* Take entry off the queue */
345  session->delayqueue = q->next;
346  q->next = NULL;
347 
348  coap_log(LOG_DEBUG, "** %s: tid=%d: transmitted after delay\n",
349  coap_session_str(session), (int)q->pdu->tid);
350  bytes_written = coap_session_send_pdu(session, q->pdu);
351  if (q->pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
352  if (coap_wait_ack(session->context, session, q) >= 0)
353  q = NULL;
354  }
355  if (COAP_PROTO_NOT_RELIABLE(session->proto)) {
356  if (q)
357  coap_delete_node(q);
358  if (bytes_written < 0)
359  break;
360  } else {
361  if (bytes_written <= 0 || (size_t)bytes_written < q->pdu->used_size + q->pdu->hdr_size) {
362  q->next = session->delayqueue;
363  session->delayqueue = q;
364  if (bytes_written > 0)
365  session->partial_write = (size_t)bytes_written;
366  break;
367  } else {
368  coap_delete_node(q);
369  }
370  }
371  }
372 }
373 
375  (void)reason;
376  coap_session_state_t state = session->state;
377 
378  coap_log(LOG_DEBUG, "*** %s: session disconnected (reason %d)\n",
379  coap_session_str(session), reason);
380 #ifndef WITHOUT_OBSERVE
381  coap_delete_observers( session->context, session );
382 #endif
383 
384  if ( session->tls) {
385  if (session->proto == COAP_PROTO_DTLS)
386  coap_dtls_free_session(session);
387  else if (session->proto == COAP_PROTO_TLS)
388  coap_tls_free_session(session);
389  session->tls = NULL;
390  }
391 
392  session->state = COAP_SESSION_STATE_NONE;
393 
394  if (session->partial_pdu) {
395  coap_delete_pdu(session->partial_pdu);
396  session->partial_pdu = NULL;
397  }
398  session->partial_read = 0;
399 
400  while (session->delayqueue) {
401  coap_queue_t *q = session->delayqueue;
402  session->delayqueue = q->next;
403  q->next = NULL;
404  debug("** %s tid=%d: not transmitted after delay\n",
405  coap_session_str(session), q->id);
406  if (q->pdu->type==COAP_MESSAGE_CON
407  && COAP_PROTO_NOT_RELIABLE(session->proto)
408  && reason != COAP_NACK_RST)
409  {
410  if (coap_wait_ack(session->context, session, q) >= 0)
411  q = NULL;
412  }
413  if (q && q->pdu->type == COAP_MESSAGE_CON
414  && session->context->nack_handler)
415  {
416  session->context->nack_handler(session->context, session, q->pdu,
417  reason, q->id);
418  }
419  if (q)
420  coap_delete_node(q);
421  }
422  if ( COAP_PROTO_RELIABLE(session->proto) ) {
423  if (session->sock.flags != COAP_SOCKET_EMPTY) {
424  coap_socket_close(&session->sock);
425  coap_handle_event(session->context,
428  }
429  if (state != COAP_SESSION_STATE_NONE) {
430  coap_handle_event(session->context,
433  }
434  }
435 }
436 
439  const coap_packet_t *packet, coap_tick_t now) {
440  coap_session_t *session = NULL;
441  unsigned int num_idle = 0;
442  coap_session_t *oldest = NULL;
443 
444  endpoint->hello.ifindex = -1;
445 
446  LL_FOREACH(endpoint->sessions, session) {
447  if (session->ifindex == packet->ifindex &&
448  coap_address_equals(&session->local_addr, &packet->dst) &&
449  coap_address_equals(&session->remote_addr, &packet->src))
450  {
451  session->last_rx_tx = now;
452  return session;
453  }
454  if (session->ref == 0 && session->delayqueue == NULL && session->type == COAP_SESSION_TYPE_SERVER) {
455  ++num_idle;
456  if (oldest==NULL || session->last_rx_tx < oldest->last_rx_tx)
457  oldest = session;
458  }
459  }
460 
461  if (endpoint->context->max_idle_sessions > 0 && num_idle >= endpoint->context->max_idle_sessions)
462  coap_session_free(oldest);
463 
464  if (endpoint->proto == COAP_PROTO_DTLS) {
465  session = &endpoint->hello;
466  coap_address_copy(&session->local_addr, &packet->dst);
467  coap_address_copy(&session->remote_addr, &packet->src);
468  session->ifindex = packet->ifindex;
469  } else {
470  session = coap_make_session(endpoint->proto, COAP_SESSION_TYPE_SERVER,
471  NULL, &packet->dst, &packet->src, packet->ifindex, endpoint->context,
472  endpoint);
473  if (session) {
474  session->last_rx_tx = now;
475  if (endpoint->proto == COAP_PROTO_UDP)
477  LL_PREPEND(endpoint->sessions, session);
478  debug("*** %s: new incoming session\n", coap_session_str(session));
479  }
480  }
481 
482  return session;
483 }
484 
487  const coap_packet_t *packet, coap_tick_t now) {
489  COAP_SESSION_TYPE_SERVER, NULL, &packet->dst, &packet->src,
490  packet->ifindex, endpoint->context, endpoint);
491  if (session) {
492  session->last_rx_tx = now;
494  session->tls = coap_dtls_new_server_session(session);
495  if (session->tls) {
497  LL_PREPEND(endpoint->sessions, session);
498  debug("*** %s: new incoming session\n", coap_session_str(session));
499  } else {
500  coap_session_free(session);
501  session = NULL;
502  }
503  }
504  return session;
505 }
506 
507 static coap_session_t *
509  coap_context_t *ctx,
510  const coap_address_t *local_if,
511  const coap_address_t *server,
512  coap_proto_t proto
513 ) {
514  coap_session_t *session = NULL;
515 
516  assert(server);
517  assert(proto != COAP_PROTO_NONE);
518 
519  session = coap_make_session(proto, COAP_SESSION_TYPE_CLIENT, local_if,
520  local_if, server, 0, ctx, NULL);
521  if (!session)
522  goto error;
523 
524  coap_session_reference(session);
525 
526  if (proto == COAP_PROTO_UDP || proto == COAP_PROTO_DTLS) {
527  if (!coap_socket_connect_udp(&session->sock, &session->local_if, server,
529  &session->local_addr, &session->remote_addr)) {
530  goto error;
531  }
532  } else if (proto == COAP_PROTO_TCP || proto == COAP_PROTO_TLS) {
533  if (!coap_socket_connect_tcp1(&session->sock, &session->local_if, server,
535  &session->local_addr, &session->remote_addr)) {
536  goto error;
537  }
538  }
539 
541  if (local_if)
542  session->sock.flags |= COAP_SOCKET_BOUND;
543  LL_PREPEND(ctx->sessions, session);
544  return session;
545 
546 error:
547  coap_session_release(session);
548  return NULL;
549 }
550 
551 static coap_session_t *
553  if (session->proto == COAP_PROTO_UDP) {
555  } else if (session->proto == COAP_PROTO_DTLS) {
556  session->tls = coap_dtls_new_client_session(session);
557  if (session->tls) {
559  } else {
560  /* Need to free session object. As a new session may not yet
561  * have been referenced, we call coap_session_reference() first
562  * before trying to release the object.
563  */
564  coap_session_reference(session);
565  coap_session_release(session);
566  return NULL;
567  }
568  } else if (session->proto == COAP_PROTO_TCP || session->proto == COAP_PROTO_TLS) {
569  if (session->sock.flags & COAP_SOCKET_WANT_CONNECT) {
571  } else if (session->proto == COAP_PROTO_TLS) {
572  int connected = 0;
573  session->tls = coap_tls_new_client_session(session, &connected);
574  if (session->tls) {
576  if (connected)
577  coap_session_send_csm(session);
578  } else {
579  /* Need to free session object. As a new session may not yet
580  * have been referenced, we call coap_session_reference()
581  * first before trying to release the object.
582  */
583  coap_session_reference(session);
584  coap_session_release(session);
585  return NULL;
586  }
587  } else {
588  coap_session_send_csm(session);
589  }
590  }
591  coap_ticks(&session->last_rx_tx);
592  return session;
593 }
594 
595 static coap_session_t *
597  if (session->proto == COAP_PROTO_TCP || session->proto == COAP_PROTO_TLS)
599  if (session->proto == COAP_PROTO_TCP) {
600  coap_session_send_csm(session);
601  } else if (session->proto == COAP_PROTO_TLS) {
602  int connected = 0;
603  session->tls = coap_tls_new_server_session(session, &connected);
604  if (session->tls) {
606  if (connected) {
608  coap_session_send_csm(session);
609  }
610  } else {
611  /* Need to free session object. As a new session may not yet
612  * have been referenced, we call coap_session_reference() first
613  * before trying to release the object.
614  */
615  coap_session_reference(session);
616  coap_session_release(session);
617  session = NULL;
618  }
619  }
620  return session;
621 }
622 
624  struct coap_context_t *ctx,
625  const coap_address_t *local_if,
626  const coap_address_t *server,
627  coap_proto_t proto
628 ) {
629  coap_session_t *session = coap_session_create_client(ctx, local_if, server, proto);
630  if (session) {
631  debug("*** %s: new outgoing session\n", coap_session_str(session));
632  session = coap_session_connect(session);
633  }
634  return session;
635 }
636 
638  struct coap_context_t *ctx,
639  const coap_address_t *local_if,
640  const coap_address_t *server,
641  coap_proto_t proto,
642  const char *identity,
643  const uint8_t *key,
644  unsigned key_len
645 ) {
646  coap_session_t *session = coap_session_create_client(ctx, local_if, server, proto);
647 
648  if (!session)
649  return NULL;
650 
651  if (identity && (strlen(identity) > 0)) {
652  size_t identity_len = strlen(identity);
653  session->psk_identity = (uint8_t*)coap_malloc(identity_len);
654  if (session->psk_identity) {
655  memcpy(session->psk_identity, identity, identity_len);
656  session->psk_identity_len = identity_len;
657  } else {
658  coap_log(LOG_WARNING, "Cannot store session PSK identity\n");
659  coap_session_release(session);
660  return NULL;
661  }
662  }
663  else if (coap_dtls_is_supported()) {
664  coap_log(LOG_WARNING, "PSK identity not defined\n");
665  coap_session_release(session);
666  return NULL;
667  }
668 
669  if (key && key_len > 0) {
670  session->psk_key = (uint8_t*)coap_malloc(key_len);
671  if (session->psk_key) {
672  memcpy(session->psk_key, key, key_len);
673  session->psk_key_len = key_len;
674  } else {
675  coap_log(LOG_WARNING, "Cannot store session PSK key\n");
676  coap_session_release(session);
677  return NULL;
678  }
679  }
680  else if (coap_dtls_is_supported()) {
681  coap_log(LOG_WARNING, "PSK key not defined\n");
682  coap_session_release(session);
683  return NULL;
684  }
685 
686  if (coap_dtls_is_supported()) {
688  coap_session_release(session);
689  return NULL;
690  }
691  }
692  debug("*** %s: new outgoing session\n", coap_session_str(session));
693  return coap_session_connect(session);
694 }
695 
697  struct coap_context_t *ctx,
698  const coap_address_t *local_if,
699  const coap_address_t *server,
700  coap_proto_t proto,
701  coap_dtls_pki_t* setup_data
702 ) {
703  coap_session_t *session;
704 
705  if (coap_dtls_is_supported()) {
706  if (!setup_data) {
707  return NULL;
708  } else {
709  if (setup_data->version != COAP_DTLS_PKI_SETUP_VERSION) {
710  coap_log(LOG_ERR, "coap_new_client_session_pki: Wrong version of setup_data\n");
711  return NULL;
712  }
713  }
714 
715  }
716  session = coap_session_create_client(ctx, local_if, server, proto);
717 
718  if (!session) {
719  return NULL;
720  }
721 
722  if (coap_dtls_is_supported()) {
723  /* we know that setup_data is not NULL */
724  if (!coap_dtls_context_set_pki(ctx, setup_data, COAP_DTLS_ROLE_CLIENT)) {
725  coap_session_release(session);
726  return NULL;
727  }
728  }
729  coap_log(LOG_DEBUG, "*** %s: new outgoing session\n", coap_session_str(session));
730  return coap_session_connect(session);
731 }
732 
733 
735  struct coap_context_t *ctx,
736  coap_endpoint_t *ep
737 ) {
738  coap_session_t *session;
740  &ep->bind_addr, NULL, NULL, 0, ctx, ep );
741  if (!session)
742  goto error;
743 
744  if (!coap_socket_accept_tcp(&ep->sock, &session->sock,
745  &session->local_addr, &session->remote_addr))
746  goto error;
749  LL_PREPEND(ep->sessions, session);
750  if (session) {
751  debug("*** %s: new incoming session\n", coap_session_str(session));
752  session = coap_session_accept(session);
753  }
754  return session;
755 
756 error:
757  coap_session_free(session);
758  return NULL;
759 }
760 
761 #ifndef WITH_LWIP
763 coap_new_endpoint(coap_context_t *context, const coap_address_t *listen_addr, coap_proto_t proto) {
764  struct coap_endpoint_t *ep = NULL;
765 
766  assert(context);
767  assert(listen_addr);
768  assert(proto != COAP_PROTO_NONE);
769 
770  if (proto == COAP_PROTO_DTLS && !coap_dtls_is_supported()) {
771  coap_log(LOG_CRIT, "coap_new_endpoint: DTLS not supported\n");
772  goto error;
773  }
774 
775  if (proto == COAP_PROTO_TLS && !coap_tls_is_supported()) {
776  coap_log(LOG_CRIT, "coap_new_endpoint: TLS not supported\n");
777  goto error;
778  }
779 
780  if (proto == COAP_PROTO_DTLS || proto == COAP_PROTO_TLS) {
781  if (!coap_dtls_context_check_keys_enabled(context)) {
782  coap_log(LOG_INFO, "coap_new_endpoint: one of coap_context_set_psk() or coap_context_set_pki() not called\n");
783  goto error;
784  }
785  }
786 
787  ep = coap_malloc_endpoint();
788  if (!ep) {
789  coap_log(LOG_WARNING, "coap_new_endpoint: malloc");
790  goto error;
791  }
792 
793  memset(ep, 0, sizeof(struct coap_endpoint_t));
794  ep->context = context;
795  ep->proto = proto;
796 
797  if (proto==COAP_PROTO_TCP || proto==COAP_PROTO_TLS) {
798  if (!coap_socket_bind_tcp(&ep->sock, listen_addr, &ep->bind_addr))
799  goto error;
801  } else if (proto==COAP_PROTO_UDP || proto==COAP_PROTO_DTLS) {
802  if (!coap_socket_bind_udp(&ep->sock, listen_addr, &ep->bind_addr))
803  goto error;
805  } else {
806  coap_log(LOG_CRIT, "coap_new_endpoint: protocol not supported\n");
807  goto error;
808  }
809 
810 #ifndef NDEBUG
811  if (LOG_DEBUG <= coap_get_log_level()) {
812 #ifndef INET6_ADDRSTRLEN
813 #define INET6_ADDRSTRLEN 40
814 #endif
815  unsigned char addr_str[INET6_ADDRSTRLEN + 8];
816 
817  if (coap_print_addr(&ep->bind_addr, addr_str, INET6_ADDRSTRLEN + 8)) {
818  debug("created %s endpoint %s\n",
819  ep->proto == COAP_PROTO_TLS ? "TLS"
820  : ep->proto == COAP_PROTO_TCP ? "TCP"
821  : ep->proto == COAP_PROTO_DTLS ? "DTLS " : "UDP",
822  addr_str);
823  }
824  }
825 #endif /* NDEBUG */
826 
828 
829  if (proto == COAP_PROTO_DTLS) {
830  ep->hello.proto = proto;
832  ep->hello.mtu = ep->default_mtu;
833  ep->hello.context = context;
834  ep->hello.endpoint = ep;
835  }
836 
838 
839  LL_PREPEND(context->endpoint, ep);
840  return ep;
841 
842 error:
843  coap_free_endpoint(ep);
844  return NULL;
845 }
846 
848  ep->default_mtu = (uint16_t)mtu;
849 }
850 
851 void
853  if (ep) {
854  coap_session_t *session, *tmp;
855 
856  if (ep->sock.flags != COAP_SOCKET_EMPTY)
857  coap_socket_close(&ep->sock);
858 
859  LL_FOREACH_SAFE(ep->sessions, session, tmp) {
860  assert(session->ref == 0);
861  if (session->ref == 0) {
862  session->endpoint = NULL;
863  session->context = NULL;
864  coap_session_free(session);
865  }
866  }
867 
869  }
870 }
871 #endif /* WITH_LWIP */
872 
875  const coap_address_t *remote_addr,
876  int ifindex) {
877  coap_session_t *s;
878  coap_endpoint_t *ep;
879  LL_FOREACH(ctx->sessions, s) {
880  if (s->ifindex == ifindex && coap_address_equals(&s->remote_addr, remote_addr))
881  return s;
882  }
883  LL_FOREACH(ctx->endpoint, ep) {
884  if (ep->hello.ifindex == ifindex && coap_address_equals(&ep->hello.remote_addr, remote_addr))
885  return &ep->hello;
886  LL_FOREACH(ep->sessions, s) {
887  if (s->ifindex == ifindex && coap_address_equals(&s->remote_addr, remote_addr))
888  return s;
889  }
890  }
891  return NULL;
892 }
893 
894 const char *coap_session_str(const coap_session_t *session) {
895  static char szSession[256];
896  char *p = szSession, *end = szSession + sizeof(szSession);
897  if (coap_print_addr(&session->local_addr, (unsigned char*)p, end - p) > 0)
898  p += strlen(p);
899  if (p + 6 < end) {
900  strcpy(p, " <-> ");
901  p += 5;
902  }
903  if (p + 1 < end) {
904  if (coap_print_addr(&session->remote_addr, (unsigned char*)p, end - p) > 0)
905  p += strlen(p);
906  }
907  if (session->ifindex > 0 && p + 1 < end)
908  p += snprintf(p, end - p, " (if%d)", session->ifindex);
909  if (p + 6 < end) {
910  if (session->proto == COAP_PROTO_UDP) {
911  strcpy(p, " UDP");
912  p += 4;
913  } else if (session->proto == COAP_PROTO_DTLS) {
914  strcpy(p, " DTLS");
915  p += 5;
916  } else if (session->proto == COAP_PROTO_TCP) {
917  strcpy(p, " TCP");
918  p += 4;
919  } else if (session->proto == COAP_PROTO_TLS) {
920  strcpy(p, " TLS");
921  p += 4;
922  } else {
923  strcpy(p, " NONE");
924  p += 5;
925  }
926  }
927 
928  return szSession;
929 }
930 
931 const char *coap_endpoint_str(const coap_endpoint_t *endpoint) {
932  static char szEndpoint[128];
933  char *p = szEndpoint, *end = szEndpoint + sizeof(szEndpoint);
934  if (coap_print_addr(&endpoint->bind_addr, (unsigned char*)p, end - p) > 0)
935  p += strlen(p);
936  if (p + 6 < end) {
937  if (endpoint->proto == COAP_PROTO_UDP) {
938  strcpy(p, " UDP");
939  p += 4;
940  } else if (endpoint->proto == COAP_PROTO_DTLS) {
941  strcpy(p, " DTLS");
942  p += 5;
943  } else {
944  strcpy(p, " NONE");
945  p += 5;
946  }
947  }
948 
949  return szEndpoint;
950 }
951 
952 #endif /* _COAP_SESSION_H_ */
uint8_t type
message type
Definition: pdu.h:288
unsigned mtu
path or CSM mtu
Definition: coap_session.h:61
void coap_session_send_csm(coap_session_t *session)
Notify session transport has just connected and CSM exchange can now start.
Definition: coap_session.c:282
#define LL_FOREACH(head, el)
Definition: utlist.h:413
coap_queue_t * sendqueue
Definition: net.h:165
#define COAP_SOCKET_EMPTY
coap_socket_flags_t values
Definition: coap_io.h:54
uint8_t * psk_identity
Definition: coap_session.h:82
#define COAP_DEFAULT_MTU
Definition: pdu.h:32
coap_session_t * coap_new_client_session(struct coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto)
Creates a new client session to the designated server.
Definition: coap_session.c:623
coap_tick_t last_rx_tx
Definition: coap_session.h:77
uint8_t con_active
Active CON request sent.
Definition: coap_session.h:71
void * app
application-specific data
Definition: coap_session.h:86
void coap_session_set_ack_timeout(coap_session_t *session, coap_fixed_point_t value)
Set the CoAP initial ack response timeout before the next re-transmit.
Definition: coap_session.c:35
#define COAP_SIGNALING_PING
Definition: pdu.h:181
uint8_t coap_proto_t
Definition: pdu.h:339
Abstraction of a fixed point number that can be used where necessary instead of a float...
Definition: coap_session.h:25
#define COAP_DTLS_ROLE_CLIENT
Internal function invoked for client.
Definition: coap_dtls.h:263
#define COAP_SESSION_TYPE_CLIENT
coap_session_type_t values
Definition: coap_session.h:40
coap_tid_t coap_wait_ack(coap_context_t *context, coap_session_t *session, coap_queue_t *node)
Definition: net.c:817
#define COAP_SIGNALING_CSM
Definition: pdu.h:180
void coap_socket_close(coap_socket_t *sock)
Definition: coap_io.c:577
#define COAP_DTLS_PKI_SETUP_VERSION
Latest PKI setup version.
Definition: coap_dtls.h:185
void coap_tls_free_session(coap_session_t *coap_session UNUSED)
Definition: coap_notls.c:159
unsigned int coap_session_get_max_transmit(coap_session_t *session)
Get the CoAP maximum retransmit before failure.
Definition: coap_session.c:56
coap_fixed_point_t coap_session_get_ack_timeout(coap_session_t *session)
Get the CoAP initial ack response timeout before the next re-transmit.
Definition: coap_session.c:61
struct coap_context_t * context
session&#39;s context
Definition: coap_session.h:68
coap_session_t * coap_new_server_session(struct coap_context_t *ctx, coap_endpoint_t *ep)
Creates a new server session for the specified endpoint.
Definition: coap_session.c:734
coap_fixed_point_t ack_timeout
timeout waiting for ack (default 2 secs)
Definition: coap_session.h:88
void * tls
security parameters
Definition: coap_session.h:69
coap_session_t * sessions
list of active sessions
Definition: coap_session.h:306
void * coap_session_get_app_data(const coap_session_t *session)
Returns any application-specific data that has been stored with session using the function coap_sessi...
Definition: coap_session.c:94
coap_endpoint_t * endpoint
the endpoints used for listening
Definition: net.h:166
#define COAP_SESSION_STATE_HANDSHAKE
Definition: coap_session.h:50
#define COAP_SOCKET_CONNECTED
the socket is connected
Definition: coap_io.h:57
#define COAP_SOCKET_BOUND
the socket is bound
Definition: coap_io.h:56
multi-purpose address abstraction
Definition: address.h:62
uint16_t tx_mid
the last message id that was used in this session
Definition: coap_session.h:70
int coap_dtls_context_check_keys_enabled(coap_context_t *ctx UNUSED)
Definition: coap_notls.c:65
ssize_t coap_socket_send(coap_socket_t *sock, coap_session_t *session, const uint8_t *data, size_t data_len)
Definition: coap_io.c:1320
unsigned ref
reference count from queues
Definition: coap_session.h:59
int coap_tid_t
coap_tid_t is used to store CoAP transaction id, i.e.
Definition: pdu.h:238
#define LL_PREPEND(head, add)
Definition: utlist.h:314
void coap_session_set_mtu(coap_session_t *session, unsigned mtu)
Set the session MTU.
Definition: coap_session.c:203
coap_tid_t coap_session_send_ping(coap_session_t *session)
Send a ping message for the session.
Definition: coap_session.c:308
unsigned tls_overhead
overhead of TLS layer
Definition: coap_session.h:60
uint8_t version
Definition: coap_dtls.h:191
#define COAP_MAX_MESSAGE_SIZE_TCP8
Definition: pdu.h:42
unsigned int coap_encode_var_safe(uint8_t *buf, size_t length, unsigned int val)
Encodes multiple-length byte sequences.
Definition: encode.c:45
int ifindex
the interface index
Definition: coap_io.h:199
#define COAP_PROTO_DTLS
Definition: pdu.h:345
int coap_socket_accept_tcp(coap_socket_t *server, coap_socket_t *new_client, coap_address_t *local_addr, coap_address_t *remote_addr)
Definition: coap_io.c:454
void * coap_dtls_new_client_session(coap_session_t *session UNUSED)
Definition: coap_notls.c:98
coap_endpoint_t * coap_new_endpoint(coap_context_t *context, const coap_address_t *listen_addr, coap_proto_t proto)
Create a new endpoint for communicating with peers.
Definition: coap_session.c:763
size_t coap_print_addr(const struct coap_address_t *addr, unsigned char *buf, size_t len)
Print the address into the defined buffer.
Definition: debug.c:171
coap_tid_t coap_send(coap_session_t *session, coap_pdu_t *pdu)
Sends a CoAP message to given peer.
Definition: net.c:869
COAP_STATIC_INLINE void coap_address_init(coap_address_t *addr)
Resets the given coap_address_t object addr to its default values.
Definition: address.h:104
uint16_t default_mtu
default mtu for this interface
Definition: coap_session.h:303
void coap_delete_observers(coap_context_t *context, coap_session_t *session)
Removes any subscription for session and releases the allocated storage.
Definition: resource.c:731
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)
Definition: coap_io.c:253
int coap_dtls_is_supported(void)
Check whether DTLS is available.
Definition: coap_notls.c:23
void * coap_tls_new_server_session(coap_session_t *session UNUSED, int *connected UNUSED)
Definition: coap_notls.c:155
coap_session_t * coap_new_client_session_pki(struct coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, coap_dtls_pki_t *setup_data)
Creates a new client session to the designated server with PKI credentials.
Definition: coap_session.c:696
coap_address_t local_if
optional local interface address
Definition: coap_session.h:62
#define COAP_EVENT_TCP_CONNECTED
TCP events for COAP_PROTO_TCP and COAP_PROTO_TLS.
Definition: coap_event.h:41
ssize_t coap_session_send(coap_session_t *session, const uint8_t *data, size_t datalen)
Function interface for datagram data transmission.
Definition: coap_session.c:215
int dtls_event
Tracking any (D)TLS events on this sesison.
Definition: coap_session.h:91
coap_session_t * coap_session_get_by_peer(coap_context_t *ctx, const coap_address_t *remote_addr, int ifindex)
Definition: coap_session.c:874
#define COAP_PDU_DELAYED
Definition: pdu.h:249
void coap_session_set_ack_random_factor(coap_session_t *session, coap_fixed_point_t value)
Set the CoAP ack randomize factor.
Definition: coap_session.c:45
Debug.
Definition: debug.h:49
void coap_endpoint_set_default_mtu(coap_endpoint_t *ep, unsigned mtu)
Set the endpoint&#39;s default MTU.
Definition: coap_session.c:847
coap_nack_handler_t nack_handler
Definition: net.h:189
#define COAP_SOCKET_WANT_ACCEPT
non blocking server socket is waiting for accept
Definition: coap_io.h:60
#define COAP_MAX_MESSAGE_SIZE_TCP16
Definition: pdu.h:43
#define COAP_EVENT_TCP_FAILED
Definition: coap_event.h:43
coap_nack_reason_t
Definition: coap_io.h:206
#define COAP_EVENT_SESSION_FAILED
Definition: coap_event.h:50
struct coap_context_t * context
endpoint&#39;s context
Definition: coap_session.h:301
coap_session_t * coap_session_reference(coap_session_t *session)
Increment reference counter on a session.
Definition: coap_session.c:71
const char * coap_endpoint_str(const coap_endpoint_t *endpoint)
Get endpoint description.
Definition: coap_session.c:931
void * coap_tls_new_client_session(coap_session_t *session UNUSED, int *connected UNUSED)
Definition: coap_notls.c:151
Abstraction of virtual endpoint that can be attached to coap_context_t.
Definition: coap_session.h:299
const char * coap_session_str(const coap_session_t *session)
Get session description.
Definition: coap_session.c:894
coap_address_t local_addr
local address and port
Definition: coap_session.h:64
#define COAP_SESSION_STATE_ESTABLISHED
Definition: coap_session.h:52
coap_tid_t id
CoAP transaction id.
Definition: net.h:46
unsigned int max_retransmit
maximum re-transmit count (default 4)
Definition: coap_session.h:87
#define COAP_DEFAULT_ACK_RANDOM_FACTOR
A factor that is used to randomize the wait time before a message is retransmitted to prevent synchro...
Definition: coap_session.h:392
uint16_t fractional_part
Fractional part of fixed point variable 1/1000 (3 points) precision.
Definition: coap_session.h:27
#define COAP_EVENT_SESSION_CONNECTED
CSM exchange events for reliable protocols only.
Definition: coap_event.h:48
#define COAP_PROTO_UDP
Definition: pdu.h:344
COAP_STATIC_INLINE void * coap_malloc(size_t size)
Wrapper function to coap_malloc_type() for backwards compatibility.
Definition: mem.h:75
struct coap_endpoint_t * coap_malloc_endpoint(void)
Definition: coap_io.c:180
int coap_tls_is_supported(void)
Check whether TLS is available.
Definition: coap_notls.c:28
coap_pdu_t * pdu
the CoAP PDU to send
Definition: net.h:47
coap_tick_t t
when to send PDU for the next time
Definition: net.h:41
size_t coap_pdu_encode_header(coap_pdu_t *pdu, coap_proto_t proto)
Compose the protocol specific header for the specified PDU.
Definition: pdu.c:579
int coap_dtls_context_set_pki(coap_context_t *ctx UNUSED, coap_dtls_pki_t *setup_data UNUSED, int server UNUSED)
Definition: coap_notls.c:41
#define COAP_INVALID_TID
Indicates an invalid transaction id.
Definition: pdu.h:241
coap_session_t * coap_endpoint_get_session(coap_endpoint_t *endpoint, const coap_packet_t *packet, coap_tick_t now)
Definition: coap_session.c:438
coap_address_t remote_addr
remote address and port
Definition: coap_session.h:63
void coap_session_set_max_retransmit(coap_session_t *session, unsigned int value)
Set the CoAP maximum retransmit count before failure.
Definition: coap_session.c:26
coap_address_t src
the packet&#39;s source address
Definition: coap_io.h:197
void coap_session_set_app_data(coap_session_t *session, void *app_data)
Stores data with the given session.
Definition: coap_session.c:88
unsigned int coap_calc_timeout(coap_session_t *session, unsigned char r)
Calculates the initial timeout based on the session CoAP transmission parameters &#39;ack_timeout&#39;, &#39;ack_random_factor&#39;, and COAP_TICKS_PER_SECOND.
Definition: net.c:791
structure for CoAP PDUs token, if any, follows the fixed size header, then options until payload mark...
Definition: pdu.h:287
coap_session_t * coap_endpoint_new_dtls_session(coap_endpoint_t *endpoint, const coap_packet_t *packet, coap_tick_t now)
Definition: coap_session.c:486
#define COAP_SIGNALING_OPTION_MAX_MESSAGE_SIZE
Definition: pdu.h:187
struct coap_queue_t * delayqueue
list of delayed messages waiting to be sent
Definition: coap_session.h:72
coap_proto_t proto
protocol used
Definition: coap_session.h:56
Warning.
Definition: debug.h:46
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
Definition: coap_time.h:85
static coap_session_t * coap_session_accept(coap_session_t *session)
Definition: coap_session.c:596
#define assert(...)
Definition: mem.c:18
void coap_free_endpoint(coap_endpoint_t *ep)
Definition: coap_session.c:852
#define COAP_SOCKET_NOT_EMPTY
the socket is not empty
Definition: coap_io.h:55
coap_session_t hello
special session of DTLS hello messages
Definition: coap_session.h:307
int coap_dtls_context_set_psk(coap_context_t *ctx UNUSED, const char *hint UNUSED, int server UNUSED)
Definition: coap_notls.c:57
unsigned int coap_dtls_get_overhead(coap_session_t *session UNUSED)
Definition: coap_notls.c:147
size_t partial_read
if > 0 indicates number of bytes already read for an incoming message
Definition: coap_session.h:75
coap_pdu_t * partial_pdu
incomplete incoming pdu
Definition: coap_session.h:76
ssize_t coap_session_delay_pdu(coap_session_t *session, coap_pdu_t *pdu, coap_queue_t *node)
Definition: coap_session.c:246
size_t used_size
used bytes of storage for token, options and payload
Definition: pdu.h:296
void coap_session_free(coap_session_t *session)
Definition: coap_session.c:147
struct coap_queue_t * next
Definition: net.h:40
coap_socket_t sock
socket object for the session, if any
Definition: coap_session.h:66
ssize_t coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len)
Definition: coap_io.c:586
void coap_ticks(coap_tick_t *t)
Sets t to the internal time with COAP_TICKS_PER_SECOND resolution.
#define COAPS_DEFAULT_PORT
Definition: pdu.h:29
#define INET6_ADDRSTRLEN
coap_proto_t proto
protocol used on this interface
Definition: coap_session.h:302
#define COAP_MESSAGE_CON
Definition: pdu.h:72
unsigned int timeout
the randomized timeout value
Definition: net.h:44
#define COAP_PROTO_TLS
Definition: pdu.h:347
#define LL_APPEND(head, add)
Definition: utlist.h:338
static coap_session_t * coap_session_connect(coap_session_t *session)
Definition: coap_session.c:552
Generic resource handling.
COAP_STATIC_INLINE void coap_free(void *object)
Wrapper function to coap_free_type() for backwards compatibility.
Definition: mem.h:82
Error.
Definition: debug.h:45
coap_session_type_t type
client or server side socket
Definition: coap_session.h:57
#define COAP_DEFAULT_NSTART
The number of simultaneous outstanding interactions that a client maintains to a given server...
Definition: coap_session.h:405
#define COAP_EVENT_TCP_CLOSED
Definition: coap_event.h:42
coap_session_state_t state
current state of relationaship with peer
Definition: coap_session.h:58
size_t psk_identity_len
Definition: coap_session.h:83
#define COAP_SESSION_TYPE_SERVER
server-side
Definition: coap_session.h:41
size_t coap_add_option(coap_pdu_t *pdu, uint16_t type, size_t len, const uint8_t *data)
de-duplicate code with coap_add_option_later
Definition: pdu.c:229
void coap_session_release(coap_session_t *session)
Decrement reference counter on a session.
Definition: coap_session.c:77
#define COAP_SESSION_TYPE_HELLO
server-side ephemeral session for responding to a client hello
Definition: coap_session.h:42
coap_fixed_point_t ack_random_factor
ack random factor backoff (default 1.5)
Definition: coap_session.h:89
int coap_remove_from_queue(coap_queue_t **queue, coap_session_t *session, coap_tid_t id, coap_queue_t **node)
This function removes the element with given id from the list given list.
Definition: net.c:1376
int ifindex
interface index
Definition: coap_session.h:65
#define COAP_DEFAULT_PORT
Definition: pdu.h:28
void coap_dtls_free_session(coap_session_t *coap_session UNUSED)
Definition: coap_notls.c:102
size_t partial_write
if > 0 indicates number of bytes already written from the pdu at the head of sendqueue ...
Definition: coap_session.h:73
#define COAP_EVENT_DTLS_CONNECTED
Definition: coap_event.h:34
int coap_address_equals(const coap_address_t *a, const coap_address_t *b)
Compares given address objects a and b.
Definition: address.c:31
int coap_handle_event(coap_context_t *context, coap_event_t event, coap_session_t *session)
Invokes the event handler of context for the given event and data.
Definition: net.c:2268
void coap_delete_pdu(coap_pdu_t *pdu)
Dispose of an CoAP PDU and frees associated storage.
Definition: pdu.c:141
ssize_t coap_session_write(coap_session_t *session, const uint8_t *data, size_t datalen)
Function interface for stream data transmission.
Definition: coap_session.c:234
coap_address_t dst
the packet&#39;s destination address
Definition: coap_io.h:198
COAP_STATIC_INLINE void coap_address_copy(coap_address_t *dst, const coap_address_t *src)
Definition: address.h:116
void * coap_dtls_new_server_session(coap_session_t *session UNUSED)
Definition: coap_notls.c:94
void coap_session_connected(coap_session_t *session)
Notify session that it has just connected or reconnected.
Definition: coap_session.c:318
#define COAP_DEFAULT_ACK_TIMEOUT
Number of seconds when to expect an ACK or a response to an outstanding CON message.
Definition: coap_session.h:385
#define COAP_SOCKET_WANT_READ
non blocking socket is waiting for reading
Definition: coap_io.h:58
#define LL_FOREACH_SAFE(head, el, tmp)
Definition: utlist.h:419
#define COAP_PROTO_RELIABLE(p)
Definition: coap_session.h:34
#define COAP_SESSION_STATE_CONNECTING
Definition: coap_session.h:49
#define COAP_MAX_MESSAGE_SIZE_TCP0
Definition: pdu.h:41
The structure used for defining the PKI setup data to be used.
Definition: coap_dtls.h:190
#define debug(...)
Obsoleted.
Definition: debug.h:143
static coap_session_t * coap_session_create_client(coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto)
Definition: coap_session.c:508
uint8_t coap_session_type_t
Definition: coap_session.h:36
#define COAP_SOCKET_WANT_CONNECT
non blocking client socket is waiting for connect
Definition: coap_io.h:61
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.
#define LL_DELETE(head, del)
Definition: utlist.h:385
#define COAP_PROTO_NOT_RELIABLE(p)
Definition: coap_session.h:33
coap_log_t coap_get_log_level(void)
Get the current logging level.
Definition: debug.c:71
#define COAP_DEFAULT_MAX_PDU_RX_SIZE
Definition: pdu.h:51
uint8_t hdr_size
actaul size used for protocol-specific header
Definition: pdu.h:291
size_t psk_key_len
Definition: coap_session.h:85
coap_socket_flags_t flags
Definition: coap_io.h:48
void coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
Definition: coap_session.c:374
coap_session_t * sessions
client sessions
Definition: net.h:167
#define coap_log(level,...)
Logging function.
Definition: debug.h:122
static coap_session_t * coap_make_session(coap_proto_t proto, coap_session_type_t type, const coap_address_t *local_if, const coap_address_t *local_addr, const coap_address_t *remote_addr, int ifindex, coap_context_t *context, coap_endpoint_t *endpoint)
Definition: coap_session.c:100
size_t coap_session_max_pdu_size(coap_session_t *session)
Get maximum acceptable PDU size.
Definition: coap_session.c:186
coap_socket_t sock
socket object for the interface, if any
Definition: coap_session.h:304
ssize_t coap_session_send_pdu(coap_session_t *session, coap_pdu_t *pdu)
Send a pdu according to the session&#39;s protocol.
Definition: net.c:620
coap_pdu_t * coap_pdu_init(uint8_t type, uint8_t code, uint16_t tid, size_t size)
Creates a new CoAP PDU with at least enough storage space for the given size maximum message size...
Definition: pdu.c:91
int coap_socket_connect_udp(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)
Definition: coap_io.c:490
coap_session_t * session
the CoAP session
Definition: net.h:45
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
#define COAP_PROTO_NONE
coap_proto_t values
Definition: pdu.h:343
#define COAP_EVENT_SESSION_CLOSED
Definition: coap_event.h:49
coap_session_t * coap_new_client_session_psk(struct coap_context_t *ctx, const coap_address_t *local_if, const coap_address_t *server, coap_proto_t proto, const char *identity, const uint8_t *key, unsigned key_len)
Creates a new client session to the designated server with PSK credentials.
Definition: coap_session.c:637
unsigned char uint8_t
Definition: uthash.h:79
struct coap_endpoint_t * endpoint
session&#39;s endpoint
Definition: coap_session.h:67
#define prng(Buf, Length)
Fills Buf with Length bytes of random data.
Definition: prng.h:112
coap_fixed_point_t coap_session_get_ack_random_factor(coap_session_t *session)
Get the CoAP ack randomize factor.
Definition: coap_session.c:66
Critical.
Definition: debug.h:44
int coap_socket_bind_udp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
Definition: coap_io.c:190
#define COAP_SESSION_STATE_NONE
coap_session_state_t values
Definition: coap_session.h:48
Information.
Definition: debug.h:48
int coap_socket_bind_tcp(coap_socket_t *sock, const coap_address_t *listen_addr, coap_address_t *bound_addr)
Definition: coap_io.c:383
uint16_t integer_part
Integer part of fixed point variable.
Definition: coap_session.h:26
void coap_mfree_endpoint(struct coap_endpoint_t *ep)
Definition: coap_io.c:185
Queue entry.
Definition: net.h:39
uint8_t coap_session_state_t
Definition: coap_session.h:44
coap_queue_t * coap_new_node(void)
Creates a new node suitable for adding to the CoAP sendqueue.
Definition: net.c:247
coap_address_t bind_addr
local interface address
Definition: coap_session.h:305
#define COAP_PROTO_TCP
Definition: pdu.h:346
uint8_t * psk_key
Definition: coap_session.h:84
The CoAP stack&#39;s global state is stored in a coap_context_t object.
Definition: net.h:148
uint16_t tid
transaction id, if any, in regular host byte order
Definition: pdu.h:293
unsigned int max_idle_sessions
Maximum number of simultaneous unused sessions per endpoint.
Definition: net.h:214
#define COAP_DEFAULT_MAX_RETRANSMIT
Number of message retransmissions before message sending is stopped RFC 7252, Section 4...
Definition: coap_session.h:398
int coap_delete_node(coap_queue_t *node)
Destroys specified node.
Definition: net.c:225
#define COAP_SESSION_STATE_CSM
Definition: coap_session.h:51