/* 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); }
static struct net_buf *ip_buf_get(enum ip_buf_type type, struct net_context *context) #endif { struct net_buf *buf; struct net_tuple *tuple; uint16_t reserve = 0; tuple = net_context_get_tuple(context); if (!tuple) { return NULL; } switch (tuple->ip_proto) { case IPPROTO_UDP: reserve = UIP_IPUDPH_LEN + UIP_LLH_LEN; break; case IPPROTO_TCP: reserve = UIP_IPTCPH_LEN + UIP_LLH_LEN; break; case IPPROTO_ICMPV6: reserve = UIP_IPICMPH_LEN + UIP_LLH_LEN; break; } #ifdef DEBUG_IP_BUFS buf = ip_buf_get_reserve_debug(type, reserve, caller, line); #else buf = ip_buf_get_reserve(type, reserve); #endif if (!buf) { return buf; } ip_buf_context(buf) = context; return buf; }
/* Application wants to send a reply */ int net_reply(struct net_context *context, struct net_buf *buf) { struct net_tuple *tuple; struct uip_udp_conn *udp; int ret = 0; if (!context || !buf) { return -EINVAL; } tuple = net_context_get_tuple(context); if (!tuple) { return -ENOENT; } switch (tuple->ip_proto) { case IPPROTO_UDP: udp = uip_udp_conn(buf); if (!udp) { NET_ERR("UDP connection missing\n"); return -ESRCH; } ret = udp_prepare_and_send(context, buf); break; case IPPROTO_TCP: NET_DBG("TCP not yet supported\n"); return -EINVAL; break; case IPPROTO_ICMPV6: NET_DBG("ICMPv6 not yet supported\n"); return -EINVAL; break; } return ret; }