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