static CellularCommInterfaceError_t _prvCommIntfOpen()

in source/cellular/comm_if_windows.c [500:641]


static CellularCommInterfaceError_t _prvCommIntfOpen( CellularCommInterfaceReceiveCallback_t receiveCallback,
                                                      void * pUserData,
                                                      CellularCommInterfaceHandle_t * pCommInterfaceHandle )
{
    CellularCommInterfaceError_t commIntRet = IOT_COMM_INTERFACE_SUCCESS;
    HANDLE hComm = ( HANDLE ) INVALID_HANDLE_VALUE;
    BOOL Status = TRUE;
    _cellularCommContext_t * pCellularCommContext = _getCellularCommContext();
    DWORD dwRes = 0;

    if( pCellularCommContext == NULL )
    {
        commIntRet = IOT_COMM_INTERFACE_FAILURE;
    }
    else if( ( pCellularCommContext->commStatus & CELLULAR_COMM_OPEN_BIT ) != 0 )
    {
        CellularLogError( "Cellular comm interface opened already" );
        commIntRet = IOT_COMM_INTERFACE_FAILURE;
    }
    else
    {
        /* Clear the context. */
        memset( pCellularCommContext, 0, sizeof( _cellularCommContext_t ) );
        pCellularCommContext->pCommInterface = &CellularCommInterface;

        /* If CreateFile fails, the return value is INVALID_HANDLE_VALUE. */
        hComm = CreateFile( TEXT( CELLULAR_COMM_PATH ),
                            GENERIC_READ | GENERIC_WRITE,
                            0,
                            NULL,
                            OPEN_EXISTING,
                            FILE_FLAG_OVERLAPPED,
                            NULL );
    }

    /* Comm port is just closed. Wait 1 second and retry. */
    if( ( hComm == ( HANDLE ) INVALID_HANDLE_VALUE ) && ( GetLastError() == 5 ) )
    {
        vTaskDelay( pdMS_TO_TICKS( 1000UL ) );
        hComm = CreateFile( TEXT( CELLULAR_COMM_PATH ),
                            GENERIC_READ | GENERIC_WRITE,
                            0,
                            NULL,
                            OPEN_EXISTING,
                            FILE_FLAG_OVERLAPPED,
                            NULL );
    }

    if( hComm == ( HANDLE ) INVALID_HANDLE_VALUE )
    {
        CellularLogError( "Cellular open COM port fail %d", GetLastError() );
        commIntRet = IOT_COMM_INTERFACE_FAILURE;
    }
    else
    {
        Status = SetupComm( hComm, COMM_TX_BUFFER_SIZE, COMM_RX_BUFFER_SIZE );

        if( Status == FALSE )
        {
            CellularLogError( "Cellular setup COM port fail %d", GetLastError() );
            commIntRet = IOT_COMM_INTERFACE_FAILURE;
        }
    }

    if( commIntRet == IOT_COMM_INTERFACE_SUCCESS )
    {
        commIntRet = _setupCommTimeout( hComm );
    }

    if( commIntRet == IOT_COMM_INTERFACE_SUCCESS )
    {
        commIntRet = _setupCommSettings( hComm );
    }

    if( commIntRet == IOT_COMM_INTERFACE_SUCCESS )
    {
        Status = SetCommMask( hComm, EV_RXCHAR );

        if( Status == FALSE )
        {
            CellularLogError( "Cellular SetCommMask fail %d", GetLastError() );
            commIntRet = IOT_COMM_INTERFACE_FAILURE;
        }
    }

    if( commIntRet == IOT_COMM_INTERFACE_SUCCESS )
    {
        pCellularCommContext->commReceiveCallback = receiveCallback;
        commIntRet = setupCommTaskThread( pCellularCommContext );
    }

    if( commIntRet == IOT_COMM_INTERFACE_SUCCESS )
    {
        vPortSetInterruptHandler( portINTERRUPT_UART, prvProcessUartInt );
        pCellularCommContext->commReceiveCallbackThread =
            CreateThread( NULL, 0, _CellularCommReceiveCBThreadFunc, hComm, 0, NULL );

        /* CreateThread return NULL for error. */
        if( pCellularCommContext->commReceiveCallbackThread == NULL )
        {
            CellularLogError( "Cellular CreateThread fail %d", GetLastError() );
            commIntRet = IOT_COMM_INTERFACE_FAILURE;
        }
    }

    if( commIntRet == IOT_COMM_INTERFACE_SUCCESS )
    {
        pCellularCommContext->pUserData = pUserData;
        pCellularCommContext->commFileHandle = hComm;
        *pCommInterfaceHandle = ( CellularCommInterfaceHandle_t ) pCellularCommContext;
        pCellularCommContext->commStatus |= CELLULAR_COMM_OPEN_BIT;
    }
    else
    {
        /* Comm interface open fail. Clean the data. */
        if( hComm != ( HANDLE ) INVALID_HANDLE_VALUE )
        {
            ( void ) CloseHandle( hComm );
            hComm = INVALID_HANDLE_VALUE;
            commIntRet = IOT_COMM_INTERFACE_FAILURE;
        }

        /* Wait for the commReceiveCallbackThread exit. */
        if( pCellularCommContext->commReceiveCallbackThread != NULL )
        {
            dwRes = WaitForSingleObject( pCellularCommContext->commReceiveCallbackThread, COMM_RECV_THREAD_TIMEOUT );

            if( dwRes != WAIT_OBJECT_0 )
            {
                CellularLogDebug( "Cellular close wait receiveCallbackThread %p fail %d",
                                  pCellularCommContext->commReceiveCallbackThread, dwRes );
            }
        }

        pCellularCommContext->commReceiveCallbackThread = NULL;

        /* Wait for the commTaskThreadStarted exit. */
        ( void ) cleanCommTaskThread( pCellularCommContext );
    }

    return commIntRet;
}