This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP432E401Y: LWIP TCP Write function in c++ script

Part Number: MSP432E401Y

Hi,

I am trying to use a modified  TCP echo example to write data using TCP. My code is in c++ and need to use extern C on my interrupt handlers. I am getting a problem where the code is going into the default handler when trying to execute the tcp_write function. The tcp write function works fine in the call back functions but they dont work when I try to use it outside those functions(in the main loop). 

  • Hi

    That means the our TCP echo demo is works for you right?

  • Yes But I am having trouble sending through TCP, I can send fine from the listening PCB but am having issues with incoming PCB connection. I have the UART packet being processes and sent to TCP but it is not working.

    This function takes the data and sends it using TCP. I noticed sometimes the function writes and sometimes it does not. Also, it seems to transmit the packet  when I receive a packet from TCP. I also double checked that tpcb is the same pcb as the incoming connection. 

    void ModemManager::process(TransitPacket::PacketType type, vector<char> data, struct tcp_pcb *tpcb)
    {
    if (type == TransitPacket::ArestoModem)
    {

    char* modemptrdata = data.data();

    tcp_write(tpcb, modemptrdata, 10, 1);

    }

    }

    When I send data from the  accept callback function, it works. 

    err_t
    echo_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
    {
    err_t ret_err;

    LWIP_UNUSED_ARG(arg);
    LWIP_UNUSED_ARG(err);

    /* commonly observed practive to call tcp_setprio(), why? */
    tcp_setprio(newpcb, TCP_PRIO_MIN);

    es = (struct echo_state *)mem_malloc(sizeof(struct echo_state));
    if (es != NULL)
    {
    es->state = ES_ACCEPTED;
    es->pcb = newpcb;
    es->retries = 0;
    es->p = NULL;
    /* pass newly allocated es to our callbacks */
    tcp_arg(newpcb, es);
    tcp_recv(newpcb, echo_recv);
    tcp_err(newpcb, echo_error);
    tcp_sent(newpcb, echo_sent);

     char modemtest[3] = {'A' , 'C', 'K'};

     char *ptrdata = modemtest;
     tcp_write(newpcb, ptrdata,3, 1);
    ModemOn = true;
    // modem_pcb = newpcb;
    ret_err = ERR_OK;
    }
    else
    {
    ret_err = ERR_MEM;
    }
    return ret_err;
    }

  • Could you send me the files that one is original and the other one is what you modified? I can compared them to try to find some hint for you.

  • I found the answer. however now I am trying to place the callback functions within a class in C++, I am getting an error when setting up the callback functions now.

     I am getting the error 

    nonstandard form for taking the address of a member function

    argument of type "void (ModemManager::*)(void *, err_t)" is incompatible with parameter of type "tcp_err_fn"

    when calling tcp_recv(newpcb,echo_recv);

    Here is my code:

    err_t ModemManager::echo_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
    {
    err_t ret_err;
    static struct echo_state *es;
    LWIP_UNUSED_ARG(arg);
    LWIP_UNUSED_ARG(err);

    /* commonly observed practive to call tcp_setprio(), why? */
    tcp_setprio(newpcb, TCP_PRIO_MIN);
    // ModemOn = true;
    es = (struct echo_state *)mem_malloc(sizeof(struct echo_state));
    if (es != NULL)
    {
    es->state = ES_ACCEPTED;
    es->pcb = newpcb;
    es->retries = 0;
    es->p = NULL;
    /* pass newly allocated es to our callbacks */

    tcp_arg(newpcb, es);
    tcp_recv(newpcb,echo_recv);  // error here
    tcp_err(newpcb, echo_error); // error here
    tcp_sent(newpcb, echo_sent);// error here


    char modemtest[3] = {'A' , 'C', 'K'};
    char *ptrdata = modemtest;
    tcp_write(newpcb, ptrdata,3, 1);
    //ModemOn = true;

    ret_err = ERR_OK;
    }
    else
    {
    ret_err = ERR_MEM;
    }
    return ret_err;
    }

    class ModemManager : public Manager
    {
    public:
    ModemManager();
    virtual ~ModemManager();
    void process(TransitPacket::PacketType type, vector<char> data, struct tcp_pcb *tpcb);
    err_t echo_accept(void *arg, struct tcp_pcb *newpcb, err_t err);
    void echo_init(void);
    err_t echo_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err);
    void echo_error(void *arg, err_t err);
    err_t echo_sent(void *arg, struct tcp_pcb *tpcb, u16_t len);

    enum echo_states
    {
    ES_NONE = 0,
    ES_ACCEPTED,
    ES_RECEIVED,
    ES_CLOSING
    };

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

    };

  • That seems the input parameter's format is not match with the data format of the function ModemManagers' parameter.

  • Kirushigan Parathan said:
    however now I am trying to place the callback functions within a class in C++, I am getting an error when setting up the callback functions now.

    The StackOverflow answer Convert C++ function pointer to c function pointer contains:

    You can't pass a non-static member function pointer as an ordinary function pointer. They're not the same thing, and probably not even the same size.

    A non-static member function expects an explicit parameter to be passed for this. The StackOverflow answer has a suggestion to create a static wrapper function.

    Is the arg parameter in the callback functions a pointer to the ModemManager object?