libcoap  4.2.0rc2
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  coap_log(LOG_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  coap_log(LOG_DEBUG, "* %s: sent %zd bytes\n",
228  coap_session_str(session), datalen);
229  } else {
230  coap_log(LOG_DEBUG, "* %s: failed to send %zd bytes\n",
231  coap_session_str(session), datalen);
232  }
233  return bytes_written;
234 }
235 
236 ssize_t coap_session_write(coap_session_t *session, const uint8_t *data, size_t datalen) {
237  ssize_t bytes_written = coap_socket_write(&session->sock, data, datalen);
238  if (bytes_written > 0) {
239  coap_ticks(&session->last_rx_tx);
240  coap_log(LOG_DEBUG, "* %s: sent %zd bytes\n",
241  coap_session_str(session), datalen);
242  } else if (bytes_written < 0) {
243  coap_log(LOG_DEBUG, "* %s: failed to send %zd bytes\n",
244  coap_session_str(session), datalen );
245  }
246  return bytes_written;
247 }
248 
249 ssize_t
251  coap_queue_t *node)
252 {
253  if ( node ) {
254  coap_queue_t *removed = NULL;
255  coap_remove_from_queue(&session->context->sendqueue, session, node->id, &removed);
256  assert(removed == node);
258  node->session = NULL;
259  node->t = 0;
260  } else {
261  coap_queue_t *q = NULL;
262  /* Check that the same tid is not getting re-used in violation of RFC7252 */
263  LL_FOREACH(session->delayqueue, q) {
264  if (q->id == pdu->tid) {
265  coap_log(LOG_ERR, "** %s: tid=%d: already in-use - dropped\n", coap_session_str(session), pdu->tid);
266  return COAP_INVALID_TID;
267  }
268  }
269  node = coap_new_node();
270  if (node == NULL)
271  return COAP_INVALID_TID;
272  node->id = pdu->tid;
273  node->pdu = pdu;
274  if (pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
275  uint8_t r;
276  prng(&r, sizeof(r));
277  /* add timeout in range [ACK_TIMEOUT...ACK_TIMEOUT * ACK_RANDOM_FACTOR] */
278  node->timeout = coap_calc_timeout(session, r);
279  }
280  }
281  LL_APPEND(session->delayqueue, node);
282  coap_log(LOG_DEBUG, "** %s: tid=%d: delayed\n",
283  coap_session_str(session), node->id);
284  return COAP_PDU_DELAYED;
285 }
286 
288  coap_pdu_t *pdu;
289  uint8_t buf[4];
290  assert(COAP_PROTO_RELIABLE(session->proto));
291  coap_log(LOG_DEBUG, "***%s: sending CSM\n", coap_session_str(session));
292  session->state = COAP_SESSION_STATE_CSM;
293  session->partial_write = 0;
294  if (session->mtu == 0)
295  session->mtu = COAP_DEFAULT_MTU; /* base value */
297  if ( pdu == NULL
299  coap_encode_var_safe(buf, sizeof(buf),
300  COAP_DEFAULT_MAX_PDU_RX_SIZE), buf) == 0
301  || coap_pdu_encode_header(pdu, session->proto) == 0
302  ) {
304  } else {
305  ssize_t bytes_written = coap_session_send_pdu(session, pdu);
306  if (bytes_written != (ssize_t)pdu->used_size + pdu->hdr_size)
308  }
309  if (pdu)
310  coap_delete_pdu(pdu);
311 }
312 
314  coap_pdu_t *ping;
315  if (session->state != COAP_SESSION_STATE_ESTABLISHED)
316  return 0;
318  if (!ping)
319  return COAP_INVALID_TID;
320  return coap_send(session, ping);
321 }
322 
324  if (session->state != COAP_SESSION_STATE_ESTABLISHED) {
325  coap_log(LOG_DEBUG, "***%s: session connected\n",
326  coap_session_str(session));
327  if (session->state == COAP_SESSION_STATE_CSM)
329  }
330 
332  session->partial_write = 0;
333 
334  if ( session->proto==COAP_PROTO_DTLS) {
335  session->tls_overhead = coap_dtls_get_overhead(session);
336  if (session->tls_overhead >= session->mtu) {
337  session->tls_overhead = session->mtu;
338  coap_log(LOG_ERR, "DTLS overhead exceeds MTU\n");
339  }
340  }
341 
342  while (session->delayqueue && session->state == COAP_SESSION_STATE_ESTABLISHED) {
343  ssize_t bytes_written;
344  coap_queue_t *q = session->delayqueue;
345  if (q->pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
346  if (session->con_active >= COAP_DEFAULT_NSTART)
347  break;
348  session->con_active++;
349  }
350  /* Take entry off the queue */
351  session->delayqueue = q->next;
352  q->next = NULL;
353 
354  coap_log(LOG_DEBUG, "** %s: tid=%d: transmitted after delay\n",
355  coap_session_str(session), (int)q->pdu->tid);
356  bytes_written = coap_session_send_pdu(session, q->pdu);
357  if (q->pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
358  if (coap_wait_ack(session->context, session, q) >= 0)
359  q = NULL;
360  }
361  if (COAP_PROTO_NOT_RELIABLE(session->proto)) {
362  if (q)
363  coap_delete_node(q);
364  if (bytes_written < 0)
365  break;
366  } else {
367  if (bytes_written <= 0 || (size_t)bytes_written < q->pdu->used_size + q->pdu->hdr_size) {
368  q->next = session->delayqueue;
369  session->delayqueue = q;
370  if (bytes_written > 0)
371  session->partial_write = (size_t)bytes_written;
372  break;
373  } else {
374  coap_delete_node(q);
375  }
376  }
377  }
378 }
379 
381  (void)reason;
382  coap_session_state_t state = session->state;
383 
384  coap_log(LOG_DEBUG, "***%s: session disconnected (reason %d)\n",
385  coap_session_str(session), reason);
386 #ifndef WITHOUT_OBSERVE
387  coap_delete_observers( session->context, session );
388 #endif
389 
390  if ( session->tls) {
391  if (session->proto == COAP_PROTO_DTLS)
392  coap_dtls_free_session(session);
393  else if (session->proto == COAP_PROTO_TLS)
394  coap_tls_free_session(session);
395  session->tls = NULL;
396  }
397 
398  session->state = COAP_SESSION_STATE_NONE;
399 
400  if (session->partial_pdu) {
401  coap_delete_pdu(session->partial_pdu);
402  session->partial_pdu = NULL;
403  }
404  session->partial_read = 0;
405 
406  while (session->delayqueue) {
407  coap_queue_t *q = session->delayqueue;
408  session->delayqueue = q->next;
409  q->next = NULL;
410  coap_log(LOG_DEBUG, "** %s: tid=%d: not transmitted after delay\n",
411  coap_session_str(session), q->id);
412  if (q->pdu->type==COAP_MESSAGE_CON
413  && COAP_PROTO_NOT_RELIABLE(session->proto)
414  && reason != COAP_NACK_RST)
415  {
416  if (coap_wait_ack(session->context, session, q) >= 0)
417  q = NULL;
418  }
419  if (q && q->pdu->type == COAP_MESSAGE_CON
420  && session->context->nack_handler)
421  {
422  session->context->nack_handler(session->context, session, q->pdu,
423  reason, q->id);
424  }
425  if (q)
426  coap_delete_node(q);
427  }
428  if ( COAP_PROTO_RELIABLE(session->proto) ) {
429  if (session->sock.flags != COAP_SOCKET_EMPTY) {
430  coap_socket_close(&session->sock);
431  coap_handle_event(session->context,
434  }
435  if (state != COAP_SESSION_STATE_NONE) {
436  coap_handle_event(session->context,
439  }
440  }
441 }
442 
445  const coap_packet_t *packet, coap_tick_t now) {
446  coap_session_t *session = NULL;
447  unsigned int num_idle = 0;
448  coap_session_t *oldest = NULL;
449 
450  endpoint->hello.ifindex = -1;
451 
452  LL_FOREACH(endpoint->sessions, session) {
453  if (session->ifindex == packet->ifindex &&
454  coap_address_equals(&session->local_addr, &packet->dst) &&
455  coap_address_equals(&session->remote_addr, &packet->src))
456  {
457  session->last_rx_tx = now;
458  return session;
459  }
460  if (session->ref == 0 && session->delayqueue == NULL && session->type == COAP_SESSION_TYPE_SERVER) {
461  ++num_idle;
462  if (oldest==NULL || session->last_rx_tx < oldest->last_rx_tx)
463  oldest = session;
464  }
465  }
466 
467  if (endpoint->context->max_idle_sessions > 0 && num_idle >= endpoint->context->max_idle_sessions)
468  coap_session_free(oldest);
469 
470  if (endpoint->proto == COAP_PROTO_DTLS) {
471  session = &endpoint->hello;
472  coap_address_copy(&session->local_addr, &packet->dst);
473  coap_address_copy(&session->remote_addr, &packet->src);
474  session->ifindex = packet->ifindex;
475  } else {
476  session = coap_make_session(endpoint->proto, COAP_SESSION_TYPE_SERVER,
477  NULL, &packet->dst, &packet->src, packet->ifindex, endpoint->context,
478  endpoint);
479  if (session) {
480  session->last_rx_tx = now;
481  if (endpoint->proto == COAP_PROTO_UDP)
483  LL_PREPEND(endpoint->sessions, session);
484  coap_log(LOG_DEBUG, "***%s: new incoming session\n",
485  coap_session_str(session));
486  }
487  }
488 
489  return session;
490 }
491 
494  const coap_packet_t *packet, coap_tick_t now) {
496  COAP_SESSION_TYPE_SERVER, NULL, &packet->dst, &packet->src,
497  packet->ifindex, endpoint->context, endpoint);
498  if (session) {
499  session->last_rx_tx = now;
501  session->tls = coap_dtls_new_server_session(session);
502  if (session->tls) {
504  LL_PREPEND(endpoint->sessions, session);
505  coap_log(LOG_DEBUG, "***%s: new incoming session\n",
506  coap_session_str(session));
507  } else {
508  coap_session_free(session);
509  session = NULL;
510  }
511  }
512  return session;
513 }
514 
515 static coap_session_t *
517  coap_context_t *ctx,
518  const coap_address_t *local_if,
519  const coap_address_t *server,
520  coap_proto_t proto
521 ) {
522  coap_session_t *session = NULL;
523 
524  assert(server);
525  assert(proto != COAP_PROTO_NONE);
526 
527  session = coap_make_session(proto, COAP_SESSION_TYPE_CLIENT, local_if,
528  local_if, server, 0, ctx, NULL);
529  if (!session)
530  goto error;
531 
532  coap_session_reference(session);
533 
534  if (proto == COAP_PROTO_UDP || proto == COAP_PROTO_DTLS) {
535  if (!coap_socket_connect_udp(&session->sock, &session->local_if, server,
537  &session->local_addr, &session->remote_addr)) {
538  goto error;
539  }
540  } else if (proto == COAP_PROTO_TCP || proto == COAP_PROTO_TLS) {
541  if (!coap_socket_connect_tcp1(&session->sock, &session->local_if, server,
543  &session->local_addr, &session->remote_addr)) {
544  goto error;
545  }
546  }
547 
549  if (local_if)
550  session->sock.flags |= COAP_SOCKET_BOUND;
551  LL_PREPEND(ctx->sessions, session);
552  return session;
553 
554 error:
555  coap_session_release(session);
556  return NULL;
557 }
558 
559 static coap_session_t *
561  if (session->proto == COAP_PROTO_UDP) {
563  } else if (session->proto == COAP_PROTO_DTLS) {
564  session->tls = coap_dtls_new_client_session(session);
565  if (session->tls) {
567  } else {
568  /* Need to free session object. As a new session may not yet
569  * have been referenced, we call coap_session_reference() first
570  * before trying to release the object.
571  */
572  coap_session_reference(session);
573  coap_session_release(session);
574  return NULL;
575  }
576  } else if (session->proto == COAP_PROTO_TCP || session->proto == COAP_PROTO_TLS) {
577  if (session->sock.flags & COAP_SOCKET_WANT_CONNECT) {
579  } else if (session->proto == COAP_PROTO_TLS) {
580  int connected = 0;
581  session->tls = coap_tls_new_client_session(session, &connected);
582  if (session->tls) {
584  if (connected)
585  coap_session_send_csm(session);
586  } else {
587  /* Need to free session object. As a new session may not yet
588  * have been referenced, we call coap_session_reference()
589  * first before trying to release the object.
590  */
591  coap_session_reference(session);
592  coap_session_release(session);
593  return NULL;
594  }
595  } else {
596  coap_session_send_csm(session);
597  }
598  }
599  coap_ticks(&session->last_rx_tx);
600  return session;
601 }
602 
603 static coap_session_t *
605  if (session->proto == COAP_PROTO_TCP || session->proto == COAP_PROTO_TLS)
607  if (session->proto == COAP_PROTO_TCP) {
608  coap_session_send_csm(session);
609  } else if (session->proto == COAP_PROTO_TLS) {
610  int connected = 0;
611  session->tls = coap_tls_new_server_session(session, &connected);
612  if (session->tls) {
614  if (connected) {
616  coap_session_send_csm(session);
617  }
618  } else {
619  /* Need to free session object. As a new session may not yet
620  * have been referenced, we call coap_session_reference() first
621  * before trying to release the object.
622  */
623  coap_session_reference(session);
624  coap_session_release(session);
625  session = NULL;
626  }
627  }
628  return session;
629 }
630 
632  struct coap_context_t *ctx,
633  const coap_address_t *local_if,
634  const coap_address_t *server,
635  coap_proto_t proto
636 ) {
637  coap_session_t *session = coap_session_create_client(ctx, local_if, server, proto);
638  if (session) {
639  coap_log(LOG_DEBUG, "***%s: new outgoing session\n",
640  coap_session_str(session));
641  session = coap_session_connect(session);
642  }
643  return session;
644 }
645 
647  struct coap_context_t *ctx,
648  const coap_address_t *local_if,
649  const coap_address_t *server,
650  coap_proto_t proto,
651  const char *identity,
652  const uint8_t *key,
653  unsigned key_len
654 ) {
655  coap_session_t *session = coap_session_create_client(ctx, local_if, server, proto);
656 
657  if (!session)
658  return NULL;
659 
660  if (identity && (strlen(identity) > 0)) {
661  size_t identity_len = strlen(identity);
662  session->psk_identity = (uint8_t*)coap_malloc(identity_len);
663  if (session->psk_identity) {
664  memcpy(session->psk_identity, identity, identity_len);
665  session->psk_identity_len = identity_len;
666  } else {
667  coap_log(LOG_WARNING, "Cannot store session PSK identity\n");
668  coap_session_release(session);
669  return NULL;
670  }
671  }
672  else if (coap_dtls_is_supported()) {
673  coap_log(LOG_WARNING, "PSK identity not defined\n");
674  coap_session_release(session);
675  return NULL;
676  }
677 
678  if (key && key_len > 0) {
679  session->psk_key = (uint8_t*)coap_malloc(key_len);
680  if (session->psk_key) {
681  memcpy(session->psk_key, key, key_len);
682  session->psk_key_len = key_len;
683  } else {
684  coap_log(LOG_WARNING, "Cannot store session PSK key\n");
685  coap_session_release(session);
686  return NULL;
687  }
688  }
689  else if (coap_dtls_is_supported()) {
690  coap_log(LOG_WARNING, "PSK key not defined\n");
691  coap_session_release(session);
692  return NULL;
693  }
694 
695  if (coap_dtls_is_supported()) {
697  coap_session_release(session);
698  return NULL;
699  }
700  }
701  coap_log(LOG_DEBUG, "***%s: new outgoing session\n",
702  coap_session_str(session));
703  return coap_session_connect(session);
704 }
705 
707  struct coap_context_t *ctx,
708  const coap_address_t *local_if,
709  const coap_address_t *server,
710  coap_proto_t proto,
711  coap_dtls_pki_t* setup_data
712 ) {
713  coap_session_t *session;
714 
715  if (coap_dtls_is_supported()) {
716  if (!setup_data) {
717  return NULL;
718  } else {
719  if (setup_data->version != COAP_DTLS_PKI_SETUP_VERSION) {
721  "coap_new_client_session_pki: Wrong version of setup_data\n");
722  return NULL;
723  }
724  }
725 
726  }
727  session = coap_session_create_client(ctx, local_if, server, proto);
728 
729  if (!session) {
730  return NULL;
731  }
732 
733  if (coap_dtls_is_supported()) {
734  /* we know that setup_data is not NULL */
735  if (!coap_dtls_context_set_pki(ctx, setup_data, COAP_DTLS_ROLE_CLIENT)) {
736  coap_session_release(session);
737  return NULL;
738  }
739  }
740  coap_log(LOG_DEBUG, "***%s: new outgoing session\n",
741  coap_session_str(session));
742  return coap_session_connect(session);
743 }
744 
745 
747  struct coap_context_t *ctx,
748  coap_endpoint_t *ep
749 ) {
750  coap_session_t *session;
752  &ep->bind_addr, NULL, NULL, 0, ctx, ep );
753  if (!session)
754  goto error;
755 
756  if (!coap_socket_accept_tcp(&ep->sock, &session->sock,
757  &session->local_addr, &session->remote_addr))
758  goto error;
761  LL_PREPEND(ep->sessions, session);
762  if (session) {
763  coap_log(LOG_DEBUG, "***%s: new incoming session\n",
764  coap_session_str(session));
765  session = coap_session_accept(session);
766  }
767  return session;
768 
769 error:
770  coap_session_free(session);
771  return NULL;
772 }
773 
774 #ifndef WITH_LWIP
776 coap_new_endpoint(coap_context_t *context, const coap_address_t *listen_addr, coap_proto_t proto) {
777  struct coap_endpoint_t *ep = NULL;
778 
779  assert(context);
780  assert(listen_addr);
781  assert(proto != COAP_PROTO_NONE);
782 
783  if (proto == COAP_PROTO_DTLS && !coap_dtls_is_supported()) {
784  coap_log(LOG_CRIT, "coap_new_endpoint: DTLS not supported\n");
785  goto error;
786  }
787 
788  if (proto == COAP_PROTO_TLS && !coap_tls_is_supported()) {
789  coap_log(LOG_CRIT, "coap_new_endpoint: TLS not supported\n");
790  goto error;
791  }
792 
793  if (proto == COAP_PROTO_DTLS || proto == COAP_PROTO_TLS) {
794  if (!coap_dtls_context_check_keys_enabled(context)) {
796  "coap_new_endpoint: one of coap_context_set_psk() or "
797  "coap_context_set_pki() not called\n");
798  goto error;
799  }
800  }
801 
802  ep = coap_malloc_endpoint();
803  if (!ep) {
804  coap_log(LOG_WARNING, "coap_new_endpoint: malloc");
805  goto error;
806  }
807 
808  memset(ep, 0, sizeof(struct coap_endpoint_t));
809  ep->context = context;
810  ep->proto = proto;
811 
812  if (proto==COAP_PROTO_TCP || proto==COAP_PROTO_TLS) {
813  if (!coap_socket_bind_tcp(&ep->sock, listen_addr, &ep->bind_addr))
814  goto error;
816  } else if (proto==COAP_PROTO_UDP || proto==COAP_PROTO_DTLS) {
817  if (!coap_socket_bind_udp(&ep->sock, listen_addr, &ep->bind_addr))
818  goto error;
820  } else {
821  coap_log(LOG_CRIT, "coap_new_endpoint: protocol not supported\n");
822  goto error;
823  }
824 
825 #ifndef NDEBUG
826  if (LOG_DEBUG <= coap_get_log_level()) {
827 #ifndef INET6_ADDRSTRLEN
828 #define INET6_ADDRSTRLEN 40
829 #endif
830  unsigned char addr_str[INET6_ADDRSTRLEN + 8];
831 
832  if (coap_print_addr(&ep->bind_addr, addr_str, INET6_ADDRSTRLEN + 8)) {
833  coap_log(LOG_DEBUG, "created %s endpoint %s\n",
834  ep->proto == COAP_PROTO_TLS ? "TLS "
835  : ep->proto == COAP_PROTO_TCP ? "TCP "
836  : ep->proto == COAP_PROTO_DTLS ? "DTLS" : "UDP ",
837  addr_str);
838  }
839  }
840 #endif /* NDEBUG */
841 
843 
844  if (proto == COAP_PROTO_DTLS) {
845  ep->hello.proto = proto;
847  ep->hello.mtu = ep->default_mtu;
848  ep->hello.context = context;
849  ep->hello.endpoint = ep;
850  }
851 
853 
854  LL_PREPEND(context->endpoint, ep);
855  return ep;
856 
857 error:
858  coap_free_endpoint(ep);
859  return NULL;
860 }
861 
863  ep->default_mtu = (uint16_t)mtu;
864 }
865 
866 void
868  if (ep) {
869  coap_session_t *session, *tmp;
870 
871  if (ep->sock.flags != COAP_SOCKET_EMPTY)
872  coap_socket_close(&ep->sock);
873 
874  LL_FOREACH_SAFE(ep->sessions, session, tmp) {
875  assert(session->ref == 0);
876  if (session->ref == 0) {
877  session->endpoint = NULL;
878  session->context = NULL;
879  coap_session_free(session);
880  }
881  }
882 
884  }
885 }
886 #endif /* WITH_LWIP */
887 
890  const coap_address_t *remote_addr,
891  int ifindex) {
892  coap_session_t *s;
893  coap_endpoint_t *ep;
894  LL_FOREACH(ctx->sessions, s) {
895  if (s->ifindex == ifindex && coap_address_equals(&s->remote_addr, remote_addr))
896  return s;
897  }
898  LL_FOREACH(ctx->endpoint, ep) {
899  if (ep->hello.ifindex == ifindex && coap_address_equals(&ep->hello.remote_addr, remote_addr))
900  return &ep->hello;
901  LL_FOREACH(ep->sessions, s) {
902  if (s->ifindex == ifindex && coap_address_equals(&s->remote_addr, remote_addr))
903  return s;
904  }
905  }
906  return NULL;
907 }
908 
909 const char *coap_session_str(const coap_session_t *session) {
910  static char szSession[256];
911  char *p = szSession, *end = szSession + sizeof(szSession);
912  if (coap_print_addr(&session->local_addr, (unsigned char*)p, end - p) > 0)
913  p += strlen(p);
914  if (p + 6 < end) {
915  strcpy(p, " <-> ");
916  p += 5;
917  }
918  if (p + 1 < end) {
919  if (coap_print_addr(&session->remote_addr, (unsigned char*)p, end - p) > 0)
920  p += strlen(p);
921  }
922  if (session->ifindex > 0 && p + 1 < end)
923  p += snprintf(p, end - p, " (if%d)", session->ifindex);
924  if (p + 6 < end) {
925  if (session->proto == COAP_PROTO_UDP) {
926  strcpy(p, " UDP ");
927  p += 4;
928  } else if (session->proto == COAP_PROTO_DTLS) {
929  strcpy(p, " DTLS");
930  p += 5;
931  } else if (session->proto == COAP_PROTO_TCP) {
932  strcpy(p, " TCP ");
933  p += 4;
934  } else if (session->proto == COAP_PROTO_TLS) {
935  strcpy(p, " TLS ");
936  p += 4;
937  } else {
938  strcpy(p, " NONE");
939  p += 5;
940  }
941  }
942 
943  return szSession;
944 }
945 
946 const char *coap_endpoint_str(const coap_endpoint_t *endpoint) {
947  static char szEndpoint[128];
948  char *p = szEndpoint, *end = szEndpoint + sizeof(szEndpoint);
949  if (coap_print_addr(&endpoint->bind_addr, (unsigned char*)p, end - p) > 0)
950  p += strlen(p);
951  if (p + 6 < end) {
952  if (endpoint->proto == COAP_PROTO_UDP) {
953  strcpy(p, " UDP");
954  p += 4;
955  } else if (endpoint->proto == COAP_PROTO_DTLS) {
956  strcpy(p, " DTLS");
957  p += 5;
958  } else {
959  strcpy(p, " NONE");
960  p += 5;
961  }
962  }
963 
964  return szEndpoint;
965 }
966 
967 #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:287
#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:631
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:824
#define COAP_SIGNALING_CSM
Definition: pdu.h:180
void coap_socket_close(coap_socket_t *sock)
Definition: coap_io.c:624
#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:746
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:1371
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:313
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:488
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:776
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:876
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:729
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:266
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:706
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:889
#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:862
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:946
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:909
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:582
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:444
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:798
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:493
#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:604
#define assert(...)
Definition: mem.c:18
void coap_free_endpoint(coap_endpoint_t *ep)
Definition: coap_session.c:867
#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:250
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:633
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:560
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)
Adds option of given type to pdu that is passed as first parameter.
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:1397
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:2310
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:236
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:323
#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
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:516
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:380
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:627
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:525
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:646
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:411
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:254
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