Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gnrc_sock: provide port for sock_ip and sock_udp #5772

Merged
merged 4 commits into from
Oct 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ ifneq (,$(filter gnrc_conn_udp,$(USEMODULE)))
USEMODULE += gnrc_udp
endif

ifneq (,$(filter gnrc_sock_%,$(USEMODULE)))
USEMODULE += gnrc_sock
endif

ifneq (,$(filter gnrc_sock_udp,$(USEMODULE)))
USEMODULE += gnrc_udp
USEMODULE += random # to generate random ports
endif

ifneq (,$(filter gnrc_sock,$(USEMODULE)))
USEMODULE += gnrc_netapi_mbox
endif

ifneq (,$(filter gnrc_netapi_mbox,$(USEMODULE)))
USEMODULE += core_mbox
endif
Expand Down
5 changes: 5 additions & 0 deletions Makefile.pseudomodules
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ PSEUDOMODULES += gnrc_sixlowpan_iphc_nhc
PSEUDOMODULES += gnrc_sixlowpan_nd_border_router
PSEUDOMODULES += gnrc_sixlowpan_router
PSEUDOMODULES += gnrc_sixlowpan_router_default
PSEUDOMODULES += gnrc_sock_check_reuse
PSEUDOMODULES += log
PSEUDOMODULES += log_printfnoformat
PSEUDOMODULES += lwip_arp
Expand Down Expand Up @@ -51,6 +52,10 @@ PSEUDOMODULES += saul_adc
PSEUDOMODULES += saul_default
PSEUDOMODULES += saul_gpio
PSEUDOMODULES += schedstatistics
PSEUDOMODULES += sock
PSEUDOMODULES += sock_ip
PSEUDOMODULES += sock_tcp
PSEUDOMODULES += sock_udp

