Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lwip: initial import of conn_ip wrapper
- Loading branch information
Showing
9 changed files
with
396 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
MODULE := lwip_conn | ||
|
||
include $(RIOTBASE)/Makefile.base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
MODULE := lwip_conn_ip | ||
|
||
include $(RIOTBASE)/Makefile.base |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
* Copyright (C) 2015 Freie Universität Berlin | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @{ | ||
* | ||
* @file | ||
* @author Martine Lenders <mlenders@inf.fu-berlin.de> | ||
*/ | ||
|
||
#include <assert.h> | ||
#include <errno.h> | ||
|
||
#include "net/ipv4/addr.h" | ||
#include "net/ipv6/addr.h" | ||
#include "net/conn/ip.h" | ||
|
||
#include "lwip/api.h" | ||
#include "lwip/conn.h" | ||
|
||
int conn_ip_create(conn_ip_t *conn, const void *addr, size_t addr_len, int family, int proto) | ||
{ | ||
struct netconn *tmp; | ||
int res; | ||
|
||
res = lwip_conn_create(&tmp, addr, addr_len, family, NETCONN_RAW, proto, 0); | ||
if (res < 0) { | ||
return res; | ||
} | ||
conn->lwip_conn = tmp; | ||
|
||
return res; | ||
} | ||
|
||
void conn_ip_close(conn_ip_t *conn) | ||
{ | ||
assert(conn != NULL); | ||
netconn_delete(conn->lwip_conn); | ||
} | ||
|
||
int conn_ip_getlocaladdr(conn_ip_t *conn, void *addr) | ||
{ | ||
assert(conn != NULL); | ||
return lwip_conn_getlocaladdr(conn->lwip_conn, addr, NULL); | ||
} | ||
|
||
int conn_ip_recvfrom(conn_ip_t *conn, void *data, size_t max_len, void *addr, size_t *addr_len) | ||
{ | ||
assert(conn != NULL); | ||
return lwip_conn_recvfrom(conn->lwip_conn, data, max_len, addr, addr_len, NULL); | ||
} | ||
|
||
int conn_ip_sendto(const void *data, size_t len, const void *src, size_t src_len, | ||
void *dst, size_t dst_len, int family, int proto) | ||
{ | ||
struct netconn *tmp; | ||
int res; | ||
|
||
res = lwip_conn_create(&tmp, src, src_len, family, NETCONN_RAW, proto, 0); | ||
if (res < 0) { | ||
return res; | ||
} | ||
res = lwip_conn_sendto(tmp, data, len, dst, dst_len, 0); | ||
netconn_delete(tmp); | ||
return res; | ||
} | ||
|
||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
/* | ||
* Copyright (C) 2015 Freie Universität Berlin | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @{ | ||
* | ||
* @file | ||
* @author Martine Lenders <mlenders@inf.fu-berlin.de> | ||
*/ | ||
|
||
#include <errno.h> | ||
#include <stdbool.h> | ||
|
||
#include "byteorder.h" | ||
#include "net/af.h" | ||
#include "net/ipv4/addr.h" | ||
#include "net/ipv6/addr.h" | ||
#include "net/conn.h" | ||
|
||
#include "lwip/api.h" | ||
#include "lwip/opt.h" | ||
|
||
int lwip_conn_create(struct netconn **netconn, const void *addr, size_t addr_len, int family, | ||
int type, int proto, uint16_t port) | ||
{ | ||
struct netconn *tmp; | ||
int res = 0; | ||
|
||
switch (family) { | ||
#if LWIP_IPV4 | ||
case AF_INET: | ||
if (addr_len != sizeof(ipv4_addr_t)) { | ||
return -EINVAL; | ||
} | ||
break; | ||
#endif | ||
#if LWIP_IPV6 | ||
case AF_INET6: | ||
if (addr_len != sizeof(ipv6_addr_t)) { | ||
return -EINVAL; | ||
} | ||
type |= NETCONN_TYPE_IPV6; | ||
break; | ||
#endif | ||
default: | ||
return -EAFNOSUPPORT; | ||
} | ||
if ((tmp = netconn_new_with_proto_and_callback(type, proto, NULL)) == NULL) { | ||
return -ENOMEM; | ||
} | ||
switch (netconn_bind(tmp, (ip_addr_t *)addr, port)) { | ||
case ERR_USE: | ||
netconn_delete(tmp); | ||
res = -EADDRINUSE; | ||
break; | ||
case ERR_VAL: | ||
netconn_delete(tmp); | ||
res = -EINVAL; | ||
break; | ||
default: | ||
break; | ||
} | ||
*netconn = tmp; | ||
return res; | ||
} | ||
|
||
int lwip_conn_getlocaladdr(struct netconn *netconn, void *addr, uint16_t *port) | ||
{ | ||
uint16_t tmp; | ||
|
||
if (netconn_getaddr(netconn, addr, &tmp, 1) != ERR_OK) { | ||
return -EOPNOTSUPP; | ||
} | ||
if (port != NULL) { | ||
*port = tmp; | ||
} | ||
#if LWIP_IPV6 | ||
if (netconn->type & NETCONN_TYPE_IPV6) { | ||
return sizeof(ipv6_addr_t); | ||
} | ||
#endif | ||
#if LWIP_IPV4 | ||
return sizeof(ipv4_addr_t); | ||
#else | ||
return -EOPNOTSUPP; | ||
#endif | ||
} | ||
|
||
int lwip_conn_recvfrom(struct netconn *netconn, void *data, size_t max_len, void *addr, | ||
size_t *addr_len, uint16_t *port) | ||
{ | ||
struct netbuf *buf; | ||
size_t len = 0; | ||
err_t res = 0; | ||
uint8_t *data_ptr = data; | ||
|
||
if (netconn == NULL) { | ||
return -ENOTSOCK; | ||
} | ||
if ((res = netconn_recv(netconn, &buf))) { | ||
switch (res) { | ||
#if LWIP_SO_RCVTIMEO | ||
case ERR_TIMEOUT: | ||
return -ETIMEDOUT; | ||
#endif | ||
case ERR_MEM: | ||
return -ENOMEM; | ||
default: | ||
return -EIO; | ||
} | ||
} | ||
len = buf->p->tot_len; | ||
if (len > max_len) { | ||
netbuf_delete(buf); | ||
return -ENOBUFS; | ||
} | ||
#if LWIP_IPV6 | ||
if (netconn->type & NETCONN_TYPE_IPV6) { | ||
*addr_len = sizeof(ipv6_addr_t); | ||
} | ||
else { | ||
#endif | ||
#if LWIP_IPV4 | ||
*addr_len = sizeof(ipv4_addr_t); | ||
#else | ||
netbuf_delete(buf); | ||
return -EOPNOTSUPP; | ||
#endif | ||
#if LWIP_IPV6 | ||
} | ||
#endif | ||
/* copy address */ | ||
memcpy(addr, &buf->addr, *addr_len); | ||
/* copy port */ | ||
if (port != NULL) { | ||
*port = buf->port; | ||
} | ||
/* copy data */ | ||
for (struct pbuf *q = buf->p; q != NULL; q = q->next) { | ||
memcpy(data_ptr, q->payload, q->len); | ||
data_ptr += q->len; | ||
} | ||
|
||
netbuf_delete(buf); | ||
|
||
return (int)len; | ||
} | ||
|
||
int lwip_conn_sendto(struct netconn *netconn, const void *data, size_t len, | ||
const void *addr, size_t addr_len, uint16_t port) | ||
{ | ||
struct netbuf *buf; | ||
int res; | ||
|
||
#if LWIP_IPV6 | ||
if (netconn->type & NETCONN_TYPE_IPV6) { | ||
if (addr_len != sizeof(ipv6_addr_t)) { | ||
return -EINVAL; | ||
} | ||
} | ||
else { | ||
#endif | ||
#if LWIP_IPV4 | ||
if (addr_len != sizeof(ipv4_addr_t)) { | ||
return -EINVAL; | ||
} | ||
#endif | ||
#if LWIP_IPV6 | ||
} | ||
#endif | ||
buf = netbuf_new(); | ||
if ((buf == NULL) || (netbuf_alloc(buf, len) == NULL)) { | ||
netbuf_delete(buf); | ||
return -ENOMEM; | ||
} | ||
if (netbuf_take(buf, data, len) != ERR_OK) { | ||
netbuf_delete(buf); | ||
return -ENOBUFS; | ||
} | ||
switch ((res = netconn_sendto(netconn, buf, addr, port))) { | ||
case ERR_OK: | ||
res = len; | ||
break; | ||
case ERR_RTE: | ||
res = -EHOSTUNREACH; | ||
break; | ||
case ERR_VAL: | ||
res = -EINVAL; | ||
break; | ||
case ERR_IF: | ||
res = -EAFNOSUPPORT; | ||
break; | ||
default: | ||
res = -EIO; | ||
break; | ||
} | ||
netbuf_delete(buf); | ||
return res; | ||
} | ||
|
||
/** @} */ |
Oops, something went wrong.