ANSC_STATUS
CcspCwmpTcpcrhoCancel
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PCCSP_CWMP_TCPCR_HANDLER_OBJECT      pMyObject     = (PCCSP_CWMP_TCPCR_HANDLER_OBJECT    )hThisObject;
    PCCSP_CWMP_TCPCR_HANDLER_PROPERTY    pProperty     = (PCCSP_CWMP_TCPCR_HANDLER_PROPERTY  )&pMyObject->Property;
    PANSC_DAEMON_SERVER_TCP_OBJECT  pTcpServer    = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hTcpServer;

    if ( !pMyObject->bActive )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    else
    {
        pMyObject->bActive = FALSE;
    }

    if ( pTcpServer )
    {
        returnStatus = pTcpServer->Cancel((ANSC_HANDLE)pTcpServer);
    }

    returnStatus = pMyObject->RemoveTcpServers((ANSC_HANDLE)pMyObject);

    return  returnStatus;
}
ANSC_STATUS
CcspCwmpTcpcrhoCreateTcpServers

    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PCCSP_CWMP_TCPCR_HANDLER_OBJECT      pMyObject     = (PCCSP_CWMP_TCPCR_HANDLER_OBJECT    )hThisObject;
    PCCSP_CWMP_TCPCR_HANDLER_PROPERTY    pProperty     = (PCCSP_CWMP_TCPCR_HANDLER_PROPERTY  )&pMyObject->Property;
    PANSC_DAEMON_SERVER_TCP_OBJECT  pTcpServer    = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hTcpServer;

    if ( pProperty->HostPort == 0 && pTcpServer )
    {
        CcspTr069PaTraceDebug(("Port is 0 on current TcpServer: Server will be removed!!!\n"));
        pTcpServer->Remove((ANSC_HANDLE)pTcpServer);
        pMyObject->hTcpServer   = (ANSC_HANDLE)NULL;
    }
    else if ( !pTcpServer && pProperty->HostPort != 0 )
    {
        pTcpServer =
            (PANSC_DAEMON_SERVER_TCP_OBJECT)AnscCreateDaemonServerTcp
                (
                    pMyObject->hContainerContext,
                    (ANSC_HANDLE)pMyObject,
                    (ANSC_HANDLE)NULL
                );

        if ( !pTcpServer )
        {
            CcspTr069PaTraceDebug(("Something wrong in AnscCreateDaemonServerTCP.\n"));
            return  ANSC_STATUS_RESOURCES;
        }
        else
        {
            pMyObject->hTcpServer = (ANSC_HANDLE)pTcpServer;
        }

        pTcpServer->SetWorker
            (
                (ANSC_HANDLE)pTcpServer,
                pMyObject->hDstoWorker,
                sizeof(ANSC_DSTO_WORKER_OBJECT)
            );
    }

    CcspTr069PaTraceDebug(("TCP server created successfully.\n"));

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
CcspCwmpTcpcrhoRemoveTcpServers
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PCCSP_CWMP_TCPCR_HANDLER_OBJECT      pMyObject     = (PCCSP_CWMP_TCPCR_HANDLER_OBJECT    )hThisObject;
    PCCSP_CWMP_TCPCR_HANDLER_PROPERTY    pProperty     = (PCCSP_CWMP_TCPCR_HANDLER_PROPERTY  )&pMyObject->Property;
    PANSC_DAEMON_SERVER_TCP_OBJECT  pTcpServer = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hTcpServer;

    if ( pTcpServer )
    {
        pTcpServer->Remove((ANSC_HANDLE)pTcpServer);

        pMyObject->hTcpServer = (ANSC_HANDLE)NULL;
    }

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
AnscDstoCancel
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PANSC_DAEMON_SERVER_TCP_OBJECT  pMyObject    = (PANSC_DAEMON_SERVER_TCP_OBJECT)hThisObject;
    PANSC_DSTO_WORKER_OBJECT        pWorker      = (PANSC_DSTO_WORKER_OBJECT      )pMyObject->hWorker;

    if ( !pMyObject->bActive )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    else if ( !pWorker )
    {
        return  ANSC_STATUS_UNAPPLICABLE;
    }
    else
    {
        pWorker->Unload(pWorker->hWorkerContext);

        pMyObject->bActive = FALSE;
    }

    if ( ((pMyObject->Socket != XSKT_SOCKET_INVALID_SOCKET) &&  (pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET)) ||
         ((pMyObject->Socket != ANSC_SOCKET_INVALID_SOCKET) && !(pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET)) )
    {
        if ( pMyObject->Mode & ANSC_DSTO_MODE_POLLING_ACCEPT )
        {
            AnscWaitEvent(&pMyObject->AcceptEvent, ANSC_DSTO_TASK_CLEANUP_TIME);

            if ( pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET )
            {
                _xskt_shutdown   (pMyObject->Socket, XSKT_SOCKET_SD_BOTH);
                _xskt_closesocket(pMyObject->Socket);
            }
            else
            {
                _ansc_shutdown   (pMyObject->Socket, ANSC_SOCKET_SD_BOTH);
                _ansc_closesocket(pMyObject->Socket);
            }
        }
        else
        {
            if ( pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET )
            {
                _xskt_shutdown   (pMyObject->Socket, XSKT_SOCKET_SD_BOTH);
                _xskt_closesocket(pMyObject->Socket);
            }
            else
            {
                _ansc_shutdown   (pMyObject->Socket, ANSC_SOCKET_SD_BOTH);
                _ansc_closesocket(pMyObject->Socket);
            }

            AnscWaitEvent(&pMyObject->AcceptEvent, ANSC_DSTO_TASK_CLEANUP_TIME);
        }
    }

    pMyObject->StopEngines      ((ANSC_HANDLE)pMyObject);
    pMyObject->DestroyEnginePool((ANSC_HANDLE)pMyObject);
    pMyObject->DestroySocketPool((ANSC_HANDLE)pMyObject);

    /*
     * The underlying socket wrapper may require an explicit cleanup() call, such is the case on
     * Microsoft windows platforms. The wrapper initialization has to done for each task. On most
     * real-time operating systems, this call is not required.
     */
    if ( pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET )
    {
        AnscCleanupXsocketWrapper((ANSC_HANDLE)pMyObject);
    }
    else
    {
        AnscCleanupSocketWrapper((ANSC_HANDLE)pMyObject);
    }

    pMyObject->Reset((ANSC_HANDLE)pMyObject);

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
AnscDstoEngage
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PANSC_DAEMON_SERVER_TCP_OBJECT  pMyObject    = (PANSC_DAEMON_SERVER_TCP_OBJECT)hThisObject;
    PANSC_DSTO_WORKER_OBJECT        pWorker      = (PANSC_DSTO_WORKER_OBJECT      )pMyObject->hWorker;
    int                             s_result     = 0;
