Contiki-NG
coap-uip.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, SICS, Swedish ICT AB.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 /**
31  * \file
32  * CoAP transport implementation for uIPv6
33  * \author
34  * Niclas Finne <nfi@sics.se>
35  * Joakim Eriksson <joakime@sics.se>
36  */
37 
38 /**
39  * \addtogroup coap-transport
40  * @{
41  *
42  * \defgroup coap-uip CoAP transport implementation for uIP
43  * @{
44  *
45  * This is an implementation of CoAP transport and CoAP endpoint over uIP
46  * with DTLS support.
47  */
48 
49 #include "contiki.h"
51 #include "net/ipv6/uiplib.h"
52 #include "net/routing/routing.h"
53 #include "coap.h"
54 #include "coap-engine.h"
55 #include "coap-endpoint.h"
56 #include "coap-transport.h"
57 #include "coap-transactions.h"
58 #include "coap-constants.h"
59 #include "coap-keystore.h"
60 #include "coap-keystore-simple.h"
61 
62 /* Log configuration */
63 #include "coap-log.h"
64 #define LOG_MODULE "coap-uip"
65 #define LOG_LEVEL LOG_LEVEL_COAP
66 
67 #ifdef WITH_DTLS
68 #include "tinydtls.h"
69 #include "dtls.h"
70 #endif /* WITH_DTLS */
71 
72 /* sanity check for configured values */
73 #if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_IPH_LEN - UIP_UDPH_LEN)
74 #error "UIP_CONF_BUFFER_SIZE too small for COAP_MAX_CHUNK_SIZE"
75 #endif
76 
77 #define SERVER_LISTEN_PORT UIP_HTONS(COAP_DEFAULT_PORT)
78 #define SERVER_LISTEN_SECURE_PORT UIP_HTONS(COAP_DEFAULT_SECURE_PORT)
79 
80 #ifdef WITH_DTLS
81 static dtls_handler_t cb;
82 static dtls_context_t *dtls_context = NULL;
83 
84 static const coap_keystore_t *dtls_keystore = NULL;
85 static struct uip_udp_conn *dtls_conn = NULL;
86 #endif /* WITH_DTLS */
87 
88 PROCESS(coap_engine, "CoAP Engine");
89 
90 static struct uip_udp_conn *udp_conn = NULL;
91 
92 /*---------------------------------------------------------------------------*/
93 void
94 coap_endpoint_log(const coap_endpoint_t *ep)
95 {
96  if(ep == NULL) {
97  LOG_OUTPUT("(NULL EP)");
98  return;
99  }
100  if(ep->secure) {
101  LOG_OUTPUT("coaps://[");
102  } else {
103  LOG_OUTPUT("coap://[");
104  }
105  log_6addr(&ep->ipaddr);
106  LOG_OUTPUT("]:%u", uip_ntohs(ep->port));
107 }
108 /*---------------------------------------------------------------------------*/
109 void
110 coap_endpoint_print(const coap_endpoint_t *ep)
111 {
112  if(ep == NULL) {
113  printf("(NULL EP)");
114  return;
115  }
116  if(ep->secure) {
117  printf("coaps://[");
118  } else {
119  printf("coap://[");
120  }
121  uiplib_ipaddr_print(&ep->ipaddr);
122  printf("]:%u", uip_ntohs(ep->port));
123 }
124 /*---------------------------------------------------------------------------*/
125 int
126 coap_endpoint_snprint(char *buf, size_t size, const coap_endpoint_t *ep)
127 {
128  int n;
129  if(buf == NULL || size == 0) {
130  return 0;
131  }
132  if(ep == NULL) {
133  n = snprintf(buf, size - 1, "(NULL EP)");
134  } else {
135  if(ep->secure) {
136  n = snprintf(buf, size - 1, "coaps://[");
137  } else {
138  n = snprintf(buf, size - 1, "coap://[");
139  }
140  if(n < size - 1) {
141  n += uiplib_ipaddr_snprint(&buf[n], size - n - 1, &ep->ipaddr);
142  }
143  if(n < size - 1) {
144  n += snprintf(&buf[n], size -n - 1, "]:%u", uip_ntohs(ep->port));
145  }
146  }
147  if(n >= size - 1) {
148  buf[size - 1] = '\0';
149  }
150  return n;
151 }
152 /*---------------------------------------------------------------------------*/
153 void
154 coap_endpoint_copy(coap_endpoint_t *destination,
155  const coap_endpoint_t *from)
156 {
157  uip_ipaddr_copy(&destination->ipaddr, &from->ipaddr);
158  destination->port = from->port;
159  destination->secure = from->secure;
160 }
161 /*---------------------------------------------------------------------------*/
162 int
163 coap_endpoint_cmp(const coap_endpoint_t *e1, const coap_endpoint_t *e2)
164 {
165  if(!uip_ipaddr_cmp(&e1->ipaddr, &e2->ipaddr)) {
166  return 0;
167  }
168  return e1->port == e2->port && e1->secure == e2->secure;
169 }
170 /*---------------------------------------------------------------------------*/
171 static int
172 index_of(const char *data, int offset, int len, uint8_t c)
173 {
174  if(offset < 0) {
175  return offset;
176  }
177  for(; offset < len; offset++) {
178  if(data[offset] == c) {
179  return offset;
180  }
181  }
182  return -1;
183 }
184 /*---------------------------------------------------------------------------*/
185 static int
186 get_port(const char *inbuf, size_t len, uint32_t *value)
187 {
188  int i;
189  *value = 0;
190  for(i = 0; i < len; i++) {
191  if(inbuf[i] >= '0' && inbuf[i] <= '9') {
192  *value = *value * 10 + (inbuf[i] - '0');
193  } else {
194  break;
195  }
196  }
197  return i;
198 }
199 /*---------------------------------------------------------------------------*/
200 int
201 coap_endpoint_parse(const char *text, size_t size, coap_endpoint_t *ep)
202 {
203  /* Only IPv6 supported */
204  int start = index_of(text, 0, size, '[');
205  int end = index_of(text, start, size, ']');
206  uint32_t port;
207 
208  ep->secure = strncmp(text, "coaps:", 6) == 0;
209  if(start >= 0 && end > start &&
210  uiplib_ipaddrconv(&text[start], &ep->ipaddr)) {
211  if(text[end + 1] == ':' &&
212  get_port(text + end + 2, size - end - 2, &port)) {
213  ep->port = UIP_HTONS(port);
214  } else if(ep->secure) {
215  /* Use secure CoAP port by default for secure endpoints. */
216  ep->port = SERVER_LISTEN_SECURE_PORT;
217  } else {
218  ep->port = SERVER_LISTEN_PORT;
219  }
220  return 1;
221  } else if(size < UIPLIB_IPV6_MAX_STR_LEN) {
222  char buf[UIPLIB_IPV6_MAX_STR_LEN];
223  memcpy(buf, text, size);
224  buf[size] = '\0';
225  if(uiplib_ipaddrconv(buf, &ep->ipaddr)) {
226  ep->port = SERVER_LISTEN_PORT;
227  return 1;
228  }
229  }
230  return 0;
231 }
232 /*---------------------------------------------------------------------------*/
233 static const coap_endpoint_t *
234 get_src_endpoint(uint8_t secure)
235 {
236  static coap_endpoint_t src;
237  uip_ipaddr_copy(&src.ipaddr, &UIP_IP_BUF->srcipaddr);
238  src.port = UIP_UDP_BUF->srcport;
239  src.secure = secure;
240  return &src;
241 }
242 /*---------------------------------------------------------------------------*/
243 int
244 coap_endpoint_is_secure(const coap_endpoint_t *ep)
245 {
246  return ep->secure;
247 }
248 /*---------------------------------------------------------------------------*/
249 int
250 coap_endpoint_is_connected(const coap_endpoint_t *ep)
251 {
252 #ifndef CONTIKI_TARGET_NATIVE
253  if(!uip_is_addr_linklocal(&ep->ipaddr)
254  && NETSTACK_ROUTING.node_is_reachable() == 0) {
255  return 0;
256  }
257 #endif
258 
259 #ifdef WITH_DTLS
260  if(ep != NULL && ep->secure != 0) {
261  dtls_peer_t *peer;
262  if(dtls_context == NULL) {
263  return 0;
264  }
265  peer = dtls_get_peer(dtls_context, ep);
266  if(peer != NULL) {
267  /* only if handshake is done! */
268  LOG_DBG("DTLS peer state for ");
269  LOG_DBG_COAP_EP(ep);
270  LOG_DBG_(" is %d (%sconnected)\n", peer->state,
271  dtls_peer_is_connected(peer) ? "" : "not ");
272  return dtls_peer_is_connected(peer);
273  } else {
274  LOG_DBG("DTLS did not find peer ");
275  LOG_DBG_COAP_EP(ep);
276  LOG_DBG_("\n");
277  return 0;
278  }
279  }
280 #endif /* WITH_DTLS */
281 
282  /* Assume connected */
283  return 1;
284 }
285 /*---------------------------------------------------------------------------*/
286 int
287 coap_endpoint_connect(coap_endpoint_t *ep)
288 {
289  if(ep->secure == 0) {
290  LOG_DBG("connect to ");
291  LOG_DBG_COAP_EP(ep);
292  LOG_DBG_("\n");
293  return 1;
294  }
295 
296 #ifdef WITH_DTLS
297  LOG_DBG("DTLS connect to ");
298  LOG_DBG_COAP_EP(ep);
299  LOG_DBG_("\n");
300 
301  /* setup all address info here... should be done to connect */
302  if(dtls_context) {
303  dtls_connect(dtls_context, ep);
304  return 1;
305  }
306 #endif /* WITH_DTLS */
307 
308  return 0;
309 }
310 /*---------------------------------------------------------------------------*/
311 void
312 coap_endpoint_disconnect(coap_endpoint_t *ep)
313 {
314 #ifdef WITH_DTLS
315  if(ep && ep->secure && dtls_context) {
316  dtls_close(dtls_context, ep);
317  }
318 #endif /* WITH_DTLS */
319 }
320 /*---------------------------------------------------------------------------*/
321 uint8_t *
323 {
324  return uip_appdata;
325 }
326 /*---------------------------------------------------------------------------*/
327 void
329 {
330  process_start(&coap_engine, NULL);
331 #ifdef WITH_DTLS
332  dtls_init();
333 
334 #if COAP_DTLS_KEYSTORE_CONF_WITH_SIMPLE
336 #endif /* COAP_DTLS_KEYSTORE_CONF_WITH_SIMPLE */
337 
338 #endif /* WITH_DTLS */
339 }
340 /*---------------------------------------------------------------------------*/
341 #ifdef WITH_DTLS
342 static void
343 process_secure_data(void)
344 {
345  LOG_INFO("receiving secure UDP datagram from [");
346  LOG_INFO_6ADDR(&UIP_IP_BUF->srcipaddr);
347  LOG_INFO_("]:%u\n", uip_ntohs(UIP_UDP_BUF->srcport));
348  LOG_INFO(" Length: %u\n", uip_datalen());
349 
350  if(dtls_context) {
351  dtls_handle_message(dtls_context, (coap_endpoint_t *)get_src_endpoint(1),
353  }
354 }
355 #endif /* WITH_DTLS */
356 /*---------------------------------------------------------------------------*/
357 static void
358 process_data(void)
359 {
360  LOG_INFO("receiving UDP datagram from [");
361  LOG_INFO_6ADDR(&UIP_IP_BUF->srcipaddr);
362  LOG_INFO_("]:%u\n", uip_ntohs(UIP_UDP_BUF->srcport));
363  LOG_INFO(" Length: %u\n", uip_datalen());
364 
365  coap_receive(get_src_endpoint(0), uip_appdata, uip_datalen());
366 }
367 /*---------------------------------------------------------------------------*/
368 int
369 coap_sendto(const coap_endpoint_t *ep, const uint8_t *data, uint16_t length)
370 {
371  if(ep == NULL) {
372  LOG_WARN("failed to send - no endpoint\n");
373  return -1;
374  }
375 
376  if(!coap_endpoint_is_connected(ep)) {
377  LOG_WARN("endpoint ");
378  LOG_WARN_COAP_EP(ep);
379  LOG_WARN_(" not connected - dropping packet\n");
380  return -1;
381  }
382 
383 #ifdef WITH_DTLS
384  if(coap_endpoint_is_secure(ep)) {
385  if(dtls_context) {
386  int ret;
387 
388  ret = dtls_write(dtls_context, (session_t *)ep, (uint8_t *)data, length);
389  LOG_INFO("sent DTLS to ");
390  LOG_INFO_COAP_EP(ep);
391  if(ret < 0) {
392  LOG_INFO_(" - error %d\n", ret);
393  } else {
394  LOG_INFO_(" %d/%u bytes\n", ret, length);
395  }
396  return ret;
397  } else {
398  LOG_WARN("no DTLS context\n");
399  return -1;
400  }
401  }
402 #endif /* WITH_DTLS */
403 
404  uip_udp_packet_sendto(udp_conn, data, length, &ep->ipaddr, ep->port);
405  LOG_INFO("sent to ");
406  LOG_INFO_COAP_EP(ep);
407  LOG_INFO_(" %u bytes\n", length);
408  return length;
409 }
410 /*---------------------------------------------------------------------------*/
411 PROCESS_THREAD(coap_engine, ev, data)
412 {
413  PROCESS_BEGIN();
414 
415  /* new connection with remote host */
416  udp_conn = udp_new(NULL, 0, NULL);
417  udp_bind(udp_conn, SERVER_LISTEN_PORT);
418  LOG_INFO("Listening on port %u\n", uip_ntohs(udp_conn->lport));
419 
420 #ifdef WITH_DTLS
421  /* create new context with app-data */
422  dtls_conn = udp_new(NULL, 0, NULL);
423  if(dtls_conn != NULL) {
424  udp_bind(dtls_conn, SERVER_LISTEN_SECURE_PORT);
425  LOG_INFO("DTLS listening on port %u\n", uip_ntohs(dtls_conn->lport));
426  dtls_context = dtls_new_context(dtls_conn);
427  }
428  if(!dtls_context) {
429  LOG_WARN("DTLS: cannot create context\n");
430  } else {
431  dtls_set_handler(dtls_context, &cb);
432  }
433 #endif /* WITH_DTLS */
434 
435  while(1) {
436  PROCESS_YIELD();
437 
438  if(ev == tcpip_event) {
439  if(uip_newdata()) {
440 #ifdef WITH_DTLS
441  if(uip_udp_conn == dtls_conn) {
442  process_secure_data();
443  continue;
444  }
445 #endif /* WITH_DTLS */
446  process_data();
447  }
448  }
449  } /* while (1) */
450 
451  PROCESS_END();
452 }
453 /*---------------------------------------------------------------------------*/
454 
455 /* DTLS */
456 #ifdef WITH_DTLS
457 
458 /* This is input coming from the DTLS code - e.g. de-crypted input from
459  the other side - peer */
460 static int
461 input_from_peer(struct dtls_context_t *ctx,
462  session_t *session, uint8_t *data, size_t len)
463 {
464  size_t i;
465 
466  if(LOG_DBG_ENABLED) {
467  LOG_DBG("received DTLS data:");
468  for(i = 0; i < len; i++) {
469  LOG_DBG_("%c", data[i]);
470  }
471  LOG_DBG_("\n");
472  LOG_DBG("Hex:");
473  for(i = 0; i < len; i++) {
474  LOG_DBG_("%02x", data[i]);
475  }
476  LOG_DBG_("\n");
477  }
478 
479  /* Ensure that the endpoint is tagged as secure */
480  session->secure = 1;
481 
482  coap_receive(session, data, len);
483 
484  return 0;
485 }
486 
487 /* This is output from the DTLS code to be sent to peer (encrypted) */
488 static int
489 output_to_peer(struct dtls_context_t *ctx,
490  session_t *session, uint8_t *data, size_t len)
491 {
492  struct uip_udp_conn *udp_connection = dtls_get_app_data(ctx);
493  LOG_DBG("output_to DTLS peer [");
494  LOG_DBG_6ADDR(&session->ipaddr);
495  LOG_DBG_("]:%u %ld bytes\n", uip_ntohs(session->port), (long)len);
496  uip_udp_packet_sendto(udp_connection, data, len,
497  &session->ipaddr, session->port);
498  return len;
499 }
500 
501 /* This defines the key-store set API since we hookup DTLS here */
502 void
503 coap_set_keystore(const coap_keystore_t *keystore)
504 {
505  dtls_keystore = keystore;
506 }
507 
508 /* This function is the "key store" for tinyDTLS. It is called to
509  * retrieve a key for the given identity within this particular
510  * session. */
511 static int
512 get_psk_info(struct dtls_context_t *ctx,
513  const session_t *session,
514  dtls_credentials_type_t type,
515  const unsigned char *id, size_t id_len,
516  unsigned char *result, size_t result_length)
517 {
519 
520  if(dtls_keystore == NULL) {
521  LOG_DBG("--- No key store available ---\n");
522  return 0;
523  }
524 
525  memset(&ks, 0, sizeof(ks));
526  LOG_DBG("---===>>> Getting the Key or ID <<<===---\n");
527  switch(type) {
528  case DTLS_PSK_IDENTITY:
529  if(id && id_len) {
530  ks.identity_hint = id;
531  ks.identity_hint_len = id_len;
532  LOG_DBG("got psk_identity_hint: '");
533  LOG_DBG_COAP_STRING((const char *)id, id_len);
534  LOG_DBG_("'\n");
535  }
536 
537  if(dtls_keystore->coap_get_psk_info) {
538  /* we know that session is a coap endpoint */
539  dtls_keystore->coap_get_psk_info((coap_endpoint_t *)session, &ks);
540  }
541  if(ks.identity == NULL || ks.identity_len == 0) {
542  LOG_DBG("no psk_identity found\n");
543  return 0;
544  }
545 
546  if(result_length < ks.identity_len) {
547  LOG_DBG("cannot return psk_identity -- buffer too small\n");
548  return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
549  }
550  memcpy(result, ks.identity, ks.identity_len);
551  LOG_DBG("psk_identity with %u bytes found\n", ks.identity_len);
552  return ks.identity_len;
553 
554  case DTLS_PSK_KEY:
555  if(dtls_keystore->coap_get_psk_info) {
556  ks.identity = id;
557  ks.identity_len = id_len;
558  /* we know that session is a coap endpoint */
559  dtls_keystore->coap_get_psk_info((coap_endpoint_t *)session, &ks);
560  }
561  if(ks.key == NULL || ks.key_len == 0) {
562  LOG_DBG("PSK for unknown id requested, exiting\n");
563  return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER);
564  }
565 
566  if(result_length < ks.key_len) {
567  LOG_DBG("cannot return psk -- buffer too small\n");
568  return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
569  }
570  memcpy(result, ks.key, ks.key_len);
571  LOG_DBG("psk with %u bytes found\n", ks.key_len);
572  return ks.key_len;
573 
574  default:
575  LOG_WARN("unsupported key store request type: %d\n", type);
576  }
577 
578  return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
579 }
580 
581 
582 static dtls_handler_t cb = {
583  .write = output_to_peer,
584  .read = input_from_peer,
585  .event = NULL,
586 #ifdef DTLS_PSK
587  .get_psk_info = get_psk_info,
588 #endif /* DTLS_PSK */
589 #ifdef DTLS_ECC
590  /* .get_ecdsa_key = get_ecdsa_key, */
591  /* .verify_ecdsa_key = verify_ecdsa_key */
592 #endif /* DTLS_ECC */
593 };
594 
595 #endif /* WITH_DTLS */
596 /*---------------------------------------------------------------------------*/
597 /** @} */
598 /** @} */
Log support for CoAP
int coap_endpoint_connect(coap_endpoint_t *ep)
Request a connection to a CoAP endpoint.
Definition: coap-uip.c:287
#define UIP_IP_BUF
Direct access to IPv6 header.
Definition: uip.h:71
void coap_endpoint_print(const coap_endpoint_t *ep)
Print a CoAP endpoint.
Definition: coap-uip.c:110
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
void coap_endpoint_log(const coap_endpoint_t *ep)
Print a CoAP endpoint via the logging module.
Definition: coap-uip.c:94
void coap_endpoint_copy(coap_endpoint_t *destination, const coap_endpoint_t *from)
Copy a CoAP endpoint from one memory area to another.
Definition: coap-uip.c:154
API to address CoAP endpoints
A simple keystore with fixed credentials.
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
CoAP engine implementation.
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
process_event_t tcpip_event
The uIP event.
Definition: tcpip.c:62
int coap_endpoint_snprint(char *buf, size_t size, const coap_endpoint_t *ep)
Print a CoAP endpoint to a string.
Definition: coap-uip.c:126
Header file for module for sending UDP packets through uIP.
uint16_t lport
The local port number in network byte order.
Definition: uip.h:1377
static void start(void)
Start measurement.
int coap_endpoint_is_connected(const coap_endpoint_t *ep)
Check if a CoAP endpoint is connected.
Definition: coap-uip.c:250
Header file for the IP address manipulation library.
#define uip_newdata()
Is new incoming data available?
Definition: uip.h:726
The structure of a CoAP keystore.
Definition: coap-keystore.h:75
void coap_set_keystore(const coap_keystore_t *keystore)
Set the CoAP keystore to use by CoAP.
struct uip_udp_conn * udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
Create a new UDP connection.
Definition: tcpip.c:261
int coap_sendto(const coap_endpoint_t *ep, const uint8_t *data, uint16_t length)
Send a message to the specified CoAP endpoint.
Definition: coap-uip.c:369
Routing driver header file
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
Definition: uip.h:1015
int coap_endpoint_parse(const char *text, size_t size, coap_endpoint_t *ep)
Parse a CoAP endpoint.
Definition: coap-uip.c:201
uint8_t * coap_databuf(void)
Returns a common data buffer that can be used when generating CoAP messages for transmission.
Definition: coap-uip.c:322
#define PROCESS_YIELD()
Yield the currently running process.
Definition: process.h:164
void coap_transport_init(void)
Initialize the CoAP transport.
Definition: coap-uip.c:328
The structure of a CoAP pre-shared key info.
Definition: coap-keystore.h:59
void log_6addr(const uip_ipaddr_t *ipaddr)
Logs an IPv6 address.
Definition: log.c:87
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
Definition: uip.h:1223
int coap_endpoint_cmp(const coap_endpoint_t *e1, const coap_endpoint_t *e2)
Compare two CoAP endpoints.
Definition: coap-uip.c:163
void coap_endpoint_disconnect(coap_endpoint_t *ep)
Request that any connection to a CoAP endpoint is discontinued.
Definition: coap-uip.c:312
int coap_endpoint_is_secure(const coap_endpoint_t *ep)
Check if a CoAP endpoint is secure (encrypted).
Definition: coap-uip.c:244
void coap_keystore_simple_init(void)
Registers a simple CoAP DTLS keystore with fixed pre-shared key credentials.
void uiplib_ipaddr_print(const uip_ipaddr_t *addr)
Print an IP address using printf().
Definition: uiplib.c:158
API for CoAP keystore
CoAP module for reliable transport
An implementation of the Constrained Application Protocol (RFC 7252).
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Definition: cc2538-rf.c:1097
#define uiplib_ipaddrconv
Convert a textual representation of an IP address to a numerical representation.
Definition: uiplib.h:71
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
Definition: uip.h:1877
#define udp_bind(conn, port)
Bind a UDP connection to a local port.
Definition: tcpip.h:261
void * uip_appdata
Pointer to the application data in the packet buffer.
Definition: uip6.c:148
int(* node_is_reachable)(void)
Tells whether the node is currently reachable as part of the network.
Definition: routing.h:114
Collection of constants specified in the CoAP standard.
#define uip_datalen()
The length of any incoming data that is currently available (if available) in the uip_appdata buffer...
Definition: uip.h:639
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
Representation of a uIP UDP connection.
Definition: uip.h:1375
API for CoAP transport
int uiplib_ipaddr_snprint(char *buf, size_t size, const uip_ipaddr_t *addr)
Write at most size - 1 characters of the IP address to the output string.
Definition: uiplib.c:166