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.

Concerto NDK , socket open/close management between shared tasks

Hi,

 

I would like to verify that I do socket close properly if its shared between multiple tasks. Please advice because after closing the socket I can't reopen it because I think that it was not properly closed. Please note if I set in comment " fdShare" in other tasks for the socket , I can reopen the socket (perform communication recovery as required). When  fdShare is used in otger tasks and socket is closed by main task, I'm fail reopen it.

 

 My main task:

void tcpAppWorker(UArg arg0, UArg arg1)

{

    Int nbytes;

    Bool flag = TRUE;

    Error_Block eb;

    char* ptrReceivedBuffer = ((CBoardSubSystem*)g_pBoard)->ptrAppLANReceivedBuffer;

    Bool ComEstflag = TRUE;

 

    fdOpenSession(TaskSelf());

 

    UARTprintf("Start TCP App work task\n");

 

    tcpAppWorkerclientfd = (SOCKET)arg0;

 

 

    ((CBoardSubSystem*)g_pBoard)->Appclientfd = tcpAppWorkerclientfd;

 

       if(ComEstflag == TRUE)

       {

              ComEstflag = FALSE;

              //Infornm C28 on  communication establish

              char temp[4];

 

              temp[0] = NEW_LPU_CLIENT_CONNECTED;

              if((arg1 > CIENT_ID_BLUBOX) && (arg1 < CIENT_LOG))

              {

                     temp[1] = arg1;//CIENT_ID_BLUBOX =1,     CLIENT_MAIN_APP =2, CIENT_RandD =3, CIENT_SERVICE =4, CIENT_LOG =5

                     ((IPCInterface *)(g_pBoard->m_pIPCInterfacePtr))->IPCSendDataFromLPU(APP_M3_C28_CMD, PRI_NORMAL, 3, temp);

              }

       }

     

    /* Make sure Error_Block is initialized */

    Error_init(&eb);

    /* Loop while we receive data */

    while (flag) {

        nbytes = recv(tcpAppWorkerclientfd, (char *)ptrReceivedBuffer, BBTCPPACKETSIZE, 0);

        //UARTprintf("TCP App new msg\n");

        UARTprintf("TCP_App rec NewMsg: SocketN = 0x%x, Size = %d\n", tcpAppWorkerclientfd, nbytes);

              UARTprintf(" DS,");

 

              for (int i = 0; i < 10; i++)

              {

                     UARTprintf("%d,", ptrReceivedBuffer[i]);

              }

 

              UARTprintf("DE\n");

        if (nbytes > 0) {

              // Handle the App Command

              ((CBoardSubSystem*)g_pBoard)->PCMessageHandle(nbytes);

 

                     }

        else {

              // Error

             fdClose(tcpAppWorkerclientfd);

             flag = FALSE;

             tcpAppWorkerclientfd=INVALID_SOCKET;

             ((CBoardSubSystem*)g_pBoard)->Appclientfd = tcpAppWorkerclientfd;

        }

    }

 

 

    fdCloseSession(TaskSelf());

    UARTprintf("Close tcp App worker\n");

    /*

     *  Since deleteTerminatedTasks is set in the cfg file,

     *  the Task will be deleted when the idle task runs.

     */

    Task_exit();

}

 

 

 

