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 "coap.h"
53 #include "coap-engine.h"
54 #include "coap-endpoint.h"
55 #include "coap-transport.h"
56 #include "coap-transactions.h"
57 #include "coap-constants.h"
58 #include "coap-keystore.h"
59 #include "coap-keystore-simple.h"
60 
61 #if UIP_CONF_IPV6_RPL
62 #include "rpl.h"
63 #endif /* UIP_CONF_IPV6_RPL */
64 
65 /* Log configuration */
66 #include "coap-log.h"
67 #define LOG_MODULE "coap-uip"
68 #define LOG_LEVEL LOG_LEVEL_COAP
69 
70 #ifdef WITH_DTLS
71 #include "tinydtls.h"
72 #include "dtls.h"
73 #endif /* WITH_DTLS */
74 
75 /* sanity check for configured values */
76 #if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPH_LEN - UIP_UDPH_LEN)
77 #error "UIP_CONF_BUFFER_SIZE too small for COAP_MAX_CHUNK_SIZE"
78 #endif
79 
80 #define SERVER_LISTEN_PORT UIP_HTONS(COAP_DEFAULT_PORT)
81 #define SERVER_LISTEN_SECURE_PORT UIP_HTONS(COAP_DEFAULT_SECURE_PORT)
82 
83 /* direct access into the buffer */
84 #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
85 #if NETSTACK_CONF_WITH_IPV6
86 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
87 #else
88 #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
89 #endif
90 
91 #ifdef WITH_DTLS
92 static dtls_handler_t cb;
93 static dtls_context_t *dtls_context = NULL;
94 
95 static const coap_keystore_t *dtls_keystore = NULL;
96 static struct uip_udp_conn *dtls_conn = NULL;
97 #endif /* WITH_DTLS */
98 
99 PROCESS(coap_engine, "CoAP Engine");
100 
101 static struct uip_udp_conn *udp_conn = NULL;
102 
103 /*---------------------------------------------------------------------------*/
104 void
105 coap_endpoint_log(const coap_endpoint_t *ep)
106 {
107  if(ep == NULL) {
108  LOG_OUTPUT("(NULL EP)");
109  return;
110  }
111  if(ep->secure) {
112  LOG_OUTPUT("coaps://[");
113  } else {
114  LOG_OUTPUT("coap://[");
115  }
116  log_6addr(&ep->ipaddr);
117  LOG_OUTPUT("]:%u", uip_ntohs(ep->port));
118 }
119 /*---------------------------------------------------------------------------*/
120 void
121 coap_endpoint_print(const coap_endpoint_t *ep)
122 {
123  if(ep == NULL) {
124  printf("(NULL EP)");
125  return;
126  }
127  if(ep->secure) {
128  printf("coaps://[");
129  } else {
130  printf("coap://[");
131  }
132  uiplib_ipaddr_print(&ep->ipaddr);
133  printf("]:%u", uip_ntohs(ep->port));
134 }
135 /*---------------------------------------------------------------------------*/
136 int
137 coap_endpoint_snprint(char *buf, size_t size, const coap_endpoint_t *ep)
138 {
139  int n;
140  if(buf == NULL || size == 0) {
141  return 0;
142  }
143  if(ep == NULL) {
144  n = snprintf(buf, size - 1, "(NULL EP)");
145  } else {
146  if(ep->secure) {
147  n = snprintf(buf, size - 1, "coaps://[");
148  } else {
149  n = snprintf(buf, size - 1, "coap://[");
150  }
151  if(n < size - 1) {
152  n += uiplib_ipaddr_snprint(&buf[n], size - n - 1, &ep->ipaddr);
153  }
154  if(n < size - 1) {
155  n += snprintf(&buf[n], size -n - 1, "]:%u", uip_ntohs(ep->port));
156  }
157  }
158  if(n >= size - 1) {
159  buf[size - 1] = '\0';
160  }
161  return n;
162 }
163 /*---------------------------------------------------------------------------*/
164 void
165 coap_endpoint_copy(coap_endpoint_t *destination,
166  const coap_endpoint_t *from)
167 {
168  uip_ipaddr_copy(&destination->ipaddr, &from->ipaddr);
169  destination->port = from->port;
170  destination->secure = from->secure;
171 }
172 /*---------------------------------------------------------------------------*/
173 int
174 coap_endpoint_cmp(const coap_endpoint_t *e1, const coap_endpoint_t *e2)
175 {
176  if(!uip_ipaddr_cmp(&e1->ipaddr, &e2->ipaddr)) {
177  return 0;
178  }
179  return e1->port == e2->port && e1->secure == e2->secure;
180 }
181 /*---------------------------------------------------------------------------*/
182 static int
183 index_of(const char *data, int offset, int len, uint8_t c)
184 {
185  if(offset < 0) {
186  return offset;
187  }
188  for(; offset < len; offset++) {
189  if(data[offset] == c) {
190  return offset;
191  }
192  }
193  return -1;
194 }
195 /*---------------------------------------------------------------------------*/
196 static int
197 get_port(const char *inbuf, size_t len, uint32_t *value)
198 {
199  int i;
200  *value = 0;
201  for(i = 0; i < len; i++) {
202  if(inbuf[i] >= '0' && inbuf[i] <= '9') {
203  *value = *value * 10 + (inbuf[i] - '0');
204  } else {
205  break;
206  }
207  }
208  return i;
209 }
210 /*---------------------------------------------------------------------------*/
211 int
212 coap_endpoint_parse(const char *text, size_t size, coap_endpoint_t *ep)
213 {
214  /* Only IPv6 supported */
215  int start = index_of(text, 0, size, '[');
216  int end = index_of(text, start, size, ']');
217  uint32_t port;
218 
219  ep->secure = strncmp(text, "coaps:", 6) == 0;
220  if(start >= 0 && end > start &&
221  uiplib_ipaddrconv(&text[start], &ep->ipaddr)) {
222  if(text[end + 1] == ':' &&
223  get_port(text + end + 2, size - end - 2, &port)) {
224  ep->port = UIP_HTONS(port);
225  } else if(ep->secure) {
226  /* Use secure CoAP port by default for secure endpoints. */
227  ep->port = SERVER_LISTEN_SECURE_PORT;
228  } else {
229  ep->port = SERVER_LISTEN_PORT;
230  }
231  return 1;
232  } else if(size < UIPLIB_IPV6_MAX_STR_LEN) {
233  char buf[UIPLIB_IPV6_MAX_STR_LEN];
234  memcpy(buf, text, size);
235  buf[size] = '\0';
236  if(uiplib_ipaddrconv(buf, &ep->ipaddr)) {
237  ep->port = SERVER_LISTEN_PORT;
238  return 1;
239  }
240  }
241  return 0;
242 }
243 /*---------------------------------------------------------------------------*/
244 static const coap_endpoint_t *
245 get_src_endpoint(uint8_t secure)
246 {
247  static coap_endpoint_t src;
248  uip_ipaddr_copy(&src.ipaddr, &UIP_IP_BUF->srcipaddr);
249  src.port = UIP_UDP_BUF->srcport;
250  src.secure = secure;
251  return &src;
252 }
253 /*---------------------------------------------------------------------------*/
254 int
255 coap_endpoint_is_secure(const coap_endpoint_t *ep)
256 {
257  return ep->secure;
258 }
259 /*---------------------------------------------------------------------------*/
260 int
261 coap_endpoint_is_connected(const coap_endpoint_t *ep)
262 {
263 #if UIP_CONF_IPV6_RPL
264 #ifndef CONTIKI_TARGET_NATIVE
265  if(rpl_get_any_dag() == NULL) {
266  return 0;
267  }
268 #endif
269 #endif /* UIP_CONF_IPV6_RPL */
270 
271 #ifdef WITH_DTLS
272  if(ep != NULL && ep->secure != 0) {
273  dtls_peer_t *peer;
274  if(dtls_context == NULL) {
275  return 0;
276  }
277  peer = dtls_get_peer(dtls_context, ep);
278  if(peer != NULL) {
279  /* only if handshake is done! */
280  LOG_DBG("DTLS peer state for ");
281  LOG_DBG_COAP_EP(ep);
282  LOG_DBG_(" is %d (%sconnected)\n", peer->state,
283  dtls_peer_is_connected(peer) ? "" : "not ");
284  return dtls_peer_is_connected(peer);
285  } else {
286  LOG_DBG("DTLS did not find peer ");
287  LOG_DBG_COAP_EP(ep);
288  LOG_DBG_("\n");
289  return 0;
290  }
291  }
292 #endif /* WITH_DTLS */
293 
294  /* Assume connected */
295  return 1;
296 }
297 /*---------------------------------------------------------------------------*/
298 int
299 coap_endpoint_connect(coap_endpoint_t *ep)
300 {
301  if(ep->secure == 0) {
302  LOG_DBG("connect to ");
303  LOG_DBG_COAP_EP(ep);
304  LOG_DBG_("\n");
305  return 1;
306  }
307 
308 #ifdef WITH_DTLS
309  LOG_DBG("DTLS connect to ");
310  LOG_DBG_COAP_EP(ep);
311  LOG_DBG_("\n");
312 
313  /* setup all address info here... should be done to connect */
314  if(dtls_context) {
315  dtls_connect(dtls_context, ep);
316  return 1;
317  }
318 #endif /* WITH_DTLS */
319 
320  return 0;
321 }
322 /*---------------------------------------------------------------------------*/
323 void
324 coap_endpoint_disconnect(coap_endpoint_t *ep)
325 {
326 #ifdef WITH_DTLS
327  if(ep && ep->secure && dtls_context) {
328  dtls_close(dtls_context, ep);
329  }
330 #endif /* WITH_DTLS */
331 }
332 /*---------------------------------------------------------------------------*/
333 uint8_t *
335 {
336  return uip_appdata;
337 }
338 /*---------------------------------------------------------------------------*/
339 void
341 {
342  process_start(&coap_engine, NULL);
343 #ifdef WITH_DTLS
344  dtls_init();
345 
346 #if COAP_DTLS_KEYSTORE_CONF_WITH_SIMPLE
348 #endif /* COAP_DTLS_KEYSTORE_CONF_WITH_SIMPLE */
349 
350 #endif /* WITH_DTLS */
351 }
352 /*---------------------------------------------------------------------------*/
353 #ifdef WITH_DTLS
354 static void
355 process_secure_data(void)
356 {
357  LOG_INFO("receiving secure UDP datagram from [");
358  LOG_INFO_6ADDR(&UIP_IP_BUF->srcipaddr);
359  LOG_INFO_("]:%u\n", uip_ntohs(UIP_UDP_BUF->srcport));
360  LOG_INFO(" Length: %u\n", uip_datalen());
361 
362  if(dtls_context) {
363  dtls_handle_message(dtls_context, (coap_endpoint_t *)get_src_endpoint(1),
365  }
366 }
367 #endif /* WITH_DTLS */
368 /*---------------------------------------------------------------------------*/
369 static void
370 process_data(void)
371 {
372  LOG_INFO("receiving UDP datagram from [");
373  LOG_INFO_6ADDR(&UIP_IP_BUF->srcipaddr);
374  LOG_INFO_("]:%u\n", uip_ntohs(UIP_UDP_BUF->srcport));
375  LOG_INFO(" Length: %u\n", uip_datalen());
376 
377  coap_receive(get_src_endpoint(0), uip_appdata, uip_datalen());
378 }
379 /*---------------------------------------------------------------------------*/
380 int
381 coap_sendto(const coap_endpoint_t *ep, const uint8_t *data, uint16_t length)
382 {
383  if(ep == NULL) {
384  LOG_WARN("failed to send - no endpoint\n");
385  return -1;
386  }
387 
388  if(!coap_endpoint_is_connected(ep)) {
389  LOG_WARN("endpoint ");
390  LOG_WARN_COAP_EP(ep);
391  LOG_WARN_(" not connected - dropping packet\n");
392  return -1;
393  }
394 
395 #ifdef WITH_DTLS
396  if(coap_endpoint_is_secure(ep)) {
397  if(dtls_context) {
398  int ret;
399 
400  ret = dtls_write(dtls_context, (session_t *)ep, (uint8_t *)data, length);
401  LOG_INFO("sent DTLS to ");
402  LOG_INFO_COAP_EP(ep);
403  if(ret < 0) {
404  LOG_INFO_(" - error %d\n", ret);
405  } else {
406  LOG_INFO_(" %d/%u bytes\n", ret, length);
407  }
408  return ret;
409  } else {
410  LOG_WARN("no DTLS context\n");
411  return -1;
412  }
413  }
414 #endif /* WITH_DTLS */
415 
416  uip_udp_packet_sendto(udp_conn, data, length, &ep->ipaddr, ep->port);
417  LOG_INFO("sent to ");
418  LOG_INFO_COAP_EP(ep);
419  LOG_INFO_(" %u bytes\n", length);
420  return length;
421 }
422 /*---------------------------------------------------------------------------*/
423 PROCESS_THREAD(coap_engine, ev, data)
424 {
425  PROCESS_BEGIN();
426 
427  /* new connection with remote host */
428  udp_conn = udp_new(NULL, 0, NULL);
429  udp_bind(udp_conn, SERVER_LISTEN_PORT);
430  LOG_INFO("Listening on port %u\n", uip_ntohs(udp_conn->lport));
431 
432 #ifdef WITH_DTLS
433  /* create new context with app-data */
434  dtls_conn = udp_new(NULL, 0, NULL);
435  if(dtls_conn != NULL) {
436  udp_bind(dtls_conn, SERVER_LISTEN_SECURE_PORT);
437  LOG_INFO("DTLS listening on port %u\n", uip_ntohs(dtls_conn->lport));
438  dtls_context = dtls_new_context(dtls_conn);
439  }
440  if(!dtls_context) {
441  LOG_WARN("DTLS: cannot create context\n");
442  } else {
443  dtls_set_handler(dtls_context, &cb);
444  }
445 #endif /* WITH_DTLS */
446 
447  while(1) {
448  PROCESS_YIELD();
449 
450  if(ev == tcpip_event) {
451  if(uip_newdata()) {
452 #ifdef WITH_DTLS
453  if(uip_udp_conn == dtls_conn) {
454  process_secure_data();
455  continue;
456  }
457 #endif /* WITH_DTLS */
458  process_data();
459  }
460  }
461  } /* while (1) */
462 
463  PROCESS_END();
464 }
465 /*---------------------------------------------------------------------------*/
466 
467 /* DTLS */
468 #ifdef WITH_DTLS
469 
470 /* This is input coming from the DTLS code - e.g. de-crypted input from
471  the other side - peer */
472 static int
473 input_from_peer(struct dtls_context_t *ctx,
474  session_t *session, uint8_t *data, size_t len)
475 {
476  size_t i;
477 
478  if(LOG_DBG_ENABLED) {
479  LOG_DBG("received DTLS data:");
480  for(i = 0; i < len; i++) {
481  LOG_DBG_("%c", data[i]);
482  }
483  LOG_DBG_("\n");
484  LOG_DBG("Hex:");
485  for(i = 0; i < len; i++) {
486  LOG_DBG_("%02x", data[i]);
487  }
488  LOG_DBG_("\n");
489  }
490 
491  /* Ensure that the endpoint is tagged as secure */
492  session->secure = 1;
493 
494  coap_receive(session, data, len);
495 
496  return 0;
497 }
498 
499 /* This is output from the DTLS code to be sent to peer (encrypted) */
500 static int
501 output_to_peer(struct dtls_context_t *ctx,
502  session_t *session, uint8_t *data, size_t len)
503 {
504  struct uip_udp_conn *udp_connection = dtls_get_app_data(ctx);
505  LOG_DBG("output_to DTLS peer [");
506  LOG_DBG_6ADDR(&session->ipaddr);
507  LOG_DBG_("]:%u %ld bytes\n", uip_ntohs(session->port), (long)len);
508  uip_udp_packet_sendto(udp_connection, data, len,
509  &session->ipaddr, session->port);
510  return len;
511 }
512 
513 /* This defines the key-store set API since we hookup DTLS here */
514 void
515 coap_set_keystore(const coap_keystore_t *keystore)
516 {
517  dtls_keystore = keystore;
518 }
519 
520 /* This function is the "key store" for tinyDTLS. It is called to
521  * retrieve a key for the given identity within this particular
522  * session. */
523 static int
524 get_psk_info(struct dtls_context_t *ctx,
525  const session_t *session,
526  dtls_credentials_type_t type,
527  const unsigned char *id, size_t id_len,
528  unsigned char *result, size_t result_length)
529 {
531 
532  if(dtls_keystore == NULL) {
533  LOG_DBG("--- No key store available ---\n");
534  return 0;
535  }
536 
537  memset(&ks, 0, sizeof(ks));
538  LOG_DBG("---===>>> Getting the Key or ID <<<===---\n");
539  switch(type) {
540  case DTLS_PSK_IDENTITY:
541  if(id && id_len) {
542  ks.identity_hint = id;
543  ks.identity_hint_len = id_len;
544  LOG_DBG("got psk_identity_hint: '");
545  LOG_DBG_COAP_STRING((const char *)id, id_len);
546  LOG_DBG_("'\n");
547  }
548 
549  if(dtls_keystore->coap_get_psk_info) {
550  /* we know that session is a coap endpoint */
551  dtls_keystore->coap_get_psk_info((coap_endpoint_t *)session, &ks);
552  }
553  if(ks.identity == NULL || ks.identity_len == 0) {
554  LOG_DBG("no psk_identity found\n");
555  return 0;
556  }
557 
558  if(result_length < ks.identity_len) {
559  LOG_DBG("cannot return psk_identity -- buffer too small\n");
560  return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
561  }
562  memcpy(result, ks.identity, ks.identity_len);
563  LOG_DBG("psk_identity with %u bytes found\n", ks.identity_len);
564  return ks.identity_len;
565 
566  case DTLS_PSK_KEY:
567  if(dtls_keystore->coap_get_psk_info) {
568  ks.identity = id;
569  ks.identity_len = id_len;
570  /* we know that session is a coap endpoint */
571  dtls_keystore->coap_get_psk_info((coap_endpoint_t *)session, &ks);
572  }
573  if(ks.key == NULL || ks.key_len == 0) {
574  LOG_DBG("PSK for unknown id requested, exiting\n");
575  return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER);
576  }
577 
578  if(result_length < ks.key_len) {
579  LOG_DBG("cannot return psk -- buffer too small\n");
580  return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
581  }
582  memcpy(result, ks.key, ks.key_len);
583  LOG_DBG("psk with %u bytes found\n", ks.key_len);
584  return ks.key_len;
585 
586  default:
587  LOG_WARN("unsupported key store request type: %d\n", type);
588  }
589 
590  return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
591 }
592 
593 
594 static dtls_handler_t cb = {
595  .write = output_to_peer,
596  .read = input_from_peer,
597  .event = NULL,
598 #ifdef DTLS_PSK
599  .get_psk_info = get_psk_info,
600 #endif /* DTLS_PSK */
601 #ifdef DTLS_ECC
602  /* .get_ecdsa_key = get_ecdsa_key, */
603  /* .verify_ecdsa_key = verify_ecdsa_key */
604 #endif /* DTLS_ECC */
605 };
606 
607 #endif /* WITH_DTLS */
608 /*---------------------------------------------------------------------------*/
609 /** @} */
610 /** @} */
Log support for CoAP
int coap_endpoint_connect(coap_endpoint_t *ep)
Request a connection to a CoAP endpoint.
Definition: coap-uip.c:299
#define UIP_IP_BUF
Pointer to IP header.
Definition: uip-nd6.c:96
void coap_endpoint_print(const coap_endpoint_t *ep)
Print a CoAP endpoint.
Definition: coap-uip.c:121
#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:105
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:165
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:66
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:137
Header file for module for sending UDP packets through uIP.
uint16_t lport
The local port number in network byte order.
Definition: uip.h:1399
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:261
Header file for the IP address manipulation library.
#define uip_newdata()
Is new incoming data available?
Definition: uip.h:729
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:265
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:381
rpl_dag_t * rpl_get_any_dag(void)
Returns pointer to any DAG (for compatibility with legagy RPL code)
Definition: rpl-dag.c:1051
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
Definition: uip.h:1018
int coap_endpoint_parse(const char *text, size_t size, coap_endpoint_t *ep)
Parse a CoAP endpoint.
Definition: coap-uip.c:212
uint8_t * coap_databuf(void)
Returns a common data buffer that can be used when generating CoAP messages for transmission.
Definition: coap-uip.c:334
#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:340
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:86
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
Definition: uip.h:1230
int coap_endpoint_cmp(const coap_endpoint_t *e1, const coap_endpoint_t *e2)
Compare two CoAP endpoints.
Definition: coap-uip.c:174
void coap_endpoint_disconnect(coap_endpoint_t *ep)
Request that any connection to a CoAP endpoint is discontinued.
Definition: coap-uip.c:324
int coap_endpoint_is_secure(const coap_endpoint_t *ep)
Check if a CoAP endpoint is secure (encrypted).
Definition: coap-uip.c:255
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:160
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:1008
#define uiplib_ipaddrconv
Convert a textual representation of an IP address to a numerical representation.
Definition: uiplib.h:72
#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:168
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:642
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:1397
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:168