Re: having trouble getting the echo client to work using TCP/uIP on K64F


Rohit Grover
 

Paul,

It is useful to work our way through the core BSD socket API in the context of Z-uIP.

Let's take connect(). Assuming that a net_context has been setup, connect() can be implemented using the snippet:

net_context_tcp_init(net_context, NULL /* bp */, NET_TCP_TYPE_CLIENT);
while ((status = net_context_get_connection_status(unicast)) != 0) {
fiber_sleep(SOME_SMALL_DURATION);
}

We're passing `bp' as NULL, but it seems un-necessary for net_context_init() to require a bp. This leads us to commit 61edc68c, by Jukka, where many of the APIs suddenly acquired an additional 'bp' parameter. In some cases, this led to code which I'm having trouble understanding. , I've attached the diff, but I'll highlight a snippet. Take the case of tcpip_poll_tcp(), which is responsible for sending out the initial SYN packet.

@@ -837,12 +837,18 @@ tcpip_poll_udp(struct uip_udp_conn *conn)
/*---------------------------------------------------------------------------*/
#if UIP_TCP
void
-tcpip_poll_tcp(struct uip_conn *conn)
+tcpip_poll_tcp(struct uip_conn *conn, struct net_buf *data_buf)
{
/* We are sending here the initial SYN */
struct net_buf *buf = ip_buf_get_tx(conn->appstate.state);
- uip_set_conn(buf) = conn;
- conn->buf = ip_buf_ref(buf);
+ uip_set_conn(data_buf) = conn;
+
+ /* The conn->buf will be freed after we have established the connection,
+ * sent the message and received an ack to it. This will happen in
+ * net_core.c:net_send().
+ */
+ conn->buf = ip_buf_ref(data_buf);
+
process_post_synch(&tcpip_process, TCP_POLL, conn, buf);
}

Here we see that we acquire a buf to send out a 'SYN' (refer to ip_buf_get_tx(...) above), but whereas previously we would associate it with the new connection and have its ref-count bumped, we now do those things for the 'data_buf' instead. This is a bit confusing. I don't see why the handling of the SYN buf needed to be changed.

Rohit.

-----Original Message-----
> From: Paul Sokolovsky [mailto:paul.sokolovsky(a)linaro.org]
> Sent: 26 August 2016 00:57
> To: Rohit Grover
> Cc: devel(a)lists.zephyrproject.org; Jukka Rissanen
> Subject: Re: having trouble getting the echo client to work using TCP/uIP on
> K64F
>
> On Fri, 26 Aug 2016 01:07:29 +0300
> Paul Sokolovsky <Paul.Sokolovsky(a)linaro.org> wrote:
>
> Some more info: Issues with IPv4/TCP can be seen building echo_server with
> microkernel - making a TCP connection in this case hard locks-up QEMU VM,
> not even pings work. Nothing special in the logging. However with
> nanokernel, everything works, and send (reply) path doesn't involve
> net_tx_fiber:
>
> Received packet 0x0010a4d0 len 7
> receive: tcp received 7 bytes data
> net: tcp_prepare_and_send (0010d27c): Packet output len 47
> net: net_driver_slip_send (0010d27c): Sending 47 bytes, application data 7
> bytes
>
>
>
> > On Mon, 22 Aug 2016 14:58:11 +0000
> > Rohit Grover <Rohit.Grover(a)arm.com> wrote:
> >
> > > With my recent changes, I
> > > manage to get the first packet bounce back successfully to the
> > > echo-client. Successive packets aren't getting processed on their
> > > way out from the client.
> >
> > I'm happy to report that I now see this too. Specifically, if using
> > net_context_get()+net_send() (implicit connection establishment), data
> > in first net_send() gets delivered (I see it in netcat), but not in
> > subsequent calls to net_send().
> >
> > I'm however interested to emulate standard socket API paradigm, where
> > you get all the standard and important calls like connect(), listen(),
> > etc. For this, I explicitly call net_context_tcp_init(ctx, NULL,
> > NET_TCP_TYPE_CLIENT) to emulate connect(). As netbuf is NULL in this
> > call, only SYN/ACK handshake happens (with retries, just as you
> > describe), and then first call
> > net_send() doesn't send anything on wire. With logging it looks like:
> >
> > >>> s.connect(("192.0.2.1", 8083))
> > resolved: 192.0.2.1
> > net: net_driver_slip_send (001349e0): Sending 40 bytes, application
> > data 0 bytes net: net_rx_fiber (001363e0): Received buf 0012c600
> > ret=0
> > >>> net: net_rx_fiber (001363e0): Received buf 0012d0f0
> > net: net_rx_fiber (001363e0): Received buf 0012b598
> > net: net_driver_slip_send (001363e0): Sending 40 bytes, application
> > data 0 bytes
> >
> > >>> s.send("GET / HTTP/1.0\r\n")
> > net: net_send (001349e0): context 0012dfa0 buf 00129a38 status 0
> > net: net_tx_fiber (00135fe0): Sending (buf 00129a38, len 56) to IP
> > stack 0
> > >>>
> >
> > So, the difference is clear: SYN/ACK stuff goes to
> > net_driver_slip_send(), but real app data get stuck in net_tx_fiber().
> >
> > I apply all your 3 patches, and they don't help.
> >
> >
> > >
> > > I find that uip_process() isn't getting called on successive
> > > packets. It gets called for the first packet due to some
> > > retransmission timer. The recently made change to eventhandler() in
> > > tcpip.c (https://gerrit.zephyrproject.org/r/#/c/4050/) makes things
> > > worse because the code meant to refresh certain periodic timers gets
> > > skipped.
> > >
> > > These issues seem to arise from uIP. I would appreciate some help
> > > from people who ported uIP to zephyr. I believe the problems will
> > > surface if someone tries a TCP/IPV4 stream.
> > >
> > > rohit
> >
>
>
>
> --
> Best Regards,
> Paul
>
> Linaro.org | Open source software for ARM SoCs Follow Linaro:
> http://www.facebook.com/pages/Linaro
> http://twitter.com/#!/linaroorg - http://www.linaro.org/linaro-blog

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

Join devel@lists.zephyrproject.org to automatically receive all group messages.