#ifdef _ANSC_IPV6_COMPATIBLE_
    ansc_addrinfo                   ansc_hints           = {0};
    ansc_addrinfo*                  pansc_local_addrinfo = NULL;
    xskt_addrinfo                   xskt_hints           = {0};
    xskt_addrinfo*                  pxskt_local_addrinfo = NULL;
    USHORT                          usPort               = 0;
    char                            port[6]              = {0};
#else
    /*RDKB-6151, CID-24487,24794; initializing variable before use*/
    ansc_socket_addr_in             local_addr1 = {0};
    xskt_socket_addr_in             local_addr2 = {0};
#endif

    if ( pMyObject->bActive )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    else if ( !pWorker )
    {
        return  ANSC_STATUS_UNAPPLICABLE;
    }
    else
    {
        pWorker->Init(pWorker->hWorkerContext);

        pMyObject->StartTime = AnscGetTickInSecondsAbs();
        pMyObject->bActive   = TRUE;
    }

    /*
     * The underlying socket wrapper may require an explicit startup() call, such is the case on
     * Microsoft windows platforms. The wrapper initialization has to done for each task. On most
     * real-time operating systems, this call is not required.
     */
    if ( pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET )
    {
        AnscStartupXsocketWrapper((ANSC_HANDLE)pMyObject);
    }
    else
    {
        AnscStartupSocketWrapper((ANSC_HANDLE)pMyObject);
    }
    
