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"
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
81static dtls_handler_t cb;
82static dtls_context_t *dtls_context = NULL;
83
84static const coap_keystore_t *dtls_keystore = NULL;
85static struct uip_udp_conn *dtls_conn = NULL;
86#endif /* WITH_DTLS */
87
88PROCESS(coap_engine, "CoAP Engine");
89
90static struct uip_udp_conn *udp_conn = NULL;
91
92/*---------------------------------------------------------------------------*/
93void
94coap_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/*---------------------------------------------------------------------------*/
109void
110coap_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/*---------------------------------------------------------------------------*/
125int
126coap_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/*---------------------------------------------------------------------------*/
153void
154coap_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/*---------------------------------------------------------------------------*/
162int
163coap_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/*---------------------------------------------------------------------------*/
171static int
172index_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/*---------------------------------------------------------------------------*/
185static int
186get_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/*---------------------------------------------------------------------------*/
200int
201coap_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/*---------------------------------------------------------------------------*/
233static const coap_endpoint_t *
234get_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/*---------------------------------------------------------------------------*/
243int
244coap_endpoint_is_secure(const coap_endpoint_t *ep)
245{
246 return ep->secure;
247}
248/*---------------------------------------------------------------------------*/
249int
250coap_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/*---------------------------------------------------------------------------*/
286int
287coap_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/*---------------------------------------------------------------------------*/
311void
312coap_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/*---------------------------------------------------------------------------*/
321uint8_t *
323{
324 return uip_appdata;
325}
326/*---------------------------------------------------------------------------*/
327void
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
342static void
343process_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/*---------------------------------------------------------------------------*/
357static void
358process_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/*---------------------------------------------------------------------------*/
368int
369coap_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
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
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/*---------------------------------------------------------------------------*/
411PROCESS_THREAD(coap_engine, ev, data)
412{
414
415 /* new connection with remote host */
416 udp_conn = udp_new(NULL, 0, NULL);
417 if(udp_conn == NULL) {
418 LOG_ERR("No UDP connection available, exiting the process!\n");
419 PROCESS_EXIT();
420 }
421
422 udp_bind(udp_conn, SERVER_LISTEN_PORT);
423 LOG_INFO("Listening on port %u\n", uip_ntohs(udp_conn->lport));
424
425#ifdef WITH_DTLS
426 /* create new context with app-data */
427 dtls_conn = udp_new(NULL, 0, NULL);
428 if(dtls_conn != NULL) {
429 udp_bind(dtls_conn, SERVER_LISTEN_SECURE_PORT);
430 LOG_INFO("DTLS listening on port %u\n", uip_ntohs(dtls_conn->lport));
431 dtls_context = dtls_new_context(dtls_conn);
432 }
433 if(!dtls_context) {
434 LOG_WARN("DTLS: cannot create context\n");
435 } else {
436 dtls_set_handler(dtls_context, &cb);
437 }
438#endif /* WITH_DTLS */
439
440 while(1) {
442
443 if(ev == tcpip_event) {
444 if(uip_newdata()) {
445#ifdef WITH_DTLS
446 if(uip_udp_conn == dtls_conn) {
447 process_secure_data();
448 continue;
449 }
450#endif /* WITH_DTLS */
451 process_data();
452 }
453 }
454 } /* while (1) */
455
456 PROCESS_END();
457}
458/*---------------------------------------------------------------------------*/
459
460/* DTLS */
461#ifdef WITH_DTLS
462
463/* This is input coming from the DTLS code - e.g. de-crypted input from
464 the other side - peer */
465static int
466input_from_peer(struct dtls_context_t *ctx,
467 session_t *session, uint8_t *data, size_t len)
468{
469 size_t i;
470
471 if(LOG_DBG_ENABLED) {
472 LOG_DBG("received DTLS data:");
473 for(i = 0; i < len; i++) {
474 LOG_DBG_("%c", data[i]);
475 }
476 LOG_DBG_("\n");
477 LOG_DBG("Hex:");
478 for(i = 0; i < len; i++) {
479 LOG_DBG_("%02x", data[i]);
480 }
481 LOG_DBG_("\n");
482 }
483
484 /* Ensure that the endpoint is tagged as secure */
485 session->secure = 1;
486
487 coap_receive(session, data, len);
488
489 return 0;
490}
491
492/* This is output from the DTLS code to be sent to peer (encrypted) */
493static int
494output_to_peer(struct dtls_context_t *ctx,
495 session_t *session, uint8_t *data, size_t len)
496{
497 struct uip_udp_conn *udp_connection = dtls_get_app_data(ctx);
498 LOG_DBG("output_to DTLS peer [");
499 LOG_DBG_6ADDR(&session->ipaddr);
500 LOG_DBG_("]:%u %ld bytes\n", uip_ntohs(session->port), (long)len);
501 uip_udp_packet_sendto(udp_connection, data, len,
502 &session->ipaddr, session->port);
503 return len;
504}
505
506/* This defines the key-store set API since we hookup DTLS here */
507void
508coap_set_keystore(const coap_keystore_t *keystore)
509{
510 dtls_keystore = keystore;
511}
512
513/* This function is the "key store" for tinyDTLS. It is called to
514 * retrieve a key for the given identity within this particular
515 * session. */
516static int
517get_psk_info(struct dtls_context_t *ctx,
518 const session_t *session,
519 dtls_credentials_type_t type,
520 const unsigned char *id, size_t id_len,
521 unsigned char *result, size_t result_length)
522{
524
525 if(dtls_keystore == NULL) {
526 LOG_DBG("--- No key store available ---\n");
527 return 0;
528 }
529
530 memset(&ks, 0, sizeof(ks));
531 LOG_DBG("---===>>> Getting the Key or ID <<<===---\n");
532 switch(type) {
533 case DTLS_PSK_IDENTITY:
534 if(id && id_len) {
535 ks.identity_hint = id;
536 ks.identity_hint_len = id_len;
537 LOG_DBG("got psk_identity_hint: '");
538 LOG_DBG_COAP_STRING((const char *)id, id_len);
539 LOG_DBG_("'\n");
540 }
541
542 if(dtls_keystore->coap_get_psk_info) {
543 /* we know that session is a coap endpoint */
544 dtls_keystore->coap_get_psk_info((coap_endpoint_t *)session, &ks);
545 }
546 if(ks.identity == NULL || ks.identity_len == 0) {
547 LOG_DBG("no psk_identity found\n");
548 return 0;
549 }
550
551 if(result_length < ks.identity_len) {
552 LOG_DBG("cannot return psk_identity -- buffer too small\n");
553 return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
554 }
555 memcpy(result, ks.identity, ks.identity_len);
556 LOG_DBG("psk_identity with %u bytes found\n", ks.identity_len);
557 return ks.identity_len;
558
559 case DTLS_PSK_KEY:
560 if(dtls_keystore->coap_get_psk_info) {
561 ks.identity = id;
562 ks.identity_len = id_len;
563 /* we know that session is a coap endpoint */
564 dtls_keystore->coap_get_psk_info((coap_endpoint_t *)session, &ks);
565 }
566 if(ks.key == NULL || ks.key_len == 0) {
567 LOG_DBG("PSK for unknown id requested, exiting\n");
568 return dtls_alert_fatal_create(DTLS_ALERT_ILLEGAL_PARAMETER);
569 }
570
571 if(result_length < ks.key_len) {
572 LOG_DBG("cannot return psk -- buffer too small\n");
573 return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
574 }
575 memcpy(result, ks.key, ks.key_len);
576 LOG_DBG("psk with %u bytes found\n", ks.key_len);
577 return ks.key_len;
578
579 default:
580 LOG_WARN("unsupported key store request type: %d\n", type);
581 }
582
583 return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
584}
585
586
587static dtls_handler_t cb = {
588 .write = output_to_peer,
589 .read = input_from_peer,
590 .event = NULL,
591#ifdef DTLS_PSK
592 .get_psk_info = get_psk_info,
593#endif /* DTLS_PSK */
594#ifdef DTLS_ECC
595 /* .get_ecdsa_key = get_ecdsa_key, */
596 /* .verify_ecdsa_key = verify_ecdsa_key */
597#endif /* DTLS_ECC */
598};
599
600#endif /* WITH_DTLS */
601/*---------------------------------------------------------------------------*/
602/** @} */
603/** @} */
Collection of constants specified in the CoAP standard.
API to address CoAP endpoints.
CoAP engine implementation.
A simple keystore with fixed credentials.
API for CoAP keystore.
Log support for CoAP.
CoAP module for reliable transport.
API for CoAP 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:1154
void coap_keystore_simple_init(void)
Registers a simple CoAP DTLS keystore with fixed pre-shared key credentials.
void coap_set_keystore(const coap_keystore_t *keystore)
Set the CoAP keystore to use by CoAP.
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
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_cmp(const coap_endpoint_t *e1, const coap_endpoint_t *e2)
Compare two CoAP endpoints.
Definition: coap-uip.c:163
int coap_endpoint_parse(const char *text, size_t size, coap_endpoint_t *ep)
Parse a CoAP endpoint.
Definition: coap-uip.c:201
int coap_endpoint_connect(coap_endpoint_t *ep)
Request a connection to a CoAP endpoint.
Definition: coap-uip.c:287
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
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_print(const coap_endpoint_t *ep)
Print a CoAP endpoint.
Definition: coap-uip.c:110
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
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_transport_init(void)
Initialize the CoAP transport.
Definition: coap-uip.c:328
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
int coap_endpoint_is_connected(const coap_endpoint_t *ep)
Check if a CoAP endpoint is connected.
Definition: coap-uip.c:250
void log_6addr(const uip_ipaddr_t *ipaddr)
Logs an IPv6 address.
Definition: log.c:89
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
#define PROCESS_EXIT()
Exit the currently running process.
Definition: process.h:200
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
#define PROCESS_YIELD()
Yield the currently running process.
Definition: process.h:164
static void start(void)
Start measurement.
process_event_t tcpip_event
The uIP event.
Definition: tcpip.c:62
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
#define udp_bind(conn, port)
Bind a UDP connection to a local port.
Definition: tcpip.h:261
#define uiplib_ipaddrconv
Convert a textual representation of an IP address to a numerical representation.
Definition: uiplib.h:71
void uiplib_ipaddr_print(const uip_ipaddr_t *addr)
Print an IP address using printf().
Definition: uiplib.c:158
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
void * uip_appdata
Pointer to the application data in the packet buffer.
Definition: uip6.c:148
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
Definition: uip.h:1775
#define UIP_IP_BUF
Direct access to IPv6 header.
Definition: uip.h:71
#define uip_datalen()
The length of any incoming data that is currently available (if available) in the uip_appdata buffer.
Definition: uip.h:593
#define uip_newdata()
Is new incoming data available?
Definition: uip.h:680
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
Definition: uip.h:1157
#define uip_ipaddr_copy(dest, src)
Copy an IP address from one place to another.
Definition: uip.h:969
Routing driver header file.
The structure of a CoAP pre-shared key info.
Definition: coap-keystore.h:59
The structure of a CoAP keystore.
Definition: coap-keystore.h:75
int(* node_is_reachable)(void)
Tells whether the node is currently reachable as part of the network.
Definition: routing.h:114
Representation of a uIP UDP connection.
Definition: uip.h:1309
uint16_t lport
The local port number in network byte order.
Definition: uip.h:1311
Header file for module for sending UDP packets through uIP.
Header file for the IP address manipulation library.