mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-27 23:41:18 +01:00
lwip_sock: provide implementation for sock_*_recv_buf()
This commit is contained in:
parent
ba711c50bf
commit
77b89bb968
@ -106,20 +106,15 @@ static uint16_t _ip6_addr_to_netif(const ip6_addr_p_t *_addr)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _parse_iphdr(const struct netbuf *buf, void *data, size_t max_len,
|
||||
static int _parse_iphdr(struct netbuf *buf, void **data, void **ctx,
|
||||
sock_ip_ep_t *remote)
|
||||
{
|
||||
uint8_t *data_ptr = buf->p->payload;
|
||||
size_t data_len = buf->p->len;
|
||||
uint8_t *data_ptr = buf->ptr->payload;
|
||||
size_t data_len = buf->ptr->len;
|
||||
|
||||
assert(buf->p->next == NULL); /* TODO this might not be generally the case
|
||||
* check later with larger payloads */
|
||||
switch (data_ptr[0] >> 4) {
|
||||
#if LWIP_IPV4
|
||||
case 4:
|
||||
if ((data_len - sizeof(struct ip_hdr)) > max_len) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
if (remote != NULL) {
|
||||
struct ip_hdr *iphdr = (struct ip_hdr *)data_ptr;
|
||||
|
||||
@ -134,9 +129,6 @@ static int _parse_iphdr(const struct netbuf *buf, void *data, size_t max_len,
|
||||
#endif
|
||||
#if LWIP_IPV6
|
||||
case 6:
|
||||
if ((data_len - sizeof(struct ip6_hdr)) > max_len) {
|
||||
return -ENOBUFS;
|
||||
}
|
||||
if (remote != NULL) {
|
||||
struct ip6_hdr *iphdr = (struct ip6_hdr *)data_ptr;
|
||||
|
||||
@ -150,24 +142,63 @@ static int _parse_iphdr(const struct netbuf *buf, void *data, size_t max_len,
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
netbuf_delete(buf);
|
||||
return -EPROTO;
|
||||
}
|
||||
memcpy(data, data_ptr, data_len);
|
||||
*data = data_ptr;
|
||||
*ctx = buf;
|
||||
return (ssize_t)data_len;
|
||||
}
|
||||
|
||||
ssize_t sock_ip_recv(sock_ip_t *sock, void *data, size_t max_len,
|
||||
uint32_t timeout, sock_ip_ep_t *remote)
|
||||
{
|
||||
void *pkt = NULL;
|
||||
struct netbuf *ctx = NULL;
|
||||
uint8_t *ptr = data;
|
||||
ssize_t res, ret = 0;
|
||||
bool nobufs = false;
|
||||
|
||||
assert((sock != NULL) && (data != NULL) && (max_len > 0));
|
||||
while ((res = sock_ip_recv_buf(sock, &pkt, (void **)&ctx, timeout,
|
||||
remote)) > 0) {
|
||||
if (ctx->p->tot_len > (ssize_t)max_len) {
|
||||
nobufs = true;
|
||||
/* progress context to last element */
|
||||
while (netbuf_next(ctx) == 0) {}
|
||||
continue;
|
||||
}
|
||||
memcpy(ptr, pkt, res);
|
||||
ptr += res;
|
||||
ret += res;
|
||||
}
|
||||
return (nobufs) ? -ENOBUFS : ((res < 0) ? res : ret);
|
||||
}
|
||||
|
||||
ssize_t sock_ip_recv_buf(sock_ip_t *sock, void **data, void **ctx,
|
||||
uint32_t timeout, sock_ip_ep_t *remote)
|
||||
{
|
||||
struct netbuf *buf;
|
||||
int res;
|
||||
|
||||
assert((sock != NULL) && (data != NULL) && (max_len > 0));
|
||||
assert((sock != NULL) && (data != NULL) && (ctx != NULL));
|
||||
buf = *ctx;
|
||||
if (buf != NULL) {
|
||||
if (netbuf_next(buf) == -1) {
|
||||
*data = NULL;
|
||||
netbuf_delete(buf);
|
||||
*ctx = NULL;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
*data = buf->ptr->payload;
|
||||
return buf->ptr->len;
|
||||
}
|
||||
}
|
||||
if ((res = lwip_sock_recv(sock->base.conn, timeout, &buf)) < 0) {
|
||||
return res;
|
||||
}
|
||||
res = _parse_iphdr(buf, data, max_len, remote);
|
||||
netbuf_delete(buf);
|
||||
res = _parse_iphdr(buf, data, ctx, remote);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@ -71,19 +71,52 @@ int sock_udp_get_remote(sock_udp_t *sock, sock_udp_ep_t *ep)
|
||||
ssize_t sock_udp_recv(sock_udp_t *sock, void *data, size_t max_len,
|
||||
uint32_t timeout, sock_udp_ep_t *remote)
|
||||
{
|
||||
uint8_t *data_ptr = data;
|
||||
void *pkt = NULL;
|
||||
void *ctx = NULL;
|
||||
uint8_t *ptr = data;
|
||||
ssize_t res, ret = 0;
|
||||
bool nobufs = false;
|
||||
|
||||
assert((sock != NULL) && (data != NULL) && (max_len > 0));
|
||||
while ((res = sock_udp_recv_buf(sock, &pkt, &ctx, timeout,
|
||||
remote)) > 0) {
|
||||
struct netbuf *buf = ctx;
|
||||
if (buf->p->tot_len > (ssize_t)max_len) {
|
||||
nobufs = true;
|
||||
/* progress context to last element */
|
||||
while (netbuf_next(ctx) == 0) {}
|
||||
continue;
|
||||
}
|
||||
memcpy(ptr, pkt, res);
|
||||
ptr += res;
|
||||
ret += res;
|
||||
}
|
||||
return (nobufs) ? -ENOBUFS : ((res < 0) ? res : ret);
|
||||
}
|
||||
|
||||
ssize_t sock_udp_recv_buf(sock_udp_t *sock, void **data, void **ctx,
|
||||
uint32_t timeout, sock_udp_ep_t *remote)
|
||||
{
|
||||
struct netbuf *buf;
|
||||
int res;
|
||||
|
||||
assert((sock != NULL) && (data != NULL) && (max_len > 0));
|
||||
assert((sock != NULL) && (data != NULL) && (ctx != NULL));
|
||||
buf = *ctx;
|
||||
if (buf != NULL) {
|
||||
if (netbuf_next(buf) == -1) {
|
||||
*data = NULL;
|
||||
netbuf_delete(buf);
|
||||
*ctx = NULL;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
*data = buf->ptr->payload;
|
||||
return buf->ptr->len;
|
||||
}
|
||||
}
|
||||
if ((res = lwip_sock_recv(sock->base.conn, timeout, &buf)) < 0) {
|
||||
return res;
|
||||
}
|
||||
res = buf->p->tot_len;
|
||||
if ((unsigned)res > max_len) {
|
||||
netbuf_delete(buf);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
if (remote != NULL) {
|
||||
/* convert remote */
|
||||
size_t addr_len;
|
||||
@ -113,13 +146,9 @@ ssize_t sock_udp_recv(sock_udp_t *sock, void *data, size_t max_len,
|
||||
memcpy(&remote->addr, &buf->addr, addr_len);
|
||||
remote->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 (ssize_t)res;
|
||||
*data = buf->ptr->payload;
|
||||
*ctx = buf;
|
||||
return (ssize_t)buf->ptr->len;
|
||||
}
|
||||
|
||||
ssize_t sock_udp_send(sock_udp_t *sock, const void *data, size_t len,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user