#ifdef _ANSC_IPV6_COMPATIBLE_

    if ( pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET )
    {
        xskt_hints.ai_family   = AF_UNSPEC;
        xskt_hints.ai_socktype = XSKT_SOCKET_STREAM;
        xskt_hints.ai_flags    = AI_PASSIVE | AI_ADDRCONFIG;

        usPort = pMyObject->GetHostPort((ANSC_HANDLE)pMyObject);
        _ansc_sprintf(port, "%d", usPort);
        CcspTraceInfo(("!!! Host Name: %s, Host Port: %s !!!\n", pMyObject->HostName, port));

        if ( _xskt_getaddrinfo
                (
                    pMyObject->HostName[0] ? pMyObject->HostName : "::", 
                    port,
                    &xskt_hints,
                    &pxskt_local_addrinfo
                ) 
            )
        {
            CcspTraceError(("!!! error 1 !!!\n"));

            returnStatus = ANSC_STATUS_FAILURE;
            
            goto  EXIT1;
        }
        
        pMyObject->pHostAddr2 = pxskt_local_addrinfo;
    }
    else
    {
        ansc_hints.ai_family   = AF_UNSPEC;
        ansc_hints.ai_socktype = ANSC_SOCKET_STREAM;
        ansc_hints.ai_flags    = AI_PASSIVE | AI_ADDRCONFIG;

        usPort = pMyObject->GetHostPort((ANSC_HANDLE)pMyObject);
        _ansc_sprintf(port, "%d", usPort);
        CcspTraceInfo(("!!! Host Name: %s, Host Port: %s !!!\n", pMyObject->HostName, port));

        if ( _ansc_getaddrinfo
                (
                    pMyObject->HostName[0] ? pMyObject->HostName : "::",
                    port,
                    &ansc_hints,
                    &pansc_local_addrinfo
                ) 
            )
        {
            returnStatus = ANSC_STATUS_FAILURE;

            goto  EXIT1;
        }
        
        pMyObject->pHostAddr1 = pansc_local_addrinfo;
    }

#endif

    /*
     * To engage the Tcp Daemon, we need to perform following acts in the respective order:
     *
     *      (1) create the os-dependent socket
     *      (2) manufacture and start all the engines objects
     *      (3) manufacture the global socket object pool
     *      (4) bind to the socket and listen on it
     */
    if ( pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET )
    {
#ifdef _ANSC_IPV6_COMPATIBLE_
        pMyObject->Socket = _xskt_socket(pxskt_local_addrinfo->ai_family, pxskt_local_addrinfo->ai_socktype, 0);
#else
        pMyObject->Socket = _xskt_socket(XSKT_SOCKET_AF_INET, XSKT_SOCKET_STREAM, 0);
#endif
    }
    else
    {
#ifdef _ANSC_IPV6_COMPATIBLE_
        pMyObject->Socket = _ansc_socket(pansc_local_addrinfo->ai_family, pansc_local_addrinfo->ai_socktype, 0);
#else
        pMyObject->Socket = _ansc_socket(ANSC_SOCKET_AF_INET, ANSC_SOCKET_STREAM, 0);
#endif
    }

    if ( ((pMyObject->Socket == XSKT_SOCKET_INVALID_SOCKET) &&  (pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET)) ||
         ((pMyObject->Socket == ANSC_SOCKET_INVALID_SOCKET) && !(pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET)) )
    {
        returnStatus = ANSC_STATUS_FAILURE;

        goto  EXIT1;
    }

    _ansc_en_reuseaddr(pMyObject->Socket);