Other tasks which use thi s socket, say for transmitting messages, I’ve added fdshare(0 function, although I’m not sure that correctly.

 

Void IPC_TaskReceiveLPUMsg(UArg arg0, UArg arg1)

{

       Uint16 tempbuff[MAX_LOG_CMD_DATA_SIZE];

       Uint16 loop;

       static Bool bNewAppSocketRegister = false;

    // Init the IPC, M3 <-> C28x communication (for LPU messages)

       IPC_init_1();

 

       // Open the file session

       //fdOpenSession(TaskSelf());

 

       System_printf("CIPCInterface (M3):: before while, after IPC_init_1() \n");

 

    // Check the WD timer "0" interrupt

    while (1)

    {

       // receive a message

       myRcvMessage = IPC_recMsgQ1 ();

      

 

       if(bNewAppSocketRegister == true)

       {

              if(((CBoardSubSystem*)g_pBoard)->Appclientfd==INVALID_SOCKET)

              {

                     fdCloseSession(TaskSelf());

                     bNewAppSocketRegister = false;

              }

       }

 

       switch (myRcvMessage->MsgType)

       {

              case SUBSYSTEM_CMD_BLUEBOX:

                     // Post the BlueBox Semaphore

                           Semaphore_post(SEM_BB_WaitOnDataReceived);

                     break;

              case APP_C28_M3_CMD:

              {

                     if((myRcvMessage->Data[1].IntData== NEW_LPU_CLIENT_CONNECTED) /*&& (myRcvMessage->Data[2].IntData== CLIENT_MAIN_APP)*/)

                           {

                           if(((CBoardSubSystem*)g_pBoard)->Appclientfd!=INVALID_SOCKET)

                           {

                                  bNewAppSocketRegister = true;

                                  fdOpenSession(TaskSelf());

                                  fdShare((SOCKET)((CBoardSubSystem*)g_pBoard)->Appclientfd);

                           }

                           }

                     //Set the same for Log client

              }

              break;

              case CLIENT_MAIN_APP:

              {

            

 

                     int i,j;

                           //copy data

                           for(i=0,j=0; i<99 && j<MAX_MSG_DATA_SHORT_SIZE; i++, j++)

                           {

                                  tempDataBuff[i++]= myRcvMessage->Data[j].ShortData.Byte1;

                                  if(i>99)

                                         break;

                                  tempDataBuff[i]= myRcvMessage->Data[j].ShortData.Byte2;

                           }

 

                           ((CBoardSubSystem*)g_pBoard)->LPUAppSendData(tempDataBuff[1], tempDataBuff[0], &tempDataBuff[1]);

 

 

              }

              break;

             

                           //break;

              default:

                     break;

       }

 

       //Free the received message

       IPC_freeMsg (myRcvMessage);

    }

 

 

}

 

 

Void TaskTransmitLogToLPU(UArg arg0, UArg arg1)

{

       static Bool bNewAppSocketRegister = false;

 

       while(1)

       {

              Semaphore_pend(SEM_TRANSMIT_LOG_TO_LPU_VIA_QUE, BIOS_WAIT_FOREVER);

 

              pTransmitLOGMessageFromQue currentTransmitLOGMessageFromQue = NULL;

              Uint16 data[20] = {0};

              char uiAppCmd = 0;

              char uiMsgSize = 0;

 

              //Set registration to socket

              if(bNewAppSocketRegister == false)

              {

                     if(((CBoardSubSystem*)g_pBoard)->Appclientfd!=INVALID_SOCKET)

                     {

                           fdOpenSession(TaskSelf());

                           fdShare((SOCKET)((CBoardSubSystem*)g_pBoard)->Appclientfd);

                         bNewAppSocketRegister = true;

                     }

                     else

                           continue;

              }

              else

              {

                     if( ((CBoardSubSystem*)g_pBoard)->Appclientfd == INVALID_SOCKET )

                     {

                           fdCloseSession(TaskSelf());

                           bNewAppSocketRegister = false;

                           continue;

                     }

              }

 

              //Enter gate

              UInt gateKey = GateMutex_enter(gateMutex6);

              do

              {

                     //get data from the que

                     pTransmitLOGMessageFromQue currentTransmitLOGMessageFromQue = (pTransmitLOGMessageFromQue)Queue_get(QUE_TRANSMIT_LOG_TO_LPU_MESSAGES);

                     if(currentTransmitLOGMessageFromQue == NULL)

                     {

                           UARTprintf("!!! Error currentTransmitLOGMessageFromQue = 0\n");

                           break;

 

                     }

 

                     uiAppCmd  = currentTransmitLOGMessageFromQue->uiAppCmd;

                     uiMsgSize = currentTransmitLOGMessageFromQue->uiMsgSize;

 

                     if ( (uiMsgSize <= 0) || (uiMsgSize > 20) )

                     {

                           UARTprintf("!!! Error TaskTransmitLogToLPU/ uiDataSize = 0\n");

                           break;

 

                     }

 

                     memcpy(data, currentTransmitLOGMessageFromQue->pData, sizeof(data[0])*uiMsgSize);

                     TransmitLOGMessage_freeMsg(currentTransmitLOGMessageFromQue);

 

              }while(0);

 

              GateMutex_leave(gateMutex6, gateKey);

 

              if(uiMsgSize > 0)

              {

                     ((CBoardSubSystem*)g_pBoard)->LPUAppSendData(uiAppCmd, uiMsgSize, &data[0]);

              }

 

       }

 

}

 

 

This task calls :

  1. 1.       fdOpenSession(TaskSelf());

 

  1. 2.       fdShare((SOCKET)((CBoardSubSystem*)g_pBoard)->Appclientfd);

 

 

Please note that when in tcpAppWorker socket is closed, the following is called:

 

             fdClose(tcpAppWorkerclientfd);

             flag = FALSE;

             tcpAppWorkerclientfd=INVALID_SOCKET;

             ((CBoardSubSystem*)g_pBoard)->Appclientfd = tcpAppWorkerclientfd;

             fdCloseSession(TaskSelf());

 

, then in my other tasks (TaskTransmitLogToLPU , IPC_TaskReceiveLPUMsg) is detected that socket is not valid anymore the following is called (please take a look at the tasks):

 

                           fdCloseSession(TaskSelf());

                           bNewAppSocketRegister = false;

                          

 

 

 

The problem that when I try to reopen this socket (communication recovery) it can’t be connected any more. Probably I’m using fdshare wrong or the order of closing and releasing socket from various tasks is wrong.

 

 

Can you please avise me when I shall call in other task which uses LAN socket the following functions:

 

fdOpenSession(TaskSelf());

fdShare((SOCKET)((CBoardSubSystem*)g_pBoard)->Appclientfd);

fdCloseSession(TaskSelf());

and maybe    fdClose(tcpAppWorkerclientfd);

 

 

How shall I synchronize open/close socket between my main task tcpAppWorker (which uses this socket- fiscally determines that there is a problem on communication and closes the socket) and my other tasks which use this socket to send messages to PC through this socket.

 

Thank you in advance,

Hope to hear from you soon

 

Regards, AS

 

  • Hi Alla,

    have you taken a look at <NDK_INSTALL_DIR>\packages\ti\ndk\tools\console\contest.c?

    It's an example that shows how to use fdShare() with an parent SOCKET. It can probably help you with your SOCKET synchronization question as well.

  • Hi Tom,

    I've looked in the example ,seems that I'm doing all OK.  However problem still persist....

    Please note that my tasks for transmit message via LAN (child socket are static  and not dynamic. Every time when a new child socket is opened my transmit taks do fdshare(). Please note that , because the threads are static, im not doing any thing when child socket is closed.

    The problem that would like to connect my MCU via LAN (many time) communication reconnect, however I fail doing it!!!

    I have one static task (void tcpHandler), which is listen to open new socket (child socket on well known port), once the request is received , the 

     clientfd = accept(lSocket, (struct sockaddr*)&client_addr, &addrlen);  is activated, and I allocate dynamically a new Thread (void tcpAppWorker) for handle receive messages on child socket.

    Please note that in addition I have other static (please not the transmit message via child task are not dynamic tasks) such as IPCReceive messageQ which is not dynamically allocated. Every time when socket child is crieted , I call fdshare() on this task.

    Please look into my code and tell me what I'm doing wrong....

    /*
     *  ======== tcpHandler ========
     *  Creates new Task to handle new TCP connections. Static listener task
     */
    void tcpHandler(UArg arg0, UArg arg1)
    {
        SOCKET lSocket;
        struct sockaddr_in sLocalAddr;
        SOCKET clientfd;
        struct sockaddr_in client_addr;
        Int addrlen=sizeof(client_addr);
        Int optval;
        Int optlen = sizeof(optval);
        Int status;
        Task_Handle taskHandle;
        Task_Params taskParams;
        Task_FuncPtr ptrTskFunc=tcpBBWorker;
        //
        Int nbytes=0;
        char* ptrAppLANReceivedBuffer = (char *)TCPHandlerReceivedBuffer;

     

        fdOpenSession(TaskSelf());

        lSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (lSocket < 0) {
         UARTprintf("tcpHandler: socket failed\n");
            Task_exit();
            return;
        }

        memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr));
        sLocalAddr.sin_family = AF_INET;
        sLocalAddr.sin_len = sizeof(sLocalAddr);
        sLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        sLocalAddr.sin_port = htons(arg0);

        status = bind(lSocket, (struct sockaddr *)&sLocalAddr, sizeof(sLocalAddr));
        if (status < 0) {
         UARTprintf("tcpHandler: bind failed\n");
            fdClose(lSocket);
            Task_exit();
            return;
        }


        if (listen(lSocket, 5) != 0){
         UARTprintf("tcpHandler: listen failed\n");
            fdClose(lSocket);
            Task_exit();
            return;
        }


        if (setsockopt(lSocket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
         UARTprintf("tcpHandler: setsockopt failed\n");
            fdClose(lSocket);
            Task_exit();
            return;
        }

        while (1) {
            /* Wait for incoming request */
            clientfd = accept(lSocket, (struct sockaddr*)&client_addr, &addrlen);


             //First bcommand for client ID, check which task to open according to received client request
            nbytes = recv(clientfd, (char *)ptrAppLANReceivedBuffer, 50, 0);//receive client ID
           if (nbytes > 0) {
             if ((TCPHandlerReceivedBuffer->data[0]==7) && (TCPHandlerReceivedBuffer->data[1]==1))
             {
                   if(TCPHandlerReceivedBuffer->data[2]>1) //R&D
                              ptrTskFunc=(Task_FuncPtr)tcpAppWorker;
                  else
                              ptrTskFunc=(Task_FuncPtr)tcpBBWorker;

              Task_Params_init(&taskParams);
              taskParams.arg0 = (UArg)clientfd;
              taskParams.arg1= (UArg)TCPHandlerReceivedBuffer->data[2];//client type: user, service, user application
              taskParams.stackSize = 1024;//768;
             taskParams.priority=5;
            taskHandle = Task_create((Task_FuncPtr)ptrTskFunc, &taskParams, NULL);
           if (taskHandle == NULL) {
            UARTprintf("tcpHandler: Failed to create new Task\n");
                  }//end  if
               }//end if

            }//end  if
        }//end while
    }

     

    /*
     *  ======== tcpAppWorker========
     *  Creates new child  dynamic task  to handle new TCP connection (with new client).
     */

    void tcpAppWorker(UArg arg0, UArg arg1)
    {
        Int nbytes;
        Bool flag = TRUE;
        Error_Block eb;
        char* ptrReceivedBuffer = ((CBoardSubSystem*)g_pBoard)->ptrAppLANReceivedBuffer;
        Bool ComEstflag = TRUE;

        fdOpenSession(TaskSelf());

        UARTprintf("Start TCP App work task\n");

        tcpAppWorkerclientfd = (SOCKET)arg0;

        ((CBoardSubSystem*)g_pBoard)->Appclientfd = tcpAppWorkerclientfd;

     if(ComEstflag == TRUE)
     {
      ComEstflag = FALSE;
      //Infornm C28 on  communication establish
      char temp[4];

      temp[0] = NEW_LPU_CLIENT_CONNECTED;
      if((arg1 > CIENT_ID_BLUBOX) && (arg1 < CIENT_LOG))
      {
       temp[1] = arg1;//CIENT_ID_BLUBOX =1, CLIENT_MAIN_APP =2, CIENT_RandD =3, CIENT_SERVICE =4, CIENT_LOG =5
       ((IPCInterface *)(g_pBoard->m_pIPCInterfacePtr))->IPCSendDataFromLPU(APP_M3_C28_CMD, PRI_NORMAL, 3, temp);
      }
     }
         
        /* Make sure Error_Block is initialized */
        Error_init(&eb);
        /* Loop while we receive data */
        while (flag) {
            nbytes = recv(tcpAppWorkerclientfd, (char *)ptrReceivedBuffer, BBTCPPACKETSIZE, 0);
             

            if (nbytes > 0) {
             if(ptrReceivedBuffer[0] > 0)
                // Handle the App Command
             ((CBoardSubSystem*)g_pBoard)->PCMessageHandle(nbytes);

        }
            else {
             // Error
                 fdClose(tcpAppWorkerclientfd);
                 flag = FALSE;
                 tcpAppWorkerclientfd=INVALID_SOCKET;
                 ((CBoardSubSystem*)g_pBoard)->Appclientfd = tcpAppWorkerclientfd;
            }
        }


        fdCloseSession(TaskSelf());
        Task_exit();
    }

     

    /*******************************************************************************
    Function Name : IPC_TaskReceiveLPUMsg -  static task for handling IPc messages...resend to PC via LAN
    Description :   This is the IPC task for receiving IPC messages to be sent to LPU
    *******************************************************************************/
    Void IPC_TaskReceiveLPUMsg(UArg arg0, UArg arg1)
    {
     Uint16 tempbuff[MAX_LOG_CMD_DATA_SIZE];
     Uint16 loop;
     static Bool bNewAppSocketRegister = false;
        // Init the IPC, M3 <-> C28x communication (for LPU messages)
     IPC_init_1();

     // Open the file session
     fdOpenSession(TaskSelf());

     System_printf("CIPCInterface (M3):: before while, after IPC_init_1() \n");

        // Check the WD timer "0" interrupt
        while (1)
        {
         // receive a message
         myRcvMessage = IPC_recMsgQ1 ();
         if(myRcvMessage == NULL)
         {
          System_printf("CIPCInterface (M3):myRcvMessage == NULL \n");
           continue;
         }

     switch (myRcvMessage->MsgType)
      {
                case APP_C28_M3_CMD:
          {
                         if(myRcvMessage->Data[1].IntData== NEW_LPU_CLIENT_CONNECTED)                   {
                               if(((CBoardSubSystem*)g_pBoard)->Appclientfd!=INVALID_SOCKET)
                             {
                                     bNewAppSocketRegister = true;
                                    fdShare((SOCKET)((CBoardSubSystem*)g_pBoard)->Appclientfd);
                            }
           }
           //Set the same for Log client
          }
          break;
          case CLIENT_MAIN_APP:
          {
                 int i,j;
                         //copy data
                         for(i=0,j=0; i<99 && j<MAX_MSG_DATA_SHORT_SIZE; i++, j++)
                        {
                                tempDataBuff[i++]= myRcvMessage->Data[j].ShortData.Byte1;
                               if(i>99)
                              break;
                               tempDataBuff[i]= myRcvMessage->Data[j].ShortData.Byte2;
                       }

                     ((CBoardSubSystem*)g_pBoard)->LPUAppSendData(tempDataBuff[1], tempDataBuff[0], &tempDataBuff[1]);

          }
          break;
          default:
           break;
         }

         //Free the received message
         IPC_freeMsg (myRcvMessage);
        }

        // Close the file session
        fdCloseSession(TaskSelf());
    }

     

    Please advice.

     

    Thank you

    AS

  • Hi Alla,

    you probably want to check the return value of the accept() call to make sure it returns a good value.

    Please take a closer look at contest.c. You'll see that the child tasks call fdOpenSession() which is immediately followed by a fdShare() call.

    For example in your code, the tcpAppWorker task is using a socket API (recv) before the file descriptor was shared with fdShare(). Also, check to make sure that you are performing the same number of fdClose() calls as you are fdOpenSession() calls. If you are sharing a socket from a parent task, you need add a fdShare() immediately after the fdOpenSession().

  • Ho Tom,

    I've tried your suggestions. Seems that now its works OK. What I did is t as follows.

    I've added to dynamically allocated task tcpAppWorker, call to fdshare() after  fdOpenSession(TaskSelf()); (because it  achild task of parent task which opened the socket).

    However for static tasks which use new created socket for transmitting the message I've removed fdshare().

    I've added storing Socket handle in static variable (it been inoitialized when new socket is opened), when the socket is closed I've aded call to  fdclose() function before fdCloseSession.   The problem was as I see it that fdshare() was called from static tasks.

     

    I hope I dd a right corrections

    Thank you for your reply!

    Regards, AS