int udp_init(struct udp_context *ctx) { struct net_context *udp_ctx = { 0 }; struct net_context *mcast_ctx = { 0 }; struct sockaddr_in6 my_addr = { 0 }; struct sockaddr_in6 my_mcast_addr = { 0 }; int rc; k_sem_init(&ctx->rx_sem, 0, UINT_MAX); net_ipaddr_copy(&my_mcast_addr.sin6_addr, &mcast_addr); my_mcast_addr.sin6_family = AF_INET6; net_ipaddr_copy(&my_addr.sin6_addr, &server_addr); my_addr.sin6_family = AF_INET6; my_addr.sin6_port = htons(SERVER_PORT); rc = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &udp_ctx); if (rc < 0) { printk("Cannot get network context for IPv6 UDP (%d)", rc); return -EIO; } rc = net_context_bind(udp_ctx, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in6)); if (rc < 0) { printk("Cannot bind IPv6 UDP port %d (%d)", SERVER_PORT, rc); goto error; } rc = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &mcast_ctx); if (rc < 0) { printk("Cannot get receiving IPv6 mcast (%d)", rc); goto error; } rc = net_context_bind(mcast_ctx, (struct sockaddr *)&my_mcast_addr, sizeof(struct sockaddr_in6)); if (rc < 0) { printk("Cannot get bind IPv6 mcast (%d)", rc); goto error; } ctx->rx_pkt = NULL; ctx->remaining = 0; ctx->net_ctx = udp_ctx; rc = net_context_recv(ctx->net_ctx, udp_received, K_NO_WAIT, ctx); if (rc != 0) { return -EIO; } return 0; error: net_context_put(udp_ctx); return -EINVAL; }
/*---------------------------------------------------------------------------*/ int coap_context_listen(coap_context_t *coap_ctx, uip_ipaddr_t *peer_addr, uint16_t peer_port) { if(coap_ctx == NULL || coap_ctx->is_used == 0) { return 0; } #ifdef NETSTACK_CONF_WITH_IPV6 memcpy(&coap_ctx->addr.in6_addr, peer_addr, sizeof(coap_ctx->addr.in6_addr)); coap_ctx->addr.family = AF_INET6; #else memcpy(&coap_ctx->addr.in_addr, peer_addr, sizeof(coap_ctx->addr.in_addr)); coap_ctx->addr.family = AF_INET; #endif coap_ctx->port = peer_port; coap_ctx->net_ctx = net_context_get(IPPROTO_UDP, (const struct net_addr *)&coap_ctx->addr, coap_ctx->port, (const struct net_addr *)&coap_ctx->my_addr, coap_ctx->my_port); if (!coap_ctx->net_ctx) { PRINTF("%s: Cannot get network context\n", __FUNCTION__); return 0; } return 1; }
/*---------------------------------------------------------------------------*/ int coap_context_connect(coap_context_t *coap_ctx, uip_ipaddr_t *addr, uint16_t port) { if(coap_ctx == NULL || coap_ctx->is_used == 0) { return 0; } #ifdef NETSTACK_CONF_WITH_IPV6 memcpy(&coap_ctx->addr.in6_addr, addr, sizeof(coap_ctx->addr.in6_addr)); coap_ctx->addr.family = AF_INET6; #else memcpy(&coap_ctx->addr.in_addr, addr, sizeof(coap_ctx->addr.in_addr)); coap_ctx->addr.family = AF_INET; #endif coap_ctx->port = port; coap_ctx->net_ctx = net_context_get(IPPROTO_UDP, (const struct net_addr *)&coap_ctx->addr, coap_ctx->port, (const struct net_addr *)&coap_ctx->my_addr, coap_ctx->my_port); if (!coap_ctx->net_ctx) { PRINTF("%s: Cannot get network context\n", __FUNCTION__); return 0; } PRINTF("coap-context: normal connect to ["); PRINT6ADDR(addr); PRINTF("]:%u\n", port); return 1; }
static inline bool get_context(struct net_context **recv, struct net_context **mcast_recv) { static struct net_addr mcast_addr; static struct net_addr any_addr; static struct net_addr my_addr; static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; static const struct in6_addr in6addr_mcast = MCAST_IPADDR; static struct in6_addr in6addr_my = MY_IPADDR; mcast_addr.in6_addr = in6addr_mcast; mcast_addr.family = AF_INET6; any_addr.in6_addr = in6addr_any; any_addr.family = AF_INET6; my_addr.in6_addr = in6addr_my; my_addr.family = AF_INET6; *recv = net_context_get(IPPROTO_UDP, &any_addr, 0, &my_addr, UDP_PORT); if (!*recv) { printk("%s: Cannot get network context\n", __func__); return NULL; } *mcast_recv = net_context_get(IPPROTO_UDP, &any_addr, 0, &mcast_addr, UDP_PORT); if (!*mcast_recv) { printk("%s: Cannot get receiving mcast network context\n", __func__); return false; } return true; }
static bool get_local_address(struct sol_network_link_addr *addr) { struct net_context *empty_ctx; struct net_addr local_addr = { 0 }; empty_ctx = net_context_get(IPPROTO_UDP, NULL, 0, &local_addr, 0); SOL_NULL_CHECK(empty_ctx, false); addr->family = SOL_NETWORK_FAMILY_INET6; addr->port = 0; memcpy(&addr->addr.in6, &local_addr.in6_addr, sizeof(addr->addr.in6)); net_context_put(empty_ctx); return true; }
static struct net_context *get_context(const struct net_addr *remote, uint16_t remote_port, const struct net_addr *local, uint16_t local_port) { struct net_context *ctx; ctx = net_context_get(IPPROTO_UDP, remote, remote_port, local, local_port); if (!ctx) { PRINT("%s: Cannot get network context\n", __func__); return NULL; } return ctx; }
/*---------------------------------------------------------------------------*/ int coap_context_connect(coap_context_t *coap_ctx, uip_ipaddr_t *addr, uint16_t port) { session_t session; if(coap_ctx == NULL || coap_ctx->is_used == 0) { return 0; } #ifdef NETSTACK_CONF_WITH_IPV6 memcpy(&coap_ctx->addr.in6_addr, addr, sizeof(coap_ctx->addr.in6_addr)); coap_ctx->addr.family = AF_INET6; #else memcpy(&coap_ctx->addr.in_addr, addr, sizeof(coap_ctx->addr.in_addr)); coap_ctx->addr.family = AF_INET; #endif coap_ctx->port = port; coap_ctx->net_ctx = net_context_get(IPPROTO_UDP, (const struct net_addr *)&coap_ctx->addr, coap_ctx->port, (const struct net_addr *)&coap_ctx->my_addr, coap_ctx->my_port); if (!coap_ctx->net_ctx) { PRINTF("%s: Cannot get network context\n", __FUNCTION__); return 0; } uip_ipaddr_copy(&session.addr.ipaddr, addr); session.addr.port = UIP_HTONS(port); session.size = sizeof(session.addr); session.ifindex = 1; coap_ctx->status = STATUS_CONNECTING; PRINTF("coap-context: DTLS CONNECT TO ["); PRINT6ADDR(addr); PRINTF("]:%u\n", uip_ntohs(port)); if(dtls_connect(coap_ctx->dtls_context, &session) >= 0) { return 1; } /* Failed to initiate connection */ coap_ctx->status = STATUS_ALERT; return 0; }
int tcp_init(struct net_context **ctx) { static struct in_addr server_addr = SERVER_IP_ADDR; static struct in_addr client_addr = CLIENT_IP_ADDR; static struct net_addr server; static struct net_addr client; server.in_addr = server_addr; server.family = AF_INET; client.in_addr = client_addr; client.family = AF_INET; *ctx = net_context_get(IPPROTO_TCP, &server, SERVER_MQTT_PORT, &client, CLIENT_MQTT_PORT); if (*ctx == NULL) { printk("%s: Unable to get network context\n", __func__); return -EINVAL; } return 0; }
static void telnet_setup_server(struct net_context **ctx, sa_family_t family, struct sockaddr *addr, socklen_t addrlen) { if (net_context_get(family, SOCK_STREAM, IPPROTO_TCP, ctx)) { SYS_LOG_ERR("No context available"); goto error; } if (net_context_bind(*ctx, addr, addrlen)) { SYS_LOG_ERR("Cannot bind on family AF_INET%s", family == AF_INET ? "" : "6"); goto error; } if (net_context_listen(*ctx, 0)) { SYS_LOG_ERR("Cannot listen on"); goto error; } if (net_context_accept(*ctx, telnet_accept, 0, NULL)) { SYS_LOG_ERR("Cannot accept"); goto error; } SYS_LOG_DBG("Telnet console enabled on AF_INET%s", family == AF_INET ? "" : "6"); return; error: SYS_LOG_ERR("Unable to start telnet on AF_INET%s", family == AF_INET ? "" : "6"); if (*ctx) { net_context_put(*ctx); *ctx = NULL; } }
static int tcp_connect(struct http_client_ctx *ctx) { socklen_t addrlen = sizeof(struct sockaddr_in); int ret; if (ctx->tcp.ctx && net_context_is_used(ctx->tcp.ctx) && net_context_get_state(ctx->tcp.ctx) == NET_CONTEXT_CONNECTED) { /* If we are already connected, then just return */ return -EALREADY; } if (ctx->tcp.remote.family == AF_INET6) { addrlen = sizeof(struct sockaddr_in6); /* If we are reconnecting, then make sure the source port * is re-calculated so that the peer will not get confused * which connection the connection is related to. * This was seen in Linux which dropped packets when the same * source port was for a new connection after the old connection * was terminated. */ net_sin6(&ctx->tcp.local)->sin6_port = 0; } else { net_sin(&ctx->tcp.local)->sin_port = 0; } ret = get_local_addr(ctx); if (ret < 0) { NET_DBG("Cannot get local address (%d)", ret); return ret; } ret = net_context_get(ctx->tcp.remote.family, SOCK_STREAM, IPPROTO_TCP, &ctx->tcp.ctx); if (ret) { NET_DBG("Get context error (%d)", ret); return ret; } net_context_setup_pools(ctx->tcp.ctx, ctx->tx_slab, ctx->data_pool); ret = net_context_bind(ctx->tcp.ctx, &ctx->tcp.local, addrlen); if (ret) { NET_DBG("Bind error (%d)", ret); goto out; } ret = net_context_connect(ctx->tcp.ctx, &ctx->tcp.remote, addrlen, NULL, ctx->tcp.timeout, NULL); if (ret) { NET_DBG("Connect error (%d)", ret); goto out; } return net_context_recv(ctx->tcp.ctx, ctx->tcp.recv_cb, K_NO_WAIT, ctx); out: net_context_put(ctx->tcp.ctx); ctx->tcp.ctx = NULL; return ret; }
static inline bool get_context(struct net_context **unicast, struct net_context **multicast) { static struct net_addr mcast_addr; static struct net_addr peer_addr; static struct net_addr any_addr; static struct net_addr my_addr; #if defined(CONFIG_NETWORKING_WITH_IPV6) static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; static const struct in6_addr in6addr_mcast = MCAST_IPADDR; mcast_addr.in6_addr = in6addr_mcast; mcast_addr.family = AF_INET6; peer_addr.in6_addr = in6addr_peer; peer_addr.family = AF_INET6; any_addr.in6_addr = in6addr_any; any_addr.family = AF_INET6; my_addr.in6_addr = in6addr_my; my_addr.family = AF_INET6; #else static const struct in_addr in4addr_any = { { { 0 } } }; static struct in_addr in4addr_my = MY_IPADDR; static struct in_addr in4addr_mcast = MCAST_IPADDR; static struct in_addr in4addr_peer = PEER_IPADDR; mcast_addr.in_addr = in4addr_mcast; mcast_addr.family = AF_INET; peer_addr.in_addr = in4addr_peer; peer_addr.family = AF_INET; any_addr.in_addr = in4addr_any; any_addr.family = AF_INET; my_addr.in_addr = in4addr_my; my_addr.family = AF_INET; #endif *unicast = net_context_get(IPPROTO_UDP, &peer_addr, PEER_PORT, &my_addr, MY_PORT); if (!*unicast) { PRINT("%s: Cannot get sending network context\n", __func__); return false; } *multicast = net_context_get(IPPROTO_UDP, &mcast_addr, PEER_PORT, &my_addr, MY_PORT); if (!*multicast) { PRINT("%s: Cannot get mcast sending network context\n", __func__); return false; } return true; }
static inline bool get_context(struct net_context **udp_recv6, struct net_context **tcp_recv6, struct net_context **mcast_recv6) { int ret; struct sockaddr_in6 mcast_addr6 = { 0 }; struct sockaddr_in6 my_addr6 = { 0 }; net_ipaddr_copy(&mcast_addr6.sin6_addr, &in6addr_mcast); mcast_addr6.sin6_family = AF_INET6; my_addr6.sin6_family = AF_INET6; my_addr6.sin6_port = htons(MY_PORT); ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, udp_recv6); if (ret < 0) { printk("Cannot get network context for IPv6 UDP (%d)", ret); return false; } ret = net_context_bind(*udp_recv6, (struct sockaddr *)&my_addr6, sizeof(struct sockaddr_in6)); if (ret < 0) { printk("Cannot bind IPv6 UDP port %d (%d)", ntohs(my_addr6.sin6_port), ret); return false; } ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, mcast_recv6); if (ret < 0) { printk("Cannot get receiving IPv6 mcast " "network context (%d)", ret); return false; } ret = net_context_bind(*mcast_recv6, (struct sockaddr *)&mcast_addr6, sizeof(struct sockaddr_in6)); if (ret < 0) { printk("Cannot bind IPv6 mcast (%d)", ret); return false; } ret = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP, tcp_recv6); if (ret < 0) { printk("Cannot get network context for IPv6 TCP (%d)", ret); return false; } net_context_setup_pools(*tcp_recv6, tx_tcp_pool, data_tcp_pool); ret = net_context_bind(*tcp_recv6, (struct sockaddr *)&my_addr6, sizeof(struct sockaddr_in6)); if (ret < 0) { printk("Cannot bind IPv6 TCP port %d (%d)", ntohs(my_addr6.sin6_port), ret); return false; } ret = net_context_listen(*tcp_recv6, 0); if (ret < 0) { printk("Cannot listen IPv6 TCP (%d)", ret); return false; } return true; }
static inline bool get_context(struct net_context **udp_recv4, struct net_context **udp_recv6, struct net_context **tcp_recv4, struct net_context **tcp_recv6) { int ret; #if defined(CONFIG_NET_IPV6) struct sockaddr_in6 my_addr6 = { 0 }; #endif #if defined(CONFIG_NET_IPV4) struct sockaddr_in my_addr4 = { 0 }; #endif #if defined(CONFIG_NET_IPV6) #if !NET_BIND_ANY_ADDR net_ipaddr_copy(&my_addr6.sin6_addr, &in6addr_my); #endif my_addr6.sin6_family = AF_INET6; my_addr6.sin6_port = htons(MY_PORT); #endif #if defined(CONFIG_NET_IPV4) #if !NET_BIND_ANY_ADDR net_ipaddr_copy(&my_addr4.sin_addr, &in4addr_my); #endif my_addr4.sin_family = AF_INET; my_addr4.sin_port = htons(MY_PORT); #endif #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_UDP) ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, udp_recv6); if (ret < 0) { NET_ERR("Cannot get network context for IPv6 UDP (%d)", ret); return false; } net_context_setup_pools(*udp_recv6, tx_udp_slab, data_udp_pool); ret = net_context_bind(*udp_recv6, (struct sockaddr *)&my_addr6, sizeof(struct sockaddr_in6)); if (ret < 0) { NET_ERR("Cannot bind IPv6 UDP port %d (%d)", ntohs(my_addr6.sin6_port), ret); return false; } #endif #if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_UDP) ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP, udp_recv4); if (ret < 0) { NET_ERR("Cannot get network context for IPv4 UDP (%d)", ret); return false; } net_context_setup_pools(*udp_recv4, tx_udp_slab, data_udp_pool); ret = net_context_bind(*udp_recv4, (struct sockaddr *)&my_addr4, sizeof(struct sockaddr_in)); if (ret < 0) { NET_ERR("Cannot bind IPv4 UDP port %d (%d)", ntohs(my_addr4.sin_port), ret); return false; } #endif #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_TCP) if (tcp_recv6) { ret = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP, tcp_recv6); if (ret < 0) { NET_ERR("Cannot get network context " "for IPv6 TCP (%d)", ret); return false; } net_context_setup_pools(*tcp_recv6, tx_tcp_slab, data_tcp_pool); ret = net_context_bind(*tcp_recv6, (struct sockaddr *)&my_addr6, sizeof(struct sockaddr_in6)); if (ret < 0) { NET_ERR("Cannot bind IPv6 TCP port %d (%d)", ntohs(my_addr6.sin6_port), ret); return false; } ret = net_context_listen(*tcp_recv6, 0); if (ret < 0) { NET_ERR("Cannot listen IPv6 TCP (%d)", ret); return false; } } #endif #if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_TCP) if (tcp_recv4) { ret = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP, tcp_recv4); if (ret < 0) { NET_ERR("Cannot get network context for IPv4 TCP"); return false; } net_context_setup_pools(*tcp_recv4, tx_tcp_slab, data_tcp_pool); ret = net_context_bind(*tcp_recv4, (struct sockaddr *)&my_addr4, sizeof(struct sockaddr_in)); if (ret < 0) { NET_ERR("Cannot bind IPv4 TCP port %d", ntohs(my_addr4.sin_port)); return false; } ret = net_context_listen(*tcp_recv4, 0); if (ret < 0) { NET_ERR("Cannot listen IPv4 TCP"); return false; } } #endif return true; }