#ifndef _ANSC_IPV6_COMPATIBLE_
    if ( pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET )
    {
        local_addr2.sin_family = XSKT_SOCKET_AF_INET;
        local_addr2.sin_port   = _xskt_htons(pMyObject->HostPort);

        if ( pMyObject->HostAddress.Value == 0 )
        {
            ((pansc_socket_addr_in)&local_addr2)->sin_addr.s_addr = XSKT_SOCKET_ANY_ADDRESS;
        }
        else
        {
            ((pansc_socket_addr_in)&local_addr2)->sin_addr.s_addr = pMyObject->HostAddress.Value;
        }
    }
    else
    {
        local_addr1.sin_family = ANSC_SOCKET_AF_INET;
        local_addr1.sin_port   = _ansc_htons(pMyObject->HostPort);

        if ( pMyObject->HostAddress.Value == 0 )
        {
            local_addr1.sin_addr.s_addr = ANSC_SOCKET_ANY_ADDRESS;
        }
        else
        {
            local_addr1.sin_addr.s_addr = pMyObject->HostAddress.Value;
        }
    }
#endif

#if !defined(_ANSC_KERNEL) || !defined(_ANSC_LINUX)
    if ( pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET )
    {
#ifdef _ANSC_IPV6_COMPATIBLE_
        s_result = _xskt_bind(pMyObject->Socket, pxskt_local_addrinfo->ai_addr, pxskt_local_addrinfo->ai_addrlen);
#else
        AnscTrace("AnscDstoEngage -- the address is 0x%lX:%d, familty %d.\n", _ansc_ntohl(local_addr2.sin_addr.s_addr), _ansc_ntohs(local_addr2.sin_port), local_addr2.sin_family);
        s_result = _xskt_bind(pMyObject->Socket, (xskt_socket_addr*)&local_addr2, sizeof(local_addr2));
#endif
    }
    else
    {
#ifdef _ANSC_IPV6_COMPATIBLE_
        s_result = _ansc_bind(pMyObject->Socket, pansc_local_addrinfo->ai_addr, pansc_local_addrinfo->ai_addrlen);
#else
        s_result = _ansc_bind(pMyObject->Socket, (ansc_socket_addr*)&local_addr1, sizeof(local_addr1));
#endif
    }
#else
	if ( pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET )
    {
        while ( _xskt_bind(pMyObject->Socket, (ansc_socket_addr*)&local_addr2, sizeof(local_addr2)) != 0 )
        {
            AnscTrace
				(
					"AnscDstoEngage -- failure to bind try again !socket %d family %d port %d address %X \n",
					pMyObject->Socket,
					local_addr2.sin_family,
                    local_addr2.sin_port,
					((pansc_socket_addr_in)&local_addr2)->sin_addr.s_addr
				);

            AnscSleep(10);
        }
    }
    else
    {
        while ( _ansc_bind(pMyObject->Socket, (ansc_socket_addr*)&local_addr1, sizeof(local_addr1)) != 0 )
        {
            AnscTrace
				(
					"AnscDstoEngage -- failure to bind try again !socket %d family %d port %d address %X \n",
					pMyObject->Socket,
					local_addr1.sin_family,
                    local_addr1.sin_port,
					local_addr1.sin_addr.s_addr
				);

            AnscSleep(10);
        }
    }
