void net_context_put(struct net_context *context) { if (!context) { return; } nano_sem_take(&contexts_lock, TICKS_UNLIMITED); if (context->tuple.ip_proto == IPPROTO_UDP) { if (net_context_get_receiver_registered(context)) { struct simple_udp_connection *udp = net_context_get_udp_connection(context); simple_udp_unregister(udp); } } #ifdef CONFIG_NETWORKING_WITH_TCP if (context->tcp_type == NET_TCP_TYPE_SERVER) { tcp_unlisten(UIP_HTONS(context->tuple.local_port), &context->tcp); } #endif memset(&context->tuple, 0, sizeof(context->tuple)); memset(&context->udp, 0, sizeof(context->udp)); context->receiver_registered = false; context_sem_give(&contexts_lock); }
/* Internal function to send network data to uIP stack */ static int check_and_send_packet(struct net_buf *buf) { struct net_tuple *tuple; struct simple_udp_connection *udp; int ret = 0; if (!netdev.drv) { return -EINVAL; } tuple = net_context_get_tuple(buf->context); if (!tuple) { return -EINVAL; } switch (tuple->ip_proto) { case IPPROTO_UDP: udp = net_context_get_udp_connection(buf->context); if (!net_context_get_receiver_registered(buf->context)) { ret = simple_udp_register(udp, tuple->local_port, #ifdef CONFIG_NETWORKING_WITH_IPV6 (uip_ip6addr_t *)&tuple->remote_addr->in6_addr, #else (uip_ip4addr_t *)&tuple->remote_addr->in_addr, #endif tuple->remote_port, udp_packet_reply, buf); if (!ret) { NET_DBG("UDP connection creation failed\n"); ret = -ENOENT; break; } net_context_set_receiver_registered(buf->context); } simple_udp_send(buf, udp, buf->data, buf->len); ret = 0; break; case IPPROTO_TCP: NET_DBG("TCP not yet supported\n"); ret = -EINVAL; break; case IPPROTO_ICMPV6: NET_DBG("ICMPv6 not yet supported\n"); ret = -EINVAL; break; } return ret; }
/* Called by application when it wants to receive network data */ struct net_buf *net_receive(struct net_context *context) { struct nano_fifo *rx_queue = net_context_get_queue(context); struct net_tuple *tuple; int ret = 0; tuple = net_context_get_tuple(context); if (!tuple) { return NULL; } switch (tuple->ip_proto) { case IPPROTO_UDP: if (!net_context_get_receiver_registered(context)) { struct simple_udp_connection *udp = net_context_get_udp_connection(context); ret = simple_udp_register(udp, tuple->local_port, #ifdef CONFIG_NETWORKING_WITH_IPV6 (uip_ip6addr_t *)&tuple->remote_addr->in6_addr, #else (uip_ip4addr_t *)&tuple->remote_addr->in_addr, #endif tuple->remote_port, udp_packet_receive, context); if (!ret) { NET_DBG("UDP connection listener failed\n"); ret = -ENOENT; break; } } net_context_set_receiver_registered(context); ret = 0; break; case IPPROTO_TCP: NET_DBG("TCP not yet supported\n"); ret = -EINVAL; break; case IPPROTO_ICMPV6: NET_DBG("ICMPv6 not yet supported\n"); ret = -EINVAL; break; } return nano_fifo_get(rx_queue); }