Ip object delete error with two interfaces

Hello,

 

I got an error sometimes when I disable all my IP stack while trying to delete the IP object. The error code is NX_SOCKETS_BOUND.

I don't understand why I got this, i disable and delete all the ip services first though...

 

void net_stop_all()
{
net_wifi_close();
net_http_server_stop();
net_dhcp_server_stop();
net_dhcp_client_stop();
net_ip_stop();

}

 

void net_wifi_close()
{
if(wifi_on)
{
do
{
result = g_sf_wifi0.p_api->close(g_sf_wifi0.p_ctrl);
tx_thread_sleep (50);
}
while(result != SSP_SUCCESS && result != SSP_ERR_NOT_OPEN);
wifi_on = 0;
}
}

 

void net_http_server_stop()
{
if(http_server_initialized)
{
result = nx_http_server_stop(&g_http_server0);
tx_thread_sleep (50);
result = nx_http_server_delete(&g_http_server0);
tx_thread_sleep (50);
memset(&g_http_server0, 0, sizeof(g_http_server0));
http_server_initialized = 0;
}
}

void net_dhcp_server_stop()
{
if(dhcp_server_initialized)
{
result = nx_dhcp_server_stop(&g_dhcp_server0);
tx_thread_sleep (50);
result = nx_dhcp_server_delete(&g_dhcp_server0);
tx_thread_sleep (50);
memset(&g_dhcp_server0, 0, sizeof(g_dhcp_server0));
//result = g_wifi_stack.dhcpServerStop(g_wifi_stack_ctrl);
dhcp_server_initialized = 0;
}

}

void net_dhcp_client_stop()
{
if(wdhcp_client_on)
{
/* Start the DHCP Client on the secondary interface. */
result = nx_dhcp_interface_stop(&g_dhcp_client1, 0);
tx_thread_sleep (50);
result = nx_dhcp_interface_disable(&g_dhcp_client1, 0);
tx_thread_sleep (50);
wdhcp_client_on = 0;
}
if(edhcp_client_on)
{
result = nx_dhcp_interface_stop(&g_dhcp_client1, 1);
tx_thread_sleep (50);
result = nx_dhcp_interface_disable(&g_dhcp_client1, 1);
tx_thread_sleep (50);
edhcp_client_on = 0;
}
if(dhcp_client_initialized)
{
result = nx_dhcp_stop(&g_dhcp_client1);
tx_thread_sleep (50);
result = nx_dhcp_delete(&g_dhcp_client1);
tx_thread_sleep (50);
memset(&g_dhcp_client1, 0, sizeof(g_dhcp_client1));
dhcp_client_initialized = 0;
}
}

 

void net_ip_stop()
{
if(ip_initialized)
{
do{
result = nx_ip_delete(&g_ip1);
tx_thread_sleep (50);
memset(&g_ip1, 0, sizeof(g_ip1));
}
while(result != 0);
result = nx_packet_pool_delete(&g_packet_pool0);
tx_thread_sleep (50);
memset(&g_packet_pool0, 0, sizeof(g_packet_pool0));
ip_initialized = 0;
}
}

 

Sorry for the bad code format, i don't know how to make the code look better here :s

 

thanks in advance for any tips :)

 

Have a nice day,

 

Clément.

  • Clement,

    First, I assume you checked all the return status calls for successful result. Assuming no errors, all the NetX application "stop()" APIs unbind or release the port unless an error occurs and the service aborts.

    Note that if the DHCP Client is running on at least one other interface, nx_dhcp_interface_stop will not unbind the socket port. Looking at how you toggle dhcp_client_initialized , edhcp_client_initialized , and wdhcp_client_initialized that seems like the most likely culprit.

    Janet
  • In reply to JanetC:

    Hello Janet,

    Indeed, I checked in debug mode the value of all the results. And no errors except when I delete the IP object. I highly suspect it have something to do with the dhcp client running on both interface that the problem occurs, your suggestion is likely the problem ! :) Can you help me again by explaining me how I can successfully unbind all the socket port before stoping both interfaces ?

    Thanks a lot for your answer and for your future answer !

    Have a nice day !

    Clément.
  • In reply to Clément:

    Clement

    I took another look at the nx_ip_delete code and I see now that it is not actually 'ports bound' that is the problem, it is the sockets not yet deleted. NetX requires that you delete the sockets before deleting the IP instance.

    If that is a problem, we could discuss whether you actually need to delete the IP instance at all. Anyway, try deleting all the sockets and see if the problem goes away.

    Janet
  • In reply to JanetC:

    Hi Janet,

    Just how in the world do I delete these sockets ?
    I'm sorry, I just don't know what netx function to use here...

    Please help,

    Thank you !
  • In reply to Clément:

    Clement,

    You just need to call two API. nx_dhcp_delete() calls nx_udp_socket_delete, and nx_http_server_delete() calls nx_tcp_socket_delete(). My apologies for omitting that detail. Now it should work fine.

    Janet
  • In reply to JanetC:

    Janet,

    Thanks a lot for your understanding and explanation ! :)
    So if I do something like that it should works ?

    result = nx_http_server_stop(&g_http_server0);
    tx_thread_sleep (10);
    result = nx_tcp_socket_delete(&g_http_server0.nx_http_server_socket);
    tx_thread_sleep (10);
    result = nx_http_server_delete(&g_http_server0);
    tx_thread_sleep (10);
    memset(&g_http_server0, 0, sizeof(g_http_server0));
    http_server_initialized = 0;

    result = nx_dhcp_stop(&g_dhcp_client1);
    tx_thread_sleep (10);
    result = nx_udp_socket_delete(&g_dhcp_client1.nx_dhcp_socket);
    tx_thread_sleep (10);
    result = nx_dhcp_delete(&g_dhcp_client1);
    tx_thread_sleep (10);
    memset(&g_dhcp_client1, 0, sizeof(g_dhcp_client1));
    dhcp_client_initialized = 0;

    Is it okay like that ?
    Is there some socket to close with the dhcp server too ?

    Thanks again,

    CLément.

     

    EDIT :

    Tried this code, with also a socket delete for udp dhcp server socket but same problem...

  • In reply to Clément:

    Clement,

    Omit the nx_udp_socket_delete and nx_tcp_socket_delete calls before calling the delete the DHCP and HTTP functions, respectively. The nx_dhcp_delete and nx_http_server_delete will call them for you.

    And yes, nx_dhcp_server_delete() will delete the UDP socket of the DHCP server.

    Regards,
    Janet
  • In reply to JanetC:

    Janet,

    So you're telling me that it's not the problem in my code in that case... I call nx_dhcp_delete, nx_dhcp_server_delete, and nx_http_server_delete respectively since the begining of the problem...
    So my error at Ip_delete should come from somewhere else in that case isn't it ?

    Do you have any other ideas ?

    Thanks,

    CLément.
  • In reply to Clément:

    Clement,

    Has your application created any other sockets or NetX application instances?

    If not, the nx_udp_socket_delete() and nx_tcp_socket_delete() calls will fail if the socket is still bound.

    If you have access to NetX source code, add it to your project and step into the nx_udp_socket_delete() and nx_tcp_socket_delete() to make sure they succeed. Unfortunately the nx_dhcp_delete, nx_dhcp_server_delete() and nx_http_server_delete() do not check status return on deleting the socket.

    NX_SOCKETS_BOUND is only returned by nx_ip_delete() and only if there are still sockets not deleted.

    Janet
  • In reply to JanetC:

    Hi Janet,

    I just forgot I had one custom http client I use...

    I'll try to check if the bug remain when I disable this http client.

    I'll keep in touch with you about that.

    Thanks a lot,

    Clément.
  • In reply to Clément:

    Hi Clement

    I checked with our development team and the reason for not checking the status return on the socket delete calls in nx_dhcp_delete(), etc, is that these functions first unbind the socket and clean up suspensions etc before deleting them. Anyway, if there are still sockets existing, the code can check for them directly by checking the values of :

    ip_ptr -> nx_ip_tcp_created_sockets_ptr -> nx_tcp_socket_name

    and

    ip_ptr -> nx_ip_udp_created_sockets_ptr -> nx_udp_socket_name

    So hopefully the custom http client socket is the hold up and deleting it will resolve your issue.

    Regards,
    Janet
  • In reply to JanetC:

    Hi Janet,

    Thanks for your explanations !
    Unfortunately, the custom http Client wasn't the culprit. But with your advice, I will be able to check if the opened socket is an UDP or a TCP one. It's better than nothing !

    I'll keep you in touch about that !

    Clément.
  • In reply to Clément:

    Hi I'm back,

    Here is the tcp socket I suspect is the problem. But don't know what it can be :

    uint32_t get_request_netx(ULONG host, uint32_t port, char *message, char *buffer_rcv) {
    NX_PACKET *pkt;
    UINT status = 0;
    ULONG bytes_rcv = 0;
    ULONG ip_status;
    static NX_TCP_SOCKET sock;
    static int have_connection = 0;

    /* Ensure the IP instance has been initialized. */
    status = nx_ip_interface_status_check(&g_ip1, 1, NX_IP_INITIALIZE_DONE, &ip_status, 100);//ip_connector
    if(status != 0)
    status = nx_ip_interface_status_check(&g_ip1, 0, NX_IP_INITIALIZE_DONE, &ip_status, 100);//ip_connector

    if (have_connection == 0 && status == 0) {
    // Create TCP Socket
    status = nx_tcp_socket_create(&g_ip1, &sock, "_Get_Request",
    NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 4096,
    NX_NULL, NX_NULL);//ip_connector
    if (status != NX_SUCCESS)
    {
    tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
    return 'A';
    }


    // Socket bind
    status = nx_tcp_client_socket_bind(&sock, NX_ANY_PORT, NX_WAIT_FOREVER);
    if (status != NX_SUCCESS)
    {
    status = nx_tcp_socket_delete(&sock);
    tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
    return 'B';
    }

    // Socket connect
    status = nx_tcp_client_socket_connect(&sock, host, (UINT)port, 100);
    if (status == NX_SUCCESS)
    {
    have_connection = 1;
    }
    else
    {
    nx_tcp_client_socket_unbind(&sock);
    nx_tcp_socket_delete(&sock);
    tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
    return 'C';
    }
    }

    if (have_connection != 0)
    {
    status = nx_packet_allocate(&g_packet_pool0, &pkt, NX_TCP_PACKET, NX_WAIT_FOREVER);
    if(status != NX_SUCCESS)
    {
    nx_tcp_socket_disconnect(&sock, 200);
    nx_tcp_client_socket_unbind(&sock);
    nx_tcp_socket_delete(&sock);
    tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
    return 'G';
    }

    status = nx_packet_data_append(pkt, message, strlen(message), &g_packet_pool0, NX_WAIT_FOREVER);

    // Send data request
    status = nx_tcp_socket_send(&sock, pkt, 400);
    if (status == NX_SUCCESS)
    {
    NX_PACKET *pkt_rcv;
    char *p = buffer_rcv;

    status = nx_tcp_socket_receive(&sock, &pkt_rcv, 200);
    if (status == NX_SUCCESS)
    {
    status = nx_packet_data_retrieve(pkt_rcv, p, &bytes_rcv);
    if (status == NX_SUCCESS)
    {
    // ok!... or not
    }
    else
    {

    status = nx_tcp_socket_delete(&sock);
    tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
    return 'F';
    }

    }
    else
    {
    status = nx_tcp_socket_delete(&sock);
    tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
    return 'E';
    }
    status = nx_packet_release(pkt_rcv);
    }
    else
    {
    tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
    return 'D';
    }
    }
    else
    {
    nx_packet_release(pkt);
    nx_tcp_socket_disconnect(&sock, 200);
    nx_tcp_client_socket_unbind(&sock);
    tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
    return 'D';
    }

    status = nx_tcp_socket_disconnect(&sock, 100);
    status = nx_tcp_client_socket_unbind(&sock);
    status = nx_tcp_socket_delete(&sock);
    have_connection = 0;

    tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
    return (uint32_t)bytes_rcv;
    }

    For me all the function should be executed in one block so the tcp socket should always be closed and deleted each time I try to reload all my IP configuration.

    Is there something wrong in the function maybe ?

    Thanks a lot,

    Clément.
  • In reply to Clément:

    I take it the nx_ip_delete is still complaining of NX_SOCKETS_BOUND still.  I copied the text above into a source code editor and found a few things missing/wrong.  I tagged my comments with 'jlc'.  Hopefully the formatting is preserved so it will be easier to read the code. 

    Try this and see if it resolves the problem.  I will run a simple program using this code and see if I run into problems with nx_ip_delete. 

    Janet

    clement.txt
    uint32_t get_request_netx(ULONG host, uint32_t port, char *message, char *buffer_rcv) 
    {
    NX_PACKET *pkt;
    UINT status = 0;
    ULONG bytes_rcv = 0;
    ULONG ip_status;
    static NX_TCP_SOCKET sock;
    static int have_connection = 0;
    
    /* Ensure the IP instance has been initialized. */
    status = nx_ip_interface_status_check(&g_ip1, 1, NX_IP_INITIALIZE_DONE, &ip_status, 100);//ip_connector
    if(status != 0)
        status = nx_ip_interface_status_check(&g_ip1, 0, NX_IP_INITIALIZE_DONE, &ip_status, 100);//ip_connector
    
    if (have_connection == 0 && status == 0) 
    {
        // Create TCP Socket
        status = nx_tcp_socket_create(&g_ip1, &sock, "_Get_Request",
        NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 4096,  NX_NULL, NX_NULL);//ip_connector
        if (status != NX_SUCCESS)
        {
            tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
            return 'A';
        }
    
        // Socket bind
        status = nx_tcp_client_socket_bind(&sock, NX_ANY_PORT, NX_WAIT_FOREVER);
        if (status != NX_SUCCESS)
        {
            status = nx_tcp_socket_delete(&sock);
            tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
            return 'B';
        }
    
        // Socket connect
        status = nx_tcp_client_socket_connect(&sock, host, (UINT)port, 100);
        if (status == NX_SUCCESS)
        {
            have_connection = 1;
        }
        else
        {
            nx_tcp_client_socket_unbind(&sock);
            nx_tcp_socket_delete(&sock);
            tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
            return 'C';
        }
    }
    
    if (have_connection != 0)
    {
        status = nx_packet_allocate(&g_packet_pool0, &pkt, NX_TCP_PACKET, NX_WAIT_FOREVER);
        if(status != NX_SUCCESS)
        {
            nx_tcp_socket_disconnect(&sock, 200);
            nx_tcp_client_socket_unbind(&sock);
            nx_tcp_socket_delete(&sock);
            tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
            return 'G';
        }
    
        status = nx_packet_data_append(pkt, message, strlen(message), &g_packet_pool0, NX_WAIT_FOREVER);
        
        // Send data request
        status = nx_tcp_socket_send(&sock, pkt, 400);
        if (status == NX_SUCCESS)
        {
            NX_PACKET *pkt_rcv;
            char *p = buffer_rcv;
            
            status = nx_tcp_socket_receive(&sock, &pkt_rcv, 200);
            if (status == NX_SUCCESS)
            {
                status = nx_packet_data_retrieve(pkt_rcv, p, &bytes_rcv);
                if (status == NX_SUCCESS)
                {
                    // ok!... or not
                }
                else
                {       
                    // jlc missing unbind!
                    // jlc missing packet releaes
                    status = nx_tcp_socket_delete(&sock);
                    tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
                    return 'F';
                }
            }
            else
            {
                // jlc missing unbind!
                status = nx_tcp_socket_delete(&sock);
                tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
                return 'E';
            }
    
            // jlc do not release packet after a successful send. NetX/ NetX Duo does that automatically
            status = nx_packet_release(pkt_rcv);
        }
        else
        {
            // jlc missing packet release (unsuccessful socket send)
            tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
            return 'D';
        }
    
        
    }
    else
    {
        nx_packet_release(pkt); // jlc packet has not been allocated yet. no need to release
        nx_tcp_socket_disconnect(&sock, 200);
        nx_tcp_client_socket_unbind(&sock);
        tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
        return 'D';
    }
    
    status = nx_tcp_socket_disconnect(&sock, 100);
    status = nx_tcp_client_socket_unbind(&sock);
    status = nx_tcp_socket_delete(&sock);
    have_connection = 0;
    
    tx_event_flags_set(&eguard_event_flags, SEND_CLOUD_COMPLETE, TX_OR);
    return (uint32_t)bytes_rcv;
    
    }
    

  • In reply to JanetC:

    HI again

    I found a few other bugs in the code above. I will finish testing it and give you the details tomorrow.

    Janet