#endif

    if ( s_result != 0 )
    {
		AnscTrace
            (
                "AnscDstoEngage -- failed to bind to the socket, error code is %d!!!\n",
                (pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET) ? _xskt_get_last_error() : _ansc_get_last_error()
            );

        returnStatus = ANSC_STATUS_FAILURE;

        goto  EXIT2;
    }

    pMyObject->ManufactureEnginePool((ANSC_HANDLE)pMyObject);
    pMyObject->ManufactureSocketPool((ANSC_HANDLE)pMyObject);
    pMyObject->StartEngines         ((ANSC_HANDLE)pMyObject);

    if ( pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET )
    {
        s_result = _xskt_listen(pMyObject->Socket, ANSC_SOCKET_BACKLOG_VALUE);
    }
    else
    {
        s_result = _ansc_listen(pMyObject->Socket, ANSC_SOCKET_BACKLOG_VALUE);
    }

    if ( s_result != 0 )
    {
		AnscTrace("AnscDstoEngage -- failed to listen on the socket!\n");

        returnStatus = ANSC_STATUS_FAILURE;

        goto  EXIT2;
    }

    /*
     * If the compilation option '_ANSC_SOCKET_TLS_LAYER_' is enabled, we can simply let the ANSC
     * socket layer to perform the SSL/TLS functionality; otherwise, we need to prepare for doing
     * SSL/TLS internally.
     */
    if ( pMyObject->Mode & ANSC_DSTO_MODE_TLS_ENABLED )
    {
#ifdef _ANSC_USE_OPENSSL_
        pMyObject->bTlsEnabled = TRUE;
        if ( !openssl_init(SSL_SERVER_CALLS) )
        {
        	AnscTrace("AnscSctoEngage - openssl_init() failed!\n");
            returnStatus = ANSC_STATUS_FAILURE;
            goto  EXIT2;
        }

#else
        #ifdef  _ANSC_SOCKET_TLS_LAYER_
        {
            _ansc_en_usetls(pMyObject->Socket);

            pMyObject->bTlsEnabled = FALSE;
        }
        #else
        {
            pMyObject->hTlsScsIf   = (pMyObject->hTlsScsIf != NULL)? pMyObject->hTlsScsIf : AnscSocketTlsGetScsIf();
            pMyObject->bTlsEnabled = TRUE;
            pMyObject->bTlsReqCert = (pMyObject->Mode & ANSC_DSTO_MODE_TLS_REQ_CERT);
        }
        #endif
#endif
    }

    AnscResetEvent(&pMyObject->AcceptEvent);
    returnStatus =
        pMyObject->SpawnTask3
            (
                (ANSC_HANDLE)pMyObject,
                (void*      )pMyObject->AcceptTask,
                (ANSC_HANDLE)pMyObject,
                ANSC_DSTO_ACCEPT_TASK_NAME,
                USER_DEFAULT_TASK_PRIORITY,
                2*USER_DEFAULT_TASK_STACK_SIZE

            );

    return  ANSC_STATUS_SUCCESS;


    /******************************************************************
                GRACEFUL ROLLBACK PROCEDURES AND EXIT DOORS
    ******************************************************************/

EXIT2:

    if ( pMyObject->Mode & ANSC_DSTO_MODE_XSOCKET )
    {
        _xskt_closesocket(pMyObject->Socket);
    }
    else
    {
        _ansc_closesocket(pMyObject->Socket);
    }