# include variants of the AT86RF2xx drivers as pseudo modules
PSEUDOMODULES += at86rf23%
Expand Down
6 changes: 6 additions & 0 deletions sys/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ endif
ifneq (,$(filter fib,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/sys/posix/include
endif
ifneq (,$(filter gnrc_sock,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/sys/net/gnrc/sock/include
ifneq (,$(filter gnrc_ipv6,$(USEMODULE)))
CFLAGS += -DSOCK_HAS_IPV6
endif
endif
ifneq (,$(filter posix,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/sys/posix/include
endif
Expand Down
9 changes: 9 additions & 0 deletions sys/net/gnrc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ endif
ifneq (,$(filter gnrc_slip,$(USEMODULE)))
DIRS += link_layer/slip
endif
ifneq (,$(filter gnrc_sock,$(USEMODULE)))
DIRS += sock
endif
ifneq (,$(filter gnrc_sock_ip,$(USEMODULE)))
DIRS += sock/ip
endif
ifneq (,$(filter gnrc_sock_udp,$(USEMODULE)))
DIRS += sock/udp
endif
ifneq (,$(filter gnrc_udp,$(USEMODULE)))
DIRS += transport_layer/udp
endif
Expand Down
3 changes: 3 additions & 0 deletions sys/net/gnrc/sock/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MODULE = gnrc_sock

include $(RIOTBASE)/Makefile.base
197 changes: 197 additions & 0 deletions sys/net/gnrc/sock/gnrc_sock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*
* Copyright (C) 2016 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* 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 "net/af.h"
#include "net/ipv6/hdr.h"
#include "net/gnrc/ipv6/hdr.h"
#include "net/gnrc/ipv6/netif.h"
#include "net/gnrc/netreg.h"
#include "net/udp.h"
#include "utlist.h"
#include "xtimer.h"

#include "sock_types.h"
#include "gnrc_sock_internal.h"

#ifdef MODULE_XTIMER
#define _TIMEOUT_MAGIC (0xF38A0B63U)
#define _TIMEOUT_MSG_TYPE (0x8474)

static void _callback_put(void *arg)
{
msg_t timeout_msg = { .sender_pid = KERNEL_PID_UNDEF,
.type = _TIMEOUT_MSG_TYPE,
.content = { .value = _TIMEOUT_MAGIC } };
gnrc_sock_reg_t *reg = arg;

/* should be safe, because otherwise if mbox were filled this callback is
* senseless */
mbox_try_put(&reg->mbox, &timeout_msg);
}
#endif

void gnrc_sock_create(gnrc_sock_reg_t *reg, gnrc_nettype_t type, uint32_t demux_ctx)
{
mbox_init(&reg->mbox, reg->mbox_queue, SOCK_MBOX_SIZE);
gnrc_netreg_entry_init_mbox(&reg->entry, demux_ctx, &reg->mbox);
gnrc_netreg_register(type, &reg->entry);
}

ssize_t gnrc_sock_recv(gnrc_sock_reg_t *reg, gnrc_pktsnip_t **pkt_out,
uint32_t timeout, sock_ip_ep_t *remote)
{
gnrc_pktsnip_t *pkt, *ip, *netif;
msg_t msg;

#ifdef MODULE_XTIMER
xtimer_t timeout_timer;

if ((timeout != SOCK_NO_TIMEOUT) && (timeout != 0)) {
timeout_timer.callback = _callback_put;
timeout_timer.arg = reg;
xtimer_set(&timeout_timer, timeout);
}
#endif
if (timeout != 0) {
mbox_get(&reg->mbox, &msg);
}
else {
if (!mbox_try_get(&reg->mbox, &msg)) {
return -EAGAIN;
}
}
#ifdef MODULE_XTIMER
xtimer_remove(&timeout_timer);
#endif
switch (msg.type) {
case GNRC_NETAPI_MSG_TYPE_RCV:
pkt = msg.content.ptr;
break;
#ifdef MODULE_XTIMER
case _TIMEOUT_MSG_TYPE:
if (msg.content.value == _TIMEOUT_MAGIC) {
return -ETIMEDOUT;
}
#endif
default:
return -EINTR;
}
/* TODO: discern NETTYPE from remote->family (set in caller), when IPv4
* was implemented */
ipv6_hdr_t *ipv6_hdr;
ip = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6);
assert((ip != NULL) && (ip->size >= 40));
ipv6_hdr = ip->data;
memcpy(&remote->addr, &ipv6_hdr->src, sizeof(ipv6_addr_t));
remote->family = AF_INET6;
netif = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_NETIF);
if (netif == NULL) {
remote->netif = SOCK_ADDR_ANY_NETIF;
}
else {
gnrc_netif_hdr_t *netif_hdr = netif->data;
/* TODO: use API in #5511 */
remote->netif = (uint16_t)netif_hdr->if_pid;
}
*pkt_out = pkt; /* set out parameter */
return 0;
}

ssize_t gnrc_sock_send(gnrc_pktsnip_t *payload, sock_ip_ep_t *local,
const sock_ip_ep_t *remote, uint8_t nh)
{
gnrc_pktsnip_t *pkt;
kernel_pid_t iface = KERNEL_PID_UNDEF;
gnrc_nettype_t type;
size_t payload_len = gnrc_pkt_len(payload);

if (local->family != remote->family) {
gnrc_pktbuf_release(payload);
return -EAFNOSUPPORT;
}
switch (local->family) {
#ifdef SOCK_HAS_IPV6
case AF_INET6: {
ipv6_hdr_t *hdr;
pkt = gnrc_ipv6_hdr_build(payload, (ipv6_addr_t *)&local->addr.ipv6,
(ipv6_addr_t *)&remote->addr.ipv6);
if (pkt == NULL) {
return -ENOMEM;
}
if (payload->type == GNRC_NETTYPE_UNDEF) {
payload->type = GNRC_NETTYPE_IPV6;
type = GNRC_NETTYPE_IPV6;
}
else {
type = payload->type;
}
hdr = pkt->data;
hdr->nh = nh;
break;
}
#endif
default:
(void)nh;
gnrc_pktbuf_release(payload);
return -EAFNOSUPPORT;
}
if (local->netif != SOCK_ADDR_ANY_NETIF) {
/* TODO: use API in #5511 */
iface = (kernel_pid_t)local->netif;
}
else if (remote->netif != SOCK_ADDR_ANY_NETIF) {
/* TODO: use API in #5511 */
iface = (kernel_pid_t)remote->netif;
}
if (iface != KERNEL_PID_UNDEF) {
gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
gnrc_netif_hdr_t *netif_hdr;

if (netif == NULL) {
gnrc_pktbuf_release(pkt);
return -ENOMEM;
}
netif_hdr = netif->data;
netif_hdr->if_pid = iface;
LL_PREPEND(pkt, netif);
}
#ifdef MODULE_GNRC_NETERR
gnrc_neterr_reg(pkt); /* no error should occur since pkt was created here */
#endif
if (!gnrc_netapi_dispatch_send(type, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) {
/* this should not happen, but just in case */
gnrc_pktbuf_release(pkt);
return -EBADMSG;
}
#ifdef MODULE_GNRC_NETERR
msg_t err_report;
err_report.type = 0;

while (err_report.type != GNRC_NETERR_MSG_TYPE) {
msg_try_receive(err_report);
if (err_report.type != GNRC_NETERR_MSG_TYPE) {
msg_try_send(err_report, sched_active_pid);
}
}
if (err_report.content.value != GNRC_NETERR_SUCCESS) {
return (int)(-err_report.content.value);
}
#endif
return payload_len;
}

/** @} */
99 changes: 99 additions & 0 deletions sys/net/gnrc/sock/include/gnrc_sock_internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright (C) 2016 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* 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.
*/

/**
* @defgroup net_gnrc_sock GNRC-specific implementation of the sock API
* @ingroup net_gnrc
* @brief Provides an implementation of the @ref net_sock by the
* @ref net_gnrc
*
* @{
*
* @file
* @brief GNRC-specific types and function definitions
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef GNRC_SOCK_INTERNAL_H_
#define GNRC_SOCK_INTERNAL_H_

#include <stdbool.h>
#include <stdint.h>
#include "mbox.h"
#include "net/af.h"
#include "net/gnrc.h"
#include "net/gnrc/netreg.h"
#include "net/sock/ip.h"

#include "sock_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Internal helper functions for GNRC
* @internal
* @{
*/
/**
* @brief Checks if address family is not supported
* @internal
*/
static inline bool gnrc_af_not_supported(int af)
{
/* TODO: add AF_INET support */
return (af != AF_INET6);
}

/**
* @brief Check if end point points to any address
* @internal
*/
static inline bool gnrc_ep_addr_any(const sock_ip_ep_t *ep)
{
assert(ep != NULL);
const uint8_t *p = (uint8_t *)&ep->addr;
for (uint8_t i = 0; i < sizeof(ep->addr); i++) {
if (p[i] != 0) {
return false;
}
}
return true;
}

/**
* @brief Create a sock internally
* @internal
*/
void gnrc_sock_create(gnrc_sock_reg_t *reg, gnrc_nettype_t type, uint32_t demux_ctx);

/**
* @brief Receive a packet internally
* @internal
*/
ssize_t gnrc_sock_recv(gnrc_sock_reg_t *reg, gnrc_pktsnip_t **pkt, uint32_t timeout,
sock_ip_ep_t *remote);

/**
* @brief Send a packet internally
* @internal
*/
ssize_t gnrc_sock_send(gnrc_pktsnip_t *payload, sock_ip_ep_t *local,
const sock_ip_ep_t *remote, uint8_t nh);
/**
* @}
*/


#ifdef __cplusplus
}
#endif

#endif /* GNRC_SOCK_INTERNAL_H_ */
/** @} */
Loading