1 /* coap_io_lwip.h -- Network I/O functions for libcoap on lwIP
2  *
3  * Copyright (C) 2012,2014 Olaf Bergmann <bergmann@tzi.org>
4  *               2014 chrysn <chrysn@fsfe.org>
5  *
6  * This file is part of the CoAP library libcoap. Please see
7  * README for terms of use.
8  */
9 
10 #include "coap_config.h"
11 #include "mem.h"
12 #include "coap_io.h"
13 
coap_packet_populate_endpoint(coap_packet_t * packet,coap_endpoint_t * target)14 void coap_packet_populate_endpoint(coap_packet_t *packet, coap_endpoint_t *target)
15 {
16 	printf("FIXME no endpoint populated\n");
17 }
coap_packet_copy_source(coap_packet_t * packet,coap_address_t * target)18 void coap_packet_copy_source(coap_packet_t *packet, coap_address_t *target)
19 {
20 	target->port = packet->srcport;
21 	memcpy(&target->addr, ip_current_src_addr(), sizeof(ip_addr_t));
22 }
coap_packet_get_memmapped(coap_packet_t * packet,unsigned char ** address,size_t * length)23 void coap_packet_get_memmapped(coap_packet_t *packet, unsigned char **address, size_t *length)
24 {
25 	LWIP_ASSERT("Can only deal with contiguous PBUFs to read the initial details", packet->pbuf->tot_len == packet->pbuf->len);
26 	*address = packet->pbuf->payload;
27 	*length = packet->pbuf->tot_len;
28 }
coap_free_packet(coap_packet_t * packet)29 void coap_free_packet(coap_packet_t *packet)
30 {
31 	if (packet->pbuf)
32 		pbuf_free(packet->pbuf);
33 	coap_free_type(COAP_PACKET, packet);
34 }
35 
coap_packet_extract_pbuf(coap_packet_t * packet)36 struct pbuf *coap_packet_extract_pbuf(coap_packet_t *packet)
37 {
38 	struct pbuf *ret = packet->pbuf;
39 	packet->pbuf = NULL;
40 	return ret;
41 }
42 
43 
44 /** Callback from lwIP when a package was received.
45  *
46  * The current implemntation deals this to coap_handle_message immedately, but
47  * other mechanisms (as storing the package in a queue and later fetching it
48  * when coap_read is called) can be envisioned.
49  *
50  * It handles everything coap_read does on other implementations.
51  */
coap_recv(void * arg,struct udp_pcb * upcb,struct pbuf * p,ip_addr_t * addr,u16_t port)52 static void coap_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
53 {
54 	coap_endpoint_t *ep = (coap_endpoint_t*)arg;
55 	coap_packet_t *packet = coap_malloc_type(COAP_PACKET, sizeof(coap_packet_t));
56 	/* this is fatal because due to the short life of the packet, never should there be more than one coap_packet_t required */
57 	LWIP_ASSERT("Insufficient coap_packet_t resources.", packet != NULL);
58 	packet->pbuf = p;
59 	packet->srcport = port;
60 
61 	/** FIXME derive the context without changing endopint definition */
62 	coap_handle_message(ep->context, packet);
63 
64 	coap_free_packet(packet);
65 }
66 
coap_new_endpoint(const coap_address_t * addr,int flags)67 coap_endpoint_t *coap_new_endpoint(const coap_address_t *addr, int flags) {
68 	coap_endpoint_t *result;
69 	err_t err;
70 
71 	LWIP_ASSERT("Flags not supported for LWIP endpoints", flags == COAP_ENDPOINT_NOSEC);
72 
73 	result = coap_malloc_type(COAP_ENDPOINT, sizeof(coap_endpoint_t));
74 	if (!result) return NULL;
75 
76 	result->pcb = udp_new();
77 	if (result->pcb == NULL) goto error;
78 
79 	udp_recv(result->pcb, coap_recv, (void*)result);
80 	err = udp_bind(result->pcb, &addr->addr, addr->port);
81 	if (err) {
82 		udp_remove(result->pcb);
83 		goto error;
84 	}
85 
86 	return result;
87 
88 error:
89 	coap_free_type(COAP_ENDPOINT, result);
90 	return NULL;
91 }
92 
coap_free_endpoint(coap_endpoint_t * ep)93 void coap_free_endpoint(coap_endpoint_t *ep)
94 {
95 	udp_remove(ep->pcb);
96 	coap_free_type(COAP_ENDPOINT, ep);
97 }
98