lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] lwip-users Digest, Vol 195, Issue 15


From: Lee
Subject: Re: [lwip-users] lwip-users Digest, Vol 195, Issue 15
Date: Thu, 14 Nov 2019 14:49:55 -0500

Hello I hope I am replying to this correctly or some one will tell me how.

Regarding the TCP client development,
I wrote both a server and client in Processing where I could rapidly develop them. I did it to help our development and test of an embedded product and the PC and Android applications that connect to and control our product through TCP socket. My two Processing creations allowed us to test each independently.

For client See my github at: https://github.com/ForrestErickson/Processing-ClientWithReconnect This is the server: https://github.com/ForrestErickson/Processing-ServerComeAndGoes

You will have to read the code to see the keyboard commands to change server status, but only if you want to.
I hope this is of use and feel free to explain any confusion you have.

If Processing does not intimidate you (it's super easy) I advise you start by running on one Windows PC both the server and client and play with them. Run them in any order and close in any order.

(Forrest) Lee Erickson
P.S. If I have one supper power it would be called novel spelling.

-----Original Message----- From: address@hidden
Sent: Thursday, November 14, 2019 12:00 PM
To: address@hidden
Subject: lwip-users Digest, Vol 195, Issue 15

Send lwip-users mailing list submissions to
address@hidden

To subscribe or unsubscribe via the World Wide Web, visit
https://lists.nongnu.org/mailman/listinfo/lwip-users
or, via email, send a message with subject or body 'help' to
address@hidden

You can reach the person managing the list at
address@hidden

When replying, please edit your Subject line so it is more specific
than "Re: Contents of lwip-users digest..."


Today's Topics:

  1. Minimal RAW TCP Client (Jamie)


----------------------------------------------------------------------

Message: 1
Date: Wed, 13 Nov 2019 15:19:10 -0700 (MST)
From: Jamie <address@hidden>
To: address@hidden
Subject: [lwip-users] Minimal RAW TCP Client
Message-ID: <address@hidden>
Content-Type: text/plain; charset=us-ascii

G'day,

I'm looking to build a minimal RAW TCP client on a SAME70 (ATSAME70Q21) MCU.
Thankfully there is already a port for lwIP on the SAME70, which allows for
the basic TCP Echo to be run on the SAME70 Xplained evaluation board (which
I have done with no problem).

The problem I'm having at the moment is in modifying the TCP Echo example
code in the following ways:

1. The lwIP TCP needs to be a client, connecting to an external TCP server.
The example code is based on lwIP being a TCP server, so I'm struggling a
bit with replacing/removing the server-based code.

2. Simplifying the code. At the moment I only need to read data from the TCP
client, I don't need any tcp_send() functionality. Additionally, the entire
application on the SAME70 is predicated on this TCP connection, so a
blocking while loop until the connection is established is acceptable
(again, trying to keep it as simple as possible).

Here <https://www.avrfreaks.net/forum/ethernet-socket-communication-same70>
is a link to a forum post where I got the TCP Echo example to work on the
SAME70 evaluation board. This is the code I'm currently trying to modify.
This is what I have so far (including some minimal commentary):

#include "sam_comms.h"

#if LWIP_TCP

static struct tcp_pcb *sam_tcp_pcb;

enum sam_tcp_states
{
ES_NONE = 0,
ES_CONNECTED,
ES_RECEIVED,
ES_CLOSING
};

struct sam_tcp_state
{
u8_t state;
u8_t retries;
struct tcp_pcb *pcb;
/* pbuf (chain) to recycle */
struct pbuf *p;
};

void sam_tcp_init(void)
{
 sam_tcp_pcb = tcp_new();
 if (sam_tcp_pcb != NULL)
 {
   err_t err;
   struct sam_tcp_state *es;

   //No error handling for the time being
   tcp_err(sam_tcp_pcb, NULL);
   tcp_recv(sam_tcp_pcb, sam_tcp_recv);

   //No polling for the time being
   tcp_poll(sam_tcp_pcb, NULL, 0);

   //I don't believe I need to bind?
   //err = tcp_bind(sam_tcp_pcb, IP_ADDR_ANY, 9999);

   //I'm thinking that somewhere here I should have a while or do loop, to
keep trying
   //to connect until a connection is established?
   err = tcp_connect(sam_tcp_pcb, IP_ADDR_ANY, 9999, sam_tcp_connect);
   if (err != ERR_OK)
   {
       //Connection not successful, close the pcb
   tcp_close(sam_tcp_pcb);
}
 }
 else
 {
   /* abort? output diagnostic? */
 }
}

err_t sam_tcp_connect(void *arg, struct tcp_pcb *connectedpcb, err_t err)
{
err_t ret_err;
struct sam_tcp_state *es;

es = (struct sam_tcp_state *)mem_malloc(sizeof(struct sam_tcp_state));
if (es != NULL)
{
es->state = ES_CONNECTED;
es->pcb = connectedpcb;
es->retries = 0;
es->p = NULL;
}
else
{
ret_err = ERR_MEM;
}
return ret_err;
}

err_t sam_tcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t
err)
{
 struct sam_tcp_state *es;
 err_t ret_err;

 LWIP_ASSERT("arg != NULL",arg != NULL);
 es = (struct sam_tcp_state *)arg;
 if (p == NULL)
 {
   /* remote host closed connection */
   es->state = ES_CLOSING;
   if(es->p == NULL)
   {
      /* we're done sending, close it */
      //sam_tcp_close(tpcb, es);
   }
   else
   {
     /* we're not done yet */
       //The below is commented out as this isn't an echo program
       //sam_tcp_send(tpcb, es);
   }
   ret_err = ERR_OK;
 }
 else if(err != ERR_OK)
 {
   /* cleanup, for unknown reason */
   if (p != NULL)
   {
     es->p = NULL;
     pbuf_free(p);
   }
   ret_err = err;
 }
 else if(es->state == ES_CONNECTED)
 {
   /* first data chunk in p->payload */
   es->state = ES_RECEIVED;
   /* store reference to incoming pbuf (chain) */
   es->p = p;
   /* install send completion notifier */
   //The below is commented out as this isn't an echo program
   //tcp_sent(tpcb, echo_sent);
   //sam_tcp_send(tpcb, es);
   ret_err = ERR_OK;
 }
 else if (es->state == ES_RECEIVED)
 {
   /* read some more data */
   if(es->p == NULL)
   {
     es->p = p;
     //The below is commented out as this isn't an echo program
     //tcp_sent(tpcb, echo_sent);
     //sam_tcp_send(tpcb, es);
   }
   else
   {
     struct pbuf *ptr;

     /* chain pbufs to the end of what we recv'ed previously  */
     ptr = es->p;
     pbuf_chain(ptr,p);
   }
   ret_err = ERR_OK;
 }
 else if(es->state == ES_CLOSING)
 {
   /* odd case, remote side closing twice, trash data */
   tcp_recved(tpcb, p->tot_len);
   es->p = NULL;
   pbuf_free(p);
   ret_err = ERR_OK;
 }
 else
 {
   /* unknown es->state, trash data  */
   tcp_recved(tpcb, p->tot_len);
   es->p = NULL;
   pbuf_free(p);
   ret_err = ERR_OK;
 }
 if (!strncmp(p->payload, "Quit", 4))
 {
 //sam_tcp_close(tpcb, es);
 } else
 {
 //
 }
 return ret_err;
}
#endif /* LWIP_TCP */

Am I on the right track? How would I go about adding a loop to continue
trying to connect to the TCP server? In terms of global macros, I've only
changed LWIP_SOCKET to 0 (disable the sockets API) and have left NO_SYS as
0. Is this correct? Are there any other macros I need to change for a RAW
TCP client implementation?

Any input, guidance or example code would be very much appreciated!

Thanks!



--
Sent from: http://lwip.100.n7.nabble.com/lwip-users-f3.html



------------------------------

Subject: Digest Footer

_______________________________________________
lwip-users mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/lwip-users

------------------------------

End of lwip-users Digest, Vol 195, Issue 15
*******************************************



reply via email to

[Prev in Thread] Current Thread [Next in Thread]