EXIT1:

    if ( returnStatus != ANSC_STATUS_SUCCESS )
    {
        pMyObject->bActive = FALSE;
    }

    return  returnStatus;
}
ANSC_STATUS
AnscDstoAsyncJobTask
    (
        ANSC_HANDLE                 hAsyncJob
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PANSC_DSTO_ASYNC_JOB            pAsyncJob    = (PANSC_DSTO_ASYNC_JOB          )hAsyncJob;
    PANSC_DAEMON_SERVER_TCP_OBJECT  pMyObject    = (PANSC_DAEMON_SERVER_TCP_OBJECT)pAsyncJob->hThisObject;
    PANSC_DAEMON_ENGINE_TCP_OBJECT  pCurEngine   = (PANSC_DAEMON_ENGINE_TCP_OBJECT)NULL;
    PANSC_DAEMON_SOCKET_TCP_OBJECT  pSocket      = (PANSC_DAEMON_SOCKET_TCP_OBJECT)pAsyncJob->hSocket;
    PANSC_DSTO_WORKER_OBJECT        pWorker      = (PANSC_DSTO_WORKER_OBJECT      )pMyObject->hWorker;
    ULONG                           ulRetryCount = 0;

    switch ( pAsyncJob->JobType )
    {
        case    ANSC_DSTO_JOB_TYPE_initTlsConnection :

                /*
                 * We have to assign an engine object to this new socket object. The assignment is done by
                 * round-robin. However, we need to make sure that the assigned engine object is not over-
                 * loaded. If it is, we repeat the search until finding a happen one.
                 */
                ulRetryCount = 0;

                if ( pSocket->bTlsEnabled )
                {
                    returnStatus = pSocket->InitTlsServer((ANSC_HANDLE)pSocket);

                    if ( returnStatus != ANSC_STATUS_SUCCESS )
                    {
                        /*
                         * I don't understand why this line was commented out before: maybe the
                         * TLS_TSA implementation in AnscDaemonSocketTcp used to clean up socket
                         * object if anything goes wrong? Anyway, it seems a good idea to enable
                         * this line. 07/20/04 - I think the reason is that it's easier to close
                         * socket from the recv() context.
                         */
                        pSocket->Finish((ANSC_HANDLE)pSocket);

                        pMyObject->TccCount++;

                        break;
                    }
                }

                while ( pCurEngine =
                            (PANSC_DAEMON_ENGINE_TCP_OBJECT)pMyObject->AssignEngine
                                (
                                    (ANSC_HANDLE)pMyObject
                                ) )
                {
                    returnStatus =
                        pCurEngine->AddSocket
                            (
                                (ANSC_HANDLE)pCurEngine,
                                (ANSC_HANDLE)pSocket
                            );

                    if ( returnStatus == ANSC_STATUS_SUCCESS )
                    {
                        pMyObject->TscCount++;

                        break;
                    }
                    else
                    {
                        ulRetryCount++;

                        if ( ulRetryCount >= pMyObject->EngineCount )
                        {
                            pSocket->Close ((ANSC_HANDLE)pSocket);
                            pSocket->Return((ANSC_HANDLE)pSocket);

                            pMyObject->TrcCount++;

                            returnStatus = ANSC_STATUS_FAILURE;

                            break;
                        }
                    }
                }

                /*
                 * If AddSocket() failed, socket has already been destroyed. In this case, we need
                 * to terminate TLS negotiation task silently. Note that the only scenario where
                 * AddSocket() fails is that the engine is serving a large number of sockets, the
                 * maximum socket number limitation has already been reached.
                 */
                if ( returnStatus != ANSC_STATUS_SUCCESS )
                {
                    break;
                }
                else if ( pSocket->bTlsEnabled )
                {
                    returnStatus = pSocket->OpenTlsServer((ANSC_HANDLE)pSocket);

                    if ( returnStatus != ANSC_STATUS_SUCCESS )
                    {
                        /*
                         * I don't understand why this line was commented out before: maybe the
                         * TLS_TSA implementation in AnscDaemonSocketTcp used to clean up socket
                         * object if anything goes wrong? Anyway, it seems a good idea to enable
                         * this line. 07/20/04 - I think the reason is that it's easier to close
                         * socket from the recv() context.
                         */
                        pSocket->ToClean((ANSC_HANDLE)pSocket, TRUE, 2);

                        pMyObject->TccCount++;

                        break;
                    }
                }

                if ( !pWorker->Accept
                        (
                            pWorker->hWorkerContext,
                            (ANSC_HANDLE)pSocket,
                            &pSocket->hClientContext
                        ) )
                {
                    pSocket->ToClean((ANSC_HANDLE)pSocket, TRUE, 2);

                    pMyObject->TccCount++;

                    break;
                }
                else
                {
                    returnStatus =
                        pWorker->SetOut
                            (
                                pWorker->hWorkerContext,
                                (ANSC_HANDLE)pSocket
                            );
                }

                /*
                 * Mark the flag that we've completed initializing the TLS connection...
                 */
                pSocket->bTlsInitializing = FALSE;

                break;

        default :

                break;
    }

    AnscFreeMemory(pAsyncJob);

    return  returnStatus;
}
ANSC_STATUS
CcspCwmpTcpcrhoEngage
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PCCSP_CWMP_TCPCR_HANDLER_OBJECT      pMyObject     = (PCCSP_CWMP_TCPCR_HANDLER_OBJECT    )hThisObject;
    PCCSP_CWMP_TCPCR_HANDLER_PROPERTY    pProperty     = (PCCSP_CWMP_TCPCR_HANDLER_PROPERTY  )&pMyObject->Property;
    PANSC_DAEMON_SERVER_TCP_OBJECT  pTcpServer    = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hTcpServer;
    ULONG                           ulEngineCount = 1;
    ULONG                           ulSocketCount = 1;
    ULONG                           ulTcpDsoMode  = ANSC_DSTO_MODE_EVENT_SYNC | ANSC_DSTO_MODE_FOREIGN_BUFFER | ANSC_DSTO_MODE_COMPACT;

    if ( pMyObject->bActive )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    else
    {
        pMyObject->bActive = TRUE;
    }

    returnStatus = pMyObject->CreateTcpServers((ANSC_HANDLE)pMyObject);
    if ( returnStatus != ANSC_STATUS_SUCCESS )
    {
        CcspTr069PaTraceDebug(("Create TCP server failed\n"));

        pMyObject->bActive = FALSE;
        return  returnStatus;
    }

    if ( pProperty->ServerMode & CCSP_CWMP_TCPCR_HANDLER_MODE_useXsocket )
    {
        ulTcpDsoMode |= ANSC_DSTO_MODE_XSOCKET;
    }

    ulEngineCount = 1;
    ulSocketCount = 4;

    pTcpServer    = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hTcpServer;

    if ( pTcpServer )
    {
#ifdef _ANSC_IPV6_COMPATIBLE_
        CcspTr069PaTraceDebug(("Tcp host addr=%s:%d\n", 
                               pProperty->HostAddr,
                               pProperty->HostPort));
        AnscCopyString(pTcpServer->HostName, pProperty->HostAddr);
#else
        CcspTr069PaTraceDebug(("Tcp host addr=%d.%d.%d.%d:%d\n", 
                               pProperty->HostAddress.Dot[0],
                               pProperty->HostAddress.Dot[1],
                               pProperty->HostAddress.Dot[2],
                               pProperty->HostAddress.Dot[3],
                               pProperty->HostPort));

        pTcpServer->SetHostAddress   ((ANSC_HANDLE)pTcpServer, pProperty->HostAddress.Dot);
#endif
        pTcpServer->SetHostPort      ((ANSC_HANDLE)pTcpServer, pProperty->HostPort       );
        pTcpServer->SetMaxMessageSize((ANSC_HANDLE)pTcpServer, CCSP_CWMP_TCPCR_MAX_MSG_SIZE   );
        pTcpServer->SetEngineCount   ((ANSC_HANDLE)pTcpServer, ulEngineCount             );
        pTcpServer->SetMinSocketCount((ANSC_HANDLE)pTcpServer, 0                         );
        pTcpServer->SetMaxSocketCount((ANSC_HANDLE)pTcpServer, ulSocketCount             );
        pTcpServer->SetMode          ((ANSC_HANDLE)pTcpServer, ulTcpDsoMode              );

        returnStatus = pTcpServer->Engage((ANSC_HANDLE)pTcpServer);
        if ( returnStatus != ANSC_STATUS_SUCCESS )
        {
            CcspTr069PaTraceError(("CcspCwmpTcpcrhoEngage - failed to be engaged, CWMP will not run properly!\n"));
            pMyObject->bActive = FALSE;

            return  returnStatus;
        }
    }

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
CcspCwmpTcpcrhoCreateTcpServers

    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PCCSP_CWMP_TCPCR_HANDLER_OBJECT      pMyObject     = (PCCSP_CWMP_TCPCR_HANDLER_OBJECT    )hThisObject;
    PCCSP_CWMP_TCPCR_HANDLER_PROPERTY    pProperty     = (PCCSP_CWMP_TCPCR_HANDLER_PROPERTY  )&pMyObject->Property;
    PANSC_DAEMON_SERVER_TCP_OBJECT  pTcpServer    = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hTcpServer;
    char  buf[64]      = {0};

    if ( pProperty->HostPort == 0 && pTcpServer )
    {
        CcspTr069PaTraceDebug(("Port is 0 on current TcpServer: Server will be removed!!!\n"));
        pTcpServer->Remove((ANSC_HANDLE)pTcpServer);
        pMyObject->hTcpServer   = (ANSC_HANDLE)NULL;
    }
    else if ( !pTcpServer && pProperty->HostPort != 0 )
    {
        if ( bIsComcastImage() ) {

           // If HostAddress value is zero, then bind the outbound interface's ip address
           if( pProperty->HostAddress.Value == 0)
           {
              CcspTr069PaTraceInfo(("%s, HostAddress value is 0\n",__FUNCTION__));
              token_t  se_token;
              int      se_fd = s_sysevent_connect(&se_token);
              if (0 > se_fd) 
              {
                 CcspTr069PaTraceError(("%s, sysevent_connect failed!!!\n",__FUNCTION__));
                 //return ERR_SYSEVENT_CONN;
              }
              else
              {
                 // Get ipv4 address from sysevent
                 if( 0 == sysevent_get(se_fd, se_token, "ipv4_wan_ipaddr", buf, sizeof(buf)) && '\0' != buf[0] )
                 {
                    CcspTr069PaTraceInfo(("%s, ipv4_wan_ipaddr got from sysevent is: %s\n",__FUNCTION__,buf));
                    pProperty->HostAddress.Value = _ansc_inet_addr(buf);
                    CcspTr069PaTraceInfo(("%s,pProperty->HostAddress.Value: %lu\n",__FUNCTION__,pProperty->HostAddress.Value));
                 }
                 else
                 {
                  // If sysevent fails, let TR69 bind on 0.0.0.0
                  CcspTr069PaTraceError(("%s, sysevent_get failed to get value of ipv4_wan_ipaddr!!!\n",__FUNCTION__));
                 }
              }
           }
       
           CcspTr069PaTraceInfo(("%s, Call AnscCreateDaemonServerTcp\n",__FUNCTION__));
        }
        pTcpServer =
            (PANSC_DAEMON_SERVER_TCP_OBJECT)AnscCreateDaemonServerTcp
                (
                    pMyObject->hContainerContext,
                    (ANSC_HANDLE)pMyObject,
                    (ANSC_HANDLE)NULL
                );

        if ( !pTcpServer )
        {
            CcspTr069PaTraceError(("Something wrong in AnscCreateDaemonServerTCP.\n"));
            return  ANSC_STATUS_RESOURCES;
        }
        else
        {
            pMyObject->hTcpServer = (ANSC_HANDLE)pTcpServer;
        }

        pTcpServer->SetWorker
            (
                (ANSC_HANDLE)pTcpServer,
                pMyObject->hDstoWorker,
                sizeof(ANSC_DSTO_WORKER_OBJECT)
            );
    }

    CcspTr069PaTraceInfo(("TCP server created successfully.\n"));

    return  ANSC_STATUS_SUCCESS;
}