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.

CC3120: sl_Select not triggering interrupt for second socket

Part Number: CC3120

Hi,


I am getting one trouble with the Trigger mode. For tcp socket, i am calling select, it works fine with one socket. but when we open multiple socket, then interrupt fails for later opened sockets.

referring to www.ti.com/.../swru455e.pdf  

I tried one fix which worked for me. before calling the first sl_select, enabling the rxset variable fixed the issue, but I got trouble if the connection is closed by either side. then it again disables all the interrupts. It seems that there is some bug in interrupt handling for sockets. especially with the sl_select function.

for(int i=0;i<16;i++)
SL_SOCKET_FD_SET(i, &rxSet);

The sl_select function is meant to help multiple sockets but it fails to reset or re-enable the trigger interrupt event. 

I checked the interrupt pin, when I open and close multiple sockets, it shows signal; but no signal after closing any of the opened socket.

It will be very kind of you if you can help me with this as soon as possible as the product is stuck because of this issue.

With Regards.

Ravdeep

  • In the sl_select, it seems the AsyncRsp.Status == 0 changes when socket is closed.
    For the moment, i am testing by opening connection and closing on the other side(My desktop PC connected to cc3120 wirelessly via internet). which generates an receive error=0 which is socket closed by other side(PC).
    After that i try to open connection on other listening socket, but no interrupt is received.
  • Hi Ravdeep,

    Do you apply the sl_Listen command to your TCP server socket (assuming that's what you meant by "other listening socket")?

    Jesu

  • If you haven't already, you should refer to section 5.7.2 in the programmer's guide. It goes into great detail about trigger mode.

    www.ti.com/.../swru455e.pdf

    Jesu
  • Hi jesu,
    Yes. With polling i am able to work normally with 5 tcp and 5 udp sockets
  • Even, mutiple accepts on same socket works perfectly fine with polling
  • Hi Ravdeep,

    What do you mean by receive error? Is this when you call sl_Recv for data reception? Also what interrupt pin are you referring to? It is my understanding that a trigger mode socket executes the SimpleLinkSocketTriggerEventHandler on interrupt.

    Jesu
  • Yes, when there is close connection by other side and there is trigger event, then the recv function returns status 0 which means other side closed connection.

    Yes the interrupt i am refering to is the simplelinksockertriggereventhandler.

    the pin is 15 HOSTINTR
  • Hi Ravdeep,

    If receive function returns 0 that is not an error. The only thing I can think regarding the interrupt not working is that you are not creating your sockets properly for trigger mode. Could you share a code snippet for how you are setting up your sockets as well as your event handler?

    Jesu
  • Hi Jesu,

    Here is the TCP client code, which is simpler to test then server, since server uses accept and accept needs localSD which causes further problems. Lets first verify the problem in this code, probably that will help to fix others.

    void SimpleLinkSocketTriggerEventHandler(SlSockTriggerEvent_t *pSlTriggerEvent)

    {

       switch(pSlTriggerEvent->Event)

       {

       case SL_SOCKET_TRIGGER_EVENT_SELECT:

       {

           LOG_MESSAGE("Notify User SL_SOCKET_TRIGGER_EVENT_SELECT \n\r");

           gTriggerModeEventArrived = TRUE;

             break;

       }

       default:

           break;

       }

    }

    static _i32 BsdTcpClient_Trigger_Mode()

    {

    _i16 Status,Sd,LocalSd;

    _u16 nfds;

    SlSockAddrIn_t LocalAddr,Addr;

    SlSockNonblocking_t BlockingOption;

    BlockingOption.NonBlockingEnabled = 1;

    SlTimeval_t timeVal = {0};

    SlFdSet_t rxSet;

    SlFdSet_t wxSet;

    LocalAddr.sin_family = SL_AF_INET;

    LocalAddr.sin_port = sl_Htons(5003);

    LocalAddr.sin_addr.s_addr = sl_Htonl(SL_IPV4_VAL(10,100,75,93));

    timeVal.tv_sec =  0;

    timeVal.tv_usec = 0;

     //Open TCP server socket

    Sd = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);

    if( Sd < 0 )

       {

           CLI_Write(" [TCP ] Create socket Error \n\r");

           ASSERT_ON_ERROR(Sd);

       }

    Status =

    sl_SetSockOpt(Sd,SL_SOL_SOCKET,SL_SO_NONBLOCKING,(_u8*)&BlockingOption,sizeof(BlockingOption));

    if( Status )

    {

           CLI_Write(" [TCP ] SO_NONBLOCKING socket Error \n\r");

    }

    Status = sl_Connect(Sd, ( SlSockAddr_t *)&LocalAddr, sizeof(SlSockAddr_t));

    if( Status )

    {

           CLI_Write(" [TCP ] Connect %d\n\r",Status);

    }

     nfds = Sd + 1;

     SL_SOCKET_FD_ZERO( &rxSet );

     SL_SOCKET_FD_ZERO( &wxSet );

     SL_SOCKET_FD_SET( Sd,& rxSet );

     SL_SOCKET_FD_SET( Sd,& wxSet );

     Status = sl_Select( nfds, &rxSet, &wxSet, NULL, &timeVal );

     if( Status <0 )

     {

     CLI_Write(" [TCP Server] Select socket Error Status %d \n\r",Status);

     }

    while(1)

    {

       while(gTriggerModeEventArrived!=TRUE)

       {

         _SlNonOsMainLoopTask();

       }

       gTriggerModeEventArrived=FALSE;

     SL_SOCKET_FD_ZERO( &rxSet );

     SL_SOCKET_FD_ZERO( &wxSet );

     SL_SOCKET_FD_SET( Sd,& rxSet );

     SL_SOCKET_FD_SET( Sd,& wxSet );

     Status = sl_Select( nfds, &rxSet, &wxSet, NULL, &timeVal );

     if (SL_SOCKET_FD_ISSET(Sd, &wxSet))

     {

       Status = sl_Recv(Sd, &(uBuf.BsdBuf[0]), 5, 0);

       if( Status < 0)

       {

         if (Status != -11)

       {

           sl_Close(Sd);

           CLI_Write(" [TCP Server] Data recv Error \n\r");

           ASSERT_ON_ERROR(Status);   //TCP_RECV_ERROR

       }

       }

       CLI_Write(" [TCP Server] %2X %2X %2X %2X %2X\n",uBuf.BsdBuf[0],uBuf.BsdBuf[1],uBuf.BsdBuf[2],uBuf.BsdBuf[3],uBuf.BsdBuf[4]);

     }

     SL_SOCKET_FD_ZERO( &rxSet );

     SL_SOCKET_FD_ZERO( &wxSet );

     SL_SOCKET_FD_SET( Sd,& rxSet );

     SL_SOCKET_FD_SET( Sd,& wxSet );

     Status = sl_Select( nfds, &rxSet, &wxSet, NULL, &timeVal );

    }

    return 0;

    }

    int32_t HandleUserApplication()

    {

    // Trigger mode user code

    -----

    BsdTcpClient_Trigger_Mode();            //called at end of the HandleUserApplication function of Trigger mode example code.

    }

    The debugged out traces

    Ő*************************************

              CC3220 Trigger Mode Application      

    *************************************************

    ŐDevice started in Station role

    Adding event 0, buffWrite: 1, buffSize: 1

    MainApp: State = 0, Event = 0

    func: StartConnection:1997

    Ő [Event] STA connected to AP - BSSID:04:18:d6:74:88:60, SSID:Paradox-Wifi

    Adding event 1, buffWrite: 2, buffSize: 1

    MainApp: State = 1, Event = 1

    func: HandleWaitForIp:2294

    Ő[NETAPP EVENT] IP Acquired: IP=10.100.75.95 , Gateway=10.100.75.1

    Adding event 2, buffWrite: 3, buffSize: 1

    MainApp: State = 2, Event = 2

    func: CheckLanConnection:2329

    Adding event 7, buffWrite: 4, buffSize: 1

    MainApp: State = 3, Event = 7

    func: HandleUserApplication:2217

    Ő[App] User Application Started

    ŐDHCP is ON

    IP 10.100.75.95

    MASK 255.255.255.0

    GW 10.100.75.1

    DNS 10.100.10.249

    Ő [TCP ] Connect -114

    Ő [TCP Server] Select socket Error Status -11

    ŐNotify User SL_SOCKET_TRIGGER_EVENT_SELECT

    Ő [TCP Server]  0  0  0  0  0

    It opens the connect socket but no data is received. if a sends more data, then no more interrupt comes.

    With accept, i am able to receive data but when i close Sd, then no longer i get any interrupt.

    With Regards

    Ravdeep

  • Hi, i found that there is some mismatch in programming guide, the sl_select parameters are given wrong. for connect it has to be wxset while to receive it has to be rxset.

    Further, coming back to major issue. Problem with next socket opened.

    I modified the code as follows.

    static _i32 BsdTcpClient_Trigger_Mode(_u16 Port)
    {
    _i16 sock[20]={0};
    _i16 Status,Sd,Sd1;
    _u16 nfds;
    SlSockAddrIn_t LocalAddr,Addr;
    SlSockNonblocking_t BlockingOption;
    BlockingOption.NonBlockingEnabled = 1;

    SlTimeval_t timeVal = {0};
    SlFdSet_t rxSet;
    SlFdSet_t wxSet;
    SlFdSet_t exSet;

    LocalAddr.sin_family = SL_AF_INET;
    LocalAddr.sin_port = sl_Htons(5003);
    LocalAddr.sin_addr.s_addr = sl_Htonl(SL_IPV4_VAL(10,100,75,106));
    timeVal.tv_sec = 0;
    timeVal.tv_usec = 0;

    int index = 0;
    //Open TCP server socket
    repeat:
    sock[index] = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);
    CLI_Write("sock[index] = %d\n\r",sock[index]);
    if( Sd < 0 )
    {
    CLI_Write(" [TCP ] Create socket Error \n\r");
    ASSERT_ON_ERROR(Sd);
    }

    Status =
    sl_SetSockOpt(sock[index],SL_SOL_SOCKET,SL_SO_NONBLOCKING,(_u8*)&BlockingOption,sizeof(BlockingOption));
    if( Status )
    {

    CLI_Write(" [TCP ] SO_NONBLOCKING socket Error \n\r");
    }


    Status = sl_Connect(sock[index], ( SlSockAddr_t *)&LocalAddr, sizeof(SlSockAddr_t));
    if( Status )
    {

    CLI_Write(" [TCP ] Connect %d\n\r",Status);
    }

    nfds = sock[index] + 1;
    SL_SOCKET_FD_ZERO( &rxSet );
    SL_SOCKET_FD_ZERO( &wxSet );
    SL_SOCKET_FD_ZERO( &exSet );
    SL_SOCKET_FD_SET( sock[index],&rxSet );
    SL_SOCKET_FD_SET( sock[index],&wxSet );
    SL_SOCKET_FD_SET( sock[index],&exSet );
    Status = sl_Select( nfds, NULL, &wxSet, NULL, &timeVal );
    if( Status <0 )
    {
    CLI_Write(" [TCP Server] Select socket Error Status %d \n\r",Status);
    }
    int firsttime=0;
    while(1)
    {

    while(gTriggerModeEventArrived!=TRUE)
    {
    ProcessEvents();
    }
    gTriggerModeEventArrived=FALSE;

    SL_SOCKET_FD_ZERO( &rxSet );
    SL_SOCKET_FD_ZERO( &wxSet );
    SL_SOCKET_FD_ZERO( &exSet );

    Status = sl_Select( nfds, &rxSet, &wxSet, &exSet, &timeVal );
    if( Status <0 )
    {
    CLI_Write(" [TCP Server] Select socket Error Status %d \n\r",Status);
    }

    Status = sl_Recv(sock[index], &(uBuf.BsdBuf[0]), 5, 0);
    if( Status < 0)
    {
    if (Status != -11)
    {

    sl_Close(sock[index]);
    CLI_Write(" [TCP Server] Data recv Error \n\r");
    ASSERT_ON_ERROR(Status); //TCP_RECV_ERROR
    }
    }
    CLI_Write(" [TCP Server] %2X %2X %2X %2X %2X\n",uBuf.BsdBuf[0],uBuf.BsdBuf[1],uBuf.BsdBuf[2],uBuf.BsdBuf[3],uBuf.BsdBuf[4]);
    if( Status == 0 && firsttime == 1)
    {

    index++;
    goto repeat;
    }

    firsttime = 1;
    SL_SOCKET_FD_ZERO( &rxSet );
    SL_SOCKET_FD_ZERO( &wxSet );
    SL_SOCKET_FD_ZERO( &exSet );
    SL_SOCKET_FD_SET( sock[index],&rxSet );
    SL_SOCKET_FD_SET( sock[index],&wxSet );
    SL_SOCKET_FD_SET( sock[index],&exSet );
    Status = sl_Select( nfds, &rxSet, NULL, &exSet, &timeVal );
    if( Status <0 )
    {
    CLI_Write(" [TCP Server] Select socket Error Status %d \n\r",Status);
    }

    Status = sl_Select( nfds, &rxSet, NULL, &exSet, &timeVal );
    if( Status <0 )
    {
    CLI_Write(" [TCP Server] Select socket Error Status %d \n\r",Status);
    }
    }
    }




    This code, opens first socket, successfully recv data, works perfectly fine if local side is closed and new socket is opened. but fails if remote side closes connection and new socket is opened, there is no interrupt on new socket connect.

    Then i tested to open more sockets without closing, so i was recieving interrupt but the trigger mode is inconsistent. somtimes it stops receiving interrupt on 5th socket, sometimes 2nd.

    This is my major issue here.

    Please help me out.
    Thank you
    With Regards
    Ravdeep.

  • Hi Ravdeep,

    After the event triggers and you call sl_Select you should check sd against rxSet before calling sl_Recv (using FD_ISSET). The point of this is to only call sl_Recv if the select function acknowledged that there is traffic on the specified sockets. For more info refer to page 95 www.ti.com/.../swru455e.pdf or the RunSelectTraffic function for the trigger mode example.

    Jesu
  • Hi Jesu,

    Yes, i used that, but there was no difference since i was checked the value of rxset and exset. I just removed that because i was just wondering that which one of the 3 Sets is triggered.
    I verified with ISSET also.
    I also tested by clearing the SL_SOCKET_FD_CLR( sock[index],&rxSet );.

    The only problem i could see is that it does not allow me to call sl_Close when i receive trigger event after sl_Recv returns 0. if i call Sl_close, then i receive no more interrupt.

    Since i tried to open 16 sockets without closing, i faced the problem of no interrupt sometimes after 5th socket, sometimes after 12th.
    Could you please verify that the code i mentioned above is working on your setup. I used a tool "Packet Sender" which listens to incoming connections. whenever there is any tcp connection, it opens a window and i type something, for which i receive data on CLI.
    The problem comes when remote side close the connection and there are more than 1 connection.

    With Regards
    Ravdeep

  • Hi Ravdeep,

    Apologies for the delay. I cannot think of reasons why you're interrupt may be failing. I will try my best to test that today and get back to you.

    Jesu
  • Thank you Jesu.
    Will be waiting for your response.

    With Regards
    Ravdeep
  • Hi Ravdeep,

    Forgive me for the delays I have still not had a chance to run these test. Been having trouble making the modifications on my end while dealing with other tasks. Have you made any progress since we lost spoke?

    Jesu
  • Hi Jesu,

    I could not go any further because it is kind of blocker for me. I tried different combinations but not fully succesful.

    Looking forward to hear from you soon.
    With Regards
    Ravdeep
  • Hi Jesu,

    Also do i need to close the socket if remote side closes the connection.
    Can you tell me what to do when i receive Status = 0 for sl_recv()

    what should be the parameters of sl_select for status of sl_recv() = 0 and for status of sl_recv() > 0?

    Because when i open new socket i do not get interrupt.

    With Regards
    Ravdeep
  • Hi Ravdeep,

    You should only be calling sl_Recv after you have checked you have data for a particular socket using SL_SOCKET_FD_ISSET. If SL_SOCKET_FD_ISSET for a particular socket comes back true, then you call sl_Recv for the socket that you know you have data for. After all that, if sl_Recv is <= 0, you can assume the remote side closed the socket and then you should proceed to close it on your end.

    sl_Select is only used to select which sockets you want to have monitored and enables trigger mode if setup correctly.

    If you do not put the socket on the watch list using rxSet, you will not get an interrupt when you send something to that socket.

    Jesu