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;
}
Ejemplo n.º 2
0
static void
CcspTr069PaSsp_XML_GetOneItemByName
    (
        PANSC_XML_DOM_NODE_OBJECT  pRootNode,
        char*                      ItemName,
        char**                     retVal
     )
{
    PANSC_XML_DOM_NODE_OBJECT pChildNode  = NULL;
    int                       uLength     = 511;
    char                      buffer[512] = {0};

    if (pRootNode && retVal && ItemName)
    {
        if(*retVal) { AnscFreeMemory(*retVal); *retVal=NULL; }
        uLength=511;
        pChildNode = (PANSC_XML_DOM_NODE_OBJECT) AnscXmlDomNodeGetChildByName(pRootNode, ItemName);
        if(pChildNode != NULL  && 
           pChildNode->GetDataString(pChildNode, NULL, buffer, &uLength) == ANSC_STATUS_SUCCESS &&
           uLength > 0)
        {
            *retVal = CcspTr069PaCloneString(buffer);
        }
    }    
    CcspTr069PaTraceDebug(("%s: %s = %s\n", __FUNCTION__, (ItemName)?(ItemName):"NULL", (*retVal)?(*retVal):"NULL"));                                                     
    //    fprintf(stderr, "%s: %s = %s\n", __FUNCTION__, (ItemName)?(ItemName):"NULL", (*retVal)?(*retVal):"NULL");
}
Ejemplo n.º 3
0
static ANSC_STATUS  
CcspTr069PaSsp_XML_GetMultipleItemWithSameName
    (
        PANSC_XML_DOM_NODE_OBJECT   pRootNode,
        char*                       ItemName,
        char**                      retVal
    )
{
    ANSC_STATUS                     returnStatus       = ANSC_STATUS_SUCCESS;
    PANSC_XML_DOM_NODE_OBJECT       pChildNode         = (PANSC_XML_DOM_NODE_OBJECT)NULL;
    char                            buffer[512]        = {0};
    ULONG                           uLength            = 511; 
    
    if (pRootNode && ItemName && retVal)
    {
        if(*retVal) { CcspTr069PaFreeMemory(*retVal); *retVal = NULL; }
        
        pChildNode = (PANSC_XML_DOM_NODE_OBJECT)
            AnscXmlDomNodeGetChildByName(pRootNode, ItemName);
        
        while( pChildNode != NULL)
        {
            if (AnscEqualString(pChildNode->Name, ItemName, TRUE))
            {
                uLength = 511;  // uLength: passes in max buffer length; gets out actual length
                
                if (pChildNode->GetDataString(pChildNode, NULL, buffer, &uLength) == ANSC_STATUS_SUCCESS && 
                    uLength > 0) 
                {
                    if(*retVal) 
                    {
                        char* sptr = (char*)CcspTr069PaAllocateMemory(AnscSizeOfString(*retVal)+1+uLength+1);
                        if(sptr == NULL) 
                        {
                            CcspTr069PaTraceWarning(("Failed to reallocate returnCA\n"));
                            CcspTr069PaFreeMemory(*retVal);
                            *retVal = NULL;
                            returnStatus =  ANSC_STATUS_RESOURCES;
                            goto EXIT;
                        }

                        _ansc_sprintf(sptr, "%s,%s", *retVal, buffer);
                        CcspTr069PaFreeMemory(*retVal);
                        *retVal = sptr;
                    }
                    else *retVal = CcspTr069PaCloneString(buffer);
                }
            }
            
            pChildNode = (PANSC_XML_DOM_NODE_OBJECT) AnscXmlDomNodeGetNextChild(pRootNode, pChildNode);
        }
        CcspTr069PaTraceDebug(("%s: %s = %s\n", __FUNCTION__, (ItemName)?(ItemName):"NULL", (*retVal)?(*retVal):"NULL"));
        //        fprintf(stderr, "%s: %s = %s\n", __FUNCTION__, (ItemName)?(ItemName):"NULL", (*retVal)?(*retVal):"NULL");
    }

 EXIT:
    return returnStatus;
}
ANSC_STATUS
CcspCwmpsoCloseConnection
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus       = ANSC_STATUS_SUCCESS;
    PCCSP_CWMP_SESSION_OBJECT       pMyObject          = (PCCSP_CWMP_SESSION_OBJECT     )hThisObject;
    PANSC_TIMER_DESCRIPTOR_OBJECT   pSessionTimerObj   = (PANSC_TIMER_DESCRIPTOR_OBJECT)pMyObject->hSessionTimerObj;
    PCCSP_CWMP_ACS_CONNECTION_OBJECT pCcspCwmpAcsConnection = (PCCSP_CWMP_ACS_CONNECTION_OBJECT  )pMyObject->hCcspCwmpAcsConnection;
    PCCSP_CWMP_CPE_CONTROLLER_OBJECT pCcspCwmpCpeController = (PCCSP_CWMP_CPE_CONTROLLER_OBJECT  )pMyObject->hCcspCwmpCpeController;
    PCCSP_CWMP_PROCESSOR_OBJECT     pCcspCwmpProcessor  = (PCCSP_CWMP_PROCESSOR_OBJECT   )pMyObject->hCcspCwmpProcessor;
    PCCSP_CWMP_MPA_INTERFACE        pCcspCwmpMpaIf         = (PCCSP_CWMP_MPA_INTERFACE          )pCcspCwmpProcessor->GetCcspCwmpMpaIf((ANSC_HANDLE)pCcspCwmpProcessor);
    int                             DelayTimes        = 10; 

    pSessionTimerObj->Stop((ANSC_HANDLE)pSessionTimerObj);

    pMyObject->bActive      = FALSE;
    pMyObject->SessionState = CCSP_CWMPSO_SESSION_STATE_idle;

    /* would cause crash if AsyncProcessEvent is freed asynchronously */
    /*
    CcspTr069PaTraceDebug(("CcspCwmpsoCloseConnection -> SetEvent\n"));
    AnscSetEvent(&pMyObject->AsyncProcessEvent);
    */
    CcspTr069PaTraceDebug(("CcspCwmpsoCloseConnection -> waiting for all tasks exit ...\n"));

    while ( pMyObject->AsyncTaskCount > 0 && DelayTimes > 0 )
    {
        AnscSleep(500);
        DelayTimes --;
    }

    CcspTr069PaTraceDebug(("CcspCwmpsoCloseConnection -> Close\n"));
    pCcspCwmpAcsConnection->Close((ANSC_HANDLE)pCcspCwmpAcsConnection);

    CcspTr069PaTraceDebug(("CcspCwmpsoCloseConnection -> UnlockWriteAccess\n"));
    pCcspCwmpMpaIf->UnlockWriteAccess(pCcspCwmpMpaIf->hOwnerContext);

    return  ANSC_STATUS_SUCCESS;
}
/**********************************************************************

    prototype:

        ANSC_STATUS
        CcspCwmpAcscoHttpSessionClosed
            (
                ANSC_HANDLE                 hThisObject
            );

    description:

        This function is called whenever the http session is closed

    argument:   ANSC_HANDLE                 hThisObject
                This handle is actually the pointer of this object
                itself.

    return:     status of operation.

**********************************************************************/
ANSC_STATUS
CcspCwmpAcscoHttpSessionClosed
    (
        ANSC_HANDLE                 hThisObject
    )
{
    PCCSP_CWMP_ACS_CONNECTION_OBJECT pMyObject       = (PCCSP_CWMP_ACS_CONNECTION_OBJECT)hThisObject;
    PCCSP_CWMP_SESSION_OBJECT        pWmpSession     = (PCCSP_CWMP_SESSION_OBJECT   )pMyObject->hCcspCwmpSession;

    CcspTr069PaTraceDebug(("CcspCwmpAcscoHttpSessionClosed...\n"));

    if( pWmpSession != NULL)
    {
        pWmpSession->NotifySessionClosed(pWmpSession);
    }

    return ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
CcspCwmpsoSaveCwmpEvent
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus       = ANSC_STATUS_SUCCESS;
    PCCSP_CWMP_SESSION_OBJECT        pMyObject          = (PCCSP_CWMP_SESSION_OBJECT   )hThisObject;
    PCCSP_CWMP_EVENT                pCcspCwmpEvent     = (PCCSP_CWMP_EVENT           )NULL;
    PCCSP_CWMP_CPE_CONTROLLER_OBJECT     pCcspCwmpCpeController = (PCCSP_CWMP_CPE_CONTROLLER_OBJECT)pMyObject->hCcspCwmpCpeController;
    PCCSP_CWMP_CFG_INTERFACE             pCcspCwmpCfgIf         = (PCCSP_CWMP_CFG_INTERFACE        )pCcspCwmpCpeController->GetCcspCwmpCfgIf((ANSC_HANDLE)pCcspCwmpCpeController);
    char                            pSavedEvents[CCSP_CWMP_SAVED_EVENTS_MAX_LEN] = { 0 };
    PCHAR                           pCurBuf            = pSavedEvents;
    ULONG                           i                  = 0;
    ULONG                           uLength            = 0;
    char*                           pRootObjName       = pCcspCwmpCpeController->GetRootObject((ANSC_HANDLE)pCcspCwmpCpeController);
    BOOL                            bRootDevice        = AnscEqualString(pRootObjName, DM_ROOTNAME, FALSE);

    /*
     * All the undiscarded events will be saved in a string seperated by a ',' and put as 
     * the value of parameter "(InternetGateway)Device.ManagementServer.SavedEvents".
     */
    for( i = 0; i < pMyObject->EventCount; i ++)
    { 
        pCcspCwmpEvent = (PCCSP_CWMP_EVENT)pMyObject->EventArray[i];

        if( CcspCwmpIsUndiscardedEvent(pCcspCwmpEvent->EventCode))
        {
            if( pCurBuf != pSavedEvents)
            {
                pCurBuf[0] = ',';
                pCurBuf ++;
            }

            uLength = AnscSizeOfString(pCcspCwmpEvent->EventCode);

            if( pCurBuf + uLength >= pSavedEvents + CCSP_CWMP_SAVED_EVENTS_MAX_LEN)
            {
                CcspTr069PaTraceWarning(("Too many events to save, ignored.\n"));

                break;
            }

            AnscCopyMemory(pCurBuf, pCcspCwmpEvent->EventCode, uLength);
            pCurBuf   += uLength;
            pCurBuf[0]=  '+';
            pCurBuf   ++;

            if( pCcspCwmpEvent->CommandKey )
            {
                uLength = AnscSizeOfString(pCcspCwmpEvent->CommandKey);

                if( uLength > 0)
                {
                    if( pCurBuf + uLength >= pSavedEvents + CCSP_CWMP_SAVED_EVENTS_MAX_LEN)
                    {
                        CcspTr069PaTraceWarning(("Too many events to save, ignored.\n"));

                        break;
                    }

                    AnscCopyMemory(pCurBuf, pCcspCwmpEvent->EventCode, uLength);
                    pCurBuf   += uLength;
                }
            }
        }
    }

    if( AnscSizeOfString(pSavedEvents) > 0)
    {
        char                        psmKeyPrefixed[CCSP_TR069PA_PSM_NODE_NAME_MAX_LEN + 16];

        CcspCwmpPrefixPsmKey(psmKeyPrefixed, pCcspCwmpCpeController->SubsysName, CCSP_TR069PA_PSM_KEY_SavedEvents);

        CcspTr069PaTraceDebug(("Save the event to the registry before reboot:\n%s\n", pSavedEvents));

        returnStatus = 
            pCcspCwmpCpeController->SaveCfgToPsm
                (
                    (ANSC_HANDLE)pCcspCwmpCpeController,
                    psmKeyPrefixed,
                    pSavedEvents
                );
    }

    return  returnStatus;
}
ANSC_STATUS
CcspCwmpsoAddModifiedParameter
    (
        ANSC_HANDLE                 hThisObject,
        char*                       pParamName,
        char*                       pParamValue,
        ULONG                       CwmpDataType,
        BOOL                        bConnectNow
    )
{
    ANSC_STATUS                     returnStatus       		= ANSC_STATUS_SUCCESS;
    PCCSP_CWMP_SESSION_OBJECT       pMyObject          		= (PCCSP_CWMP_SESSION_OBJECT)hThisObject;
    PCCSP_CWMP_ACS_CONNECTION_OBJECT     
									pCcspCwmpAcsConnection 	= (PCCSP_CWMP_ACS_CONNECTION_OBJECT)pMyObject->hCcspCwmpAcsConnection;
    PCCSP_CWMP_CPE_CONTROLLER_OBJECT     
									pCcspCwmpCpeController 	= (PCCSP_CWMP_CPE_CONTROLLER_OBJECT)pMyObject->hCcspCwmpCpeController;
    PCCSP_CWMP_PROCESSOR_OBJECT     pCcspCwmpProcessor  	= (PCCSP_CWMP_PROCESSOR_OBJECT)pMyObject->hCcspCwmpProcessor;
    ULONG                           i                  		= 0;
    ULONG                           bExist             		= FALSE;

    CcspTr069PaTraceDebug(("AddModifiedParameter - '%s'\n", pParamName));

    if ( pMyObject->ModifiedParamCount >= CCSP_CWMPSO_MAX_PARAM_NUMBER )
    {
        CcspTr069PaFreeMemory(pParamName);

        return  ANSC_STATUS_RESOURCES;
    }

    for ( i = 0; i < pMyObject->ModifiedParamCount; i++ )
    {
        if ( pMyObject->ModifiedParamArray[i] )
        {
            if ( AnscEqualString
                    (
                        pParamName,
                        pMyObject->ModifiedParamArray[i],
                        TRUE
                    ) )
            {
                bExist = TRUE;

                if ( pMyObject->ModifiedParamValueArray[i] )
                {
                    CcspTr069PaFreeMemory(pMyObject->ModifiedParamValueArray[i]);
                }

                pMyObject->ModifiedParamValueArray[i] = CcspTr069PaCloneString(pParamValue);
                pMyObject->ModifiedParamTypeArray [i] = CwmpDataType;

                break;
            }
        }
    }

    if( !bExist)
    {
        pMyObject->ModifiedParamArray     [pMyObject->ModifiedParamCount]   = CcspTr069PaCloneString(pParamName);
        pMyObject->ModifiedParamValueArray[pMyObject->ModifiedParamCount]   = CcspTr069PaCloneString(pParamValue);
        pMyObject->ModifiedParamTypeArray [pMyObject->ModifiedParamCount++] = CwmpDataType;
    }

    /*
     * Bin: We are supposed to add "ValueChange" event for passive notification as well.
     */
    if ( TRUE )
    {
        PCCSP_CWMP_EVENT            pCcspCwmpEvent = (PCCSP_CWMP_EVENT)CcspTr069PaAllocateMemory(sizeof(CCSP_CWMP_EVENT));

        if ( !pCcspCwmpEvent )
        {
            return  ANSC_STATUS_RESOURCES;
        }
        else
        {
            pCcspCwmpEvent->EventCode  = CcspTr069PaCloneString(CCSP_CWMP_INFORM_EVENT_NAME_ValueChange);
            pCcspCwmpEvent->CommandKey = NULL;
        }

        returnStatus =
            pMyObject->AddCwmpEvent
                (
                    (ANSC_HANDLE)pMyObject,
                    pCcspCwmpEvent,
                    bConnectNow && pCcspCwmpCpeController->bBootInformSent
                );
    }

    return  returnStatus;
}
ANSC_STATUS
CcspCwmpsoAddCwmpEvent
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hCwmpEvent,
        BOOL                        bConnectNow
    )
{
    ANSC_STATUS                     returnStatus       = ANSC_STATUS_SUCCESS;
    PCCSP_CWMP_SESSION_OBJECT       pMyObject          = (PCCSP_CWMP_SESSION_OBJECT   )hThisObject;
    PCCSP_CWMP_PROCESSOR_OBJECT     pCcspCwmpProcessor = (PCCSP_CWMP_PROCESSOR_OBJECT )pMyObject->hCcspCwmpProcessor;
    PCCSP_CWMP_EVENT                pCcspCwmpEvent     = (PCCSP_CWMP_EVENT           )hCwmpEvent;
    PCCSP_CWMP_EVENT                pCcspCwmpEventExist= (PCCSP_CWMP_EVENT           )NULL;
    BOOL                            bExist             = FALSE;
    ULONG                           i                  = 0;

    if ( pMyObject->EventCount >= CCSP_CWMPSO_MAX_EVENT_NUMBER )
    {
        CcspCwmpFreeEvent(pCcspCwmpEvent);
	}
	else
	{
        /*
         *  Bin Zhu updated here on 12/18/2006
         *  According to WT151, for all the single event (starts with a number "0" - "9"),
         *  If there's only already in the array, the new one will be discarded.
         */
        if( pCcspCwmpEvent->EventCode[0] >= '0' && pCcspCwmpEvent->EventCode[0] <= '9')
        {
            for( i = 0; i < pMyObject->EventCount; i ++)
            {
                pCcspCwmpEventExist = (PCCSP_CWMP_EVENT)pMyObject->EventArray[i];

                if( AnscEqualString(pCcspCwmpEvent->EventCode, pCcspCwmpEventExist->EventCode, TRUE))
                {
                    bExist = TRUE;

                    CcspTr069PaTraceWarning(("The event '%s' is already there, discarded.\n", pCcspCwmpEvent->EventCode));

                    break;
                }
            }
        } 
        else 
        if ( pCcspCwmpEvent->EventCode[0] >= 'M' )
        {
            for( i = 0; i < pMyObject->EventCount; i ++)
            {
                pCcspCwmpEventExist = (PCCSP_CWMP_EVENT)pMyObject->EventArray[i];

                if ( AnscEqualString(pCcspCwmpEvent->EventCode, pCcspCwmpEventExist->EventCode, TRUE) &&
                     ( (!pCcspCwmpEvent->CommandKey && !pCcspCwmpEventExist->CommandKey) || 
                        (pCcspCwmpEvent->CommandKey && pCcspCwmpEventExist->CommandKey &&
                         AnscEqualString(pCcspCwmpEvent->CommandKey, pCcspCwmpEventExist->CommandKey, TRUE)) ) )
                {
                    bExist = TRUE;

                    CcspTr069PaTraceWarning
                        ((
                            "The event '%s' with CommandKey '%s' is already there, discarded.\n", 
                            pCcspCwmpEvent->EventCode,
                            pCcspCwmpEvent->CommandKey
                        ));

                    break;
                }
            }
        }

        if( !bExist )
        {
  		    pMyObject->EventArray[pMyObject->EventCount++] = (ANSC_HANDLE)pCcspCwmpEvent;
            CcspTr069PaTraceDebug(("<RT> Event '%s' with CommandKey '%s' added at location '%d'\n",
                                   pCcspCwmpEvent->EventCode, pCcspCwmpEvent->CommandKey, pMyObject->EventCount));
        }
        else
        {
            CcspCwmpFreeEvent(pCcspCwmpEvent);
        }
	}

    if ( bConnectNow )
    {
		PANSC_TIMER_DESCRIPTOR_OBJECT   pDelayedActiveNotifTimerObj
                                                        = (PANSC_TIMER_DESCRIPTOR_OBJECT)pMyObject->hDelayedActiveNotifTimerObj;
    	PCCSP_CWMP_PROCESSOR_PROPERTY   pProperty       = (PCCSP_CWMP_PROCESSOR_PROPERTY)&pCcspCwmpProcessor->Property;
		BOOL							bInformDelayed  = FALSE;
        PCCSP_CWMP_EVENT                pFirstEvent     = (PCCSP_CWMP_EVENT)pMyObject->EventArray[0];
	
		/* Active Notification Throttling */	
		if ( pMyObject->EventCount == 1 /* "4 VALUE CHANGE" event is the only one to trigger Inform */ && 
			 AnscEqualString(pFirstEvent->EventCode, CCSP_CWMP_INFORM_EVENT_NAME_ValueChange, TRUE) &&
			 pProperty->DefActiveNotifThrottle != 0 && 
			 pProperty->LastActiveNotifTime != 0 )
		{
			/* calculate the delay inform timer interval */
			ULONG						ulTimeNow = AnscGetTickInSeconds();
			ULONG						ulDelta   = 0;
			ULONG						ulInterval= 0;

			if ( ulTimeNow >= pProperty->LastActiveNotifTime )
			{
				ulDelta = ulTimeNow - pProperty->LastActiveNotifTime;
			}
			else
			{
				ulDelta = 0xFFFFFFFF - pProperty->LastActiveNotifTime + ulTimeNow;
			}

			if ( ulDelta < pProperty->DefActiveNotifThrottle )
			{
				bInformDelayed = TRUE;

				ulInterval = pProperty->DefActiveNotifThrottle - ulDelta;
 
    			CcspTr069PaTraceDebug(("Active notification will be delayed by %u seconds\n", ulInterval));

                if ( !pMyObject->bDelayedActiveNotifTimerScheduled )
                {
		            pDelayedActiveNotifTimerObj->SetInterval((ANSC_HANDLE)pDelayedActiveNotifTimerObj, ulInterval * 1000);
	    	        pDelayedActiveNotifTimerObj->Start((ANSC_HANDLE)pDelayedActiveNotifTimerObj);
    				pMyObject->bDelayedActiveNotifTimerScheduled = TRUE;
                }
 			}
		}


		if ( !bInformDelayed )
		{
            ULONG                   ulActiveSessions    = pCcspCwmpProcessor->GetActiveWmpSessionCount((ANSC_HANDLE)pCcspCwmpProcessor, TRUE);

            if ( ulActiveSessions == 0 )
            {
        	    pMyObject->SessionState = CCSP_CWMPSO_SESSION_STATE_connectNow;
    	        returnStatus            =
        	        pCcspCwmpProcessor->SignalSession
            	        (
                	        (ANSC_HANDLE)pCcspCwmpProcessor,
                    	    (ANSC_HANDLE)pMyObject
	                    );
            }
            else
            {
                pMyObject->bInformWhenActive = TRUE;
            }
		}
    }

    return 	returnStatus; 
}
ANSC_STATUS
CcspCwmpAcscoHttpAddCookie
    (
        ANSC_HANDLE                 hThisObject,
        PCHAR                       pCookie
    )
{
    PCCSP_CWMP_ACS_CONNECTION_OBJECT pMyObject         = (PCCSP_CWMP_ACS_CONNECTION_OBJECT)hThisObject;
    ANSC_STATUS                     returnStatus      = ANSC_STATUS_SUCCESS;
    PHTTP_SIMPLE_CLIENT_OBJECT      pHttpSimpleClient = (PHTTP_SIMPLE_CLIENT_OBJECT)pMyObject->hHttpSimpleClient;
    PHTTP_HFP_INTERFACE             pHttpHfpIf        = (PHTTP_HFP_INTERFACE)pHttpSimpleClient->GetHfpIf((ANSC_HANDLE)pHttpSimpleClient);
    char*                           pCookieValue      = NULL;
    PHTTP_HFO_SET_COOKIE            pHfoSetCookie     = NULL;

    if ( !pCookie || AnscSizeOfString(pCookie) <= 5)
    {
        CcspTr069PaTraceDebug(("!!!Empty Cookie, ignored.\n"));

        return ANSC_STATUS_SUCCESS;
    }

    if ( pMyObject->NumCookies >= CCSP_CWMP_ACSCO_MAX_COOKIE )
    {
        CcspTr069PaTraceDebug(("!!!Too many cookies, over the limit %d.\n", CCSP_CWMP_ACSCO_MAX_COOKIE));

        return ANSC_STATUS_DISCARD;
    }

    pCookieValue = (PCHAR)CcspTr069PaAllocateMemory(AnscSizeOfString(pCookie) + 64);

    if( NULL == pCookieValue )
    {
        return ANSC_STATUS_RESOURCES;
    }

    pHfoSetCookie = (PHTTP_HFO_SET_COOKIE)pHttpHfpIf->ParseHeader(pHttpHfpIf->hOwnerContext, pCookie, AnscSizeOfString(pCookie));

    if ( pHfoSetCookie )
    {
        ULONG                       ulCookieSize = 0;
        int                         nIndex;
        ULONG                       i;

        /* play a trick here - suppose the definitions of Cookie and Set-Cookie/2 are the same */
        pHfoSetCookie->HeaderId = HTTP_HEADER_ID_COOKIE;
        pHfoSetCookie->Flags &= ~HTTP_FIELD_FLAG_VALUE_PRESENT;
        pHfoSetCookie->Flags &= ~HTTP_FIELD_FLAG_LINE_PRESENT;

        ulCookieSize = pHttpHfpIf->GetHeaderSize(pHttpHfpIf->hOwnerContext, (ANSC_HANDLE)pHfoSetCookie);
        pHttpHfpIf->BuildHeader(pHttpHfpIf->hOwnerContext, (ANSC_HANDLE)pHfoSetCookie, pCookieValue, ulCookieSize);
        pCookieValue[ulCookieSize] = 0;

        /* remove old cookies */
        for ( i = 0; i < pHfoSetCookie->CookieCount; i ++ )
        {
            nIndex = pMyObject->FindCookie((ANSC_HANDLE)pMyObject, pHfoSetCookie->CookieArray[i].Name);
            if ( nIndex >= 0 )
            {
                pMyObject->DelCookie((ANSC_HANDLE)pMyObject, (ULONG)nIndex);
            }
        }

        pMyObject->Cookies[pMyObject->NumCookies++] = CcspTr069PaCloneString(pCookieValue + 8);

        CcspTr069PaFreeMemory(pHfoSetCookie);
    }

    CcspTr069PaFreeMemory(pCookieValue);

    return returnStatus;
}
ANSC_STATUS
CcspCwmpAcscoHttpBspNotify
    (
        ANSC_HANDLE                 hThisObject,
        ULONG                       ulEvent,
        ULONG                       ulError,
        ANSC_HANDLE                 hReqContext,
        ANSC_HANDLE                 hBmoReq,
        ANSC_HANDLE                 hBmoRep
    )
{
    ANSC_STATUS                      returnStatus           = ANSC_STATUS_SUCCESS;
    PANSC_ACS_INTERN_HTTP_CONTENT    pHttpGetReq            = (PANSC_ACS_INTERN_HTTP_CONTENT )hReqContext;
    PCCSP_CWMP_ACS_CONNECTION_OBJECT pMyObject              = (PCCSP_CWMP_ACS_CONNECTION_OBJECT)hThisObject;
    PCCSP_CWMP_SESSION_OBJECT        pWmpSession            = (PCCSP_CWMP_SESSION_OBJECT   )pMyObject->hCcspCwmpSession;
    PCCSP_CWMP_CPE_CONTROLLER_OBJECT pCcspCwmpCpeController = (PCCSP_CWMP_CPE_CONTROLLER_OBJECT)pWmpSession->hCcspCwmpCpeController;
    PCCSP_CWMP_STAT_INTERFACE        pCcspCwmpStatIf        = (PCCSP_CWMP_STAT_INTERFACE)pCcspCwmpCpeController->hCcspCwmpStaIf;
    PHTTP_BMO_REP_OBJECT             pHttpBmoRep            = (PHTTP_BMO_REP_OBJECT      )hBmoRep;

    switch ( ulEvent )
    {
        case    HTTP_BSP_EVENT_BAD_REQUEST :
        case    HTTP_BSP_EVENT_CANNOT_RESOLVE_NAME :
        case    HTTP_BSP_EVENT_SERVER_UNAVAILABLE :
        case    HTTP_BSP_EVENT_NETWORK_FAILURE :
        case    HTTP_BSP_EVENT_TIMEOUT :

                if( pHttpGetReq != NULL && pHttpGetReq->CompleteStatus == ANSC_STATUS_RESET_SESSION)
                {
                    break;
                }

                if( pHttpGetReq && pHttpGetReq->ulContentSize == 0)
                {
                    pHttpGetReq->CompleteStatus = ANSC_STATUS_FAILURE;

                    AnscSetEvent(&pHttpGetReq->CompleteEvent);
                }

                CcspTr069PaTraceDebug(("HttpClient Notify: %d\n", (int)ulEvent));

                if( pCcspCwmpStatIf)
                {
                    pCcspCwmpStatIf->IncTcpFailure(pCcspCwmpStatIf->hOwnerContext);
                }

                CcspCwmpAcscoHttpSessionClosed(hThisObject);

                break;

        case    HTTP_BSP_EVENT_SOCKET_CLOSED:

                /*
                 * During the test with Motive ACS, we observed that the web server
                 * close the connection after sending chanllenge back, which is an option.
                 *
                 * In that case, we need to start a new session and send back the authentication
                 * information.
                 */
                if( pHttpGetReq)
                {
                    char*           pHeaderLocation = NULL;
                    
                    if ( pHttpBmoRep )
                    {
                        pHeaderLocation = pHttpBmoRep->GetHeaderValueByName((ANSC_HANDLE)pHttpBmoRep, "Location");
                    }

                    if ( pHeaderLocation && AnscSizeOfString(pHeaderLocation) != 0 )
                    {
                        ULONG       ulCode = pHttpBmoRep->GetCode((ANSC_HANDLE)pHttpBmoRep);
                        CcspTr069PaTraceInfo(("ACS URL moved (HTTP code=%u) to: %s\n", ulCode, pHeaderLocation));

                        pHttpGetReq->ulContentSize = AnscSizeOfString(pHeaderLocation);
                        pHttpGetReq->pContent      = CcspTr069PaCloneString(pHeaderLocation);
                        pHttpGetReq->bIsRedirect   = TRUE;
                    }

                    pHttpGetReq->CompleteStatus = ANSC_STATUS_RESET_SESSION;

                    AnscSetEvent(&pHttpGetReq->CompleteEvent);
                }

                CcspTr069PaTraceDebug(("HttpClient Notify: SOCKET CLOSED\n"));

                /* CcspCwmpAcscoHttpSessionClosed(hThisObject); */

                break;

        case HTTP_BSP_EVENT_TLS_TIMEOUT:
        case HTTP_BSP_EVENT_TLS_ERROR:

                CcspTr069PaTraceDebug(("HttpClient TLS Notify: %d\n", ulEvent));

                if( pCcspCwmpStatIf)
                {
                    pCcspCwmpStatIf->IncTlsFailure(pCcspCwmpStatIf->hOwnerContext);
                }

                if ( pHttpGetReq )
                {
                    pHttpGetReq->CompleteStatus = ANSC_STATUS_FAILURE;
                    AnscSetEvent(&pHttpGetReq->CompleteEvent);
                }

                break;


        default :

                CcspTr069PaTraceDebug(("HttpClient Notify: %d\n", ulEvent));

                if ( pHttpGetReq )
                {
                    pHttpGetReq->CompleteStatus = ANSC_STATUS_FAILURE;
                    AnscSetEvent(&pHttpGetReq->CompleteEvent);
                }

                break;
    }

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
CcspCwmpAcscoHttpBspBrowse
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hBmoReq,
        ANSC_HANDLE                 hBmoRep,
        ANSC_HANDLE                 hReqContext
    )
{
    ANSC_STATUS                     returnStatus      = ANSC_STATUS_SUCCESS;
    PCCSP_CWMP_ACS_CONNECTION_OBJECT pMyObject         = (PCCSP_CWMP_ACS_CONNECTION_OBJECT)hThisObject;
    PHTTP_BMO_REQ_OBJECT            pHttpBmoReq       = (PHTTP_BMO_REQ_OBJECT      )hBmoReq;
    PHTTP_BMO_REP_OBJECT            pHttpBmoRep       = (PHTTP_BMO_REP_OBJECT      )hBmoRep;
    PANSC_ACS_INTERN_HTTP_CONTENT   pHttpGetReq       = (PANSC_ACS_INTERN_HTTP_CONTENT )hReqContext;
    PHTTP_RESPONSE_INFO             pHttpRepInfo      = (PHTTP_RESPONSE_INFO       )pHttpBmoRep->GetRepInfo ((ANSC_HANDLE)pHttpBmoRep);
    ULONG                           ulResponseSize    = (ULONG                     )pHttpBmoRep->GetBodySize((ANSC_HANDLE)pHttpBmoRep);
    char*                           pHttpResponse     = (char*                     )NULL;
    char*                           pHeaderLocation   = NULL;
    char*                           pCookie           = NULL;
    ULONG                           ulCode            = 0;
    char*                           pCookieHeader     = NULL;
    ULONG                           ulCookieIndex     = 0;
    BOOL                            bCookiesRemoved   = FALSE;

    if ( pHttpGetReq == NULL)
    {
        return ANSC_STATUS_FAILURE;
    }

    ulCode = pHttpBmoRep->GetCode((ANSC_HANDLE)pHttpBmoRep);

    if( HTTP_STATUS_NO_CONTENT == ulCode) /* ACS has nothing to say */
    {
        if( pHttpGetReq != NULL)
        {
            pHttpGetReq->ulContentSize = 0;
            pHttpGetReq->pContent      = NULL;
            pHttpGetReq->bIsRedirect   = FALSE;
        }

        returnStatus = ANSC_STATUS_SUCCESS;

        goto EXIT1;
    }
    else if( HTTP_STATUS_MOVED_PERMANENTLY != ulCode &&
             HTTP_STATUS_FOUND != ulCode             &&
             HTTP_STATUS_OK != ulCode                &&
             HTTP_STATUS_UNAUTHORIZED != ulCode		 &&
			 HTTP_STATUS_TEMP_REDIRECT != ulCode
           )
    {
        returnStatus = ANSC_STATUS_FAILURE;

        CcspTr069PaTraceDebug(("HttpClient returned code: %d\n", (int)ulCode));

        goto  EXIT1;
    }

    /* save Authorization header value */
    if ( TRUE )
    {
        char*                       pAuthHeaderValue   = NULL;

        /* Authorization header in request */
        pAuthHeaderValue = pHttpBmoReq->GetHeaderValueById((ANSC_HANDLE)pHttpBmoReq, HTTP_HEADER_ID_AUTHORIZATION);

        if ( pMyObject->AuthHeaderValue ) CcspTr069PaFreeMemory(pMyObject->AuthHeaderValue);
        pMyObject->AuthHeaderValue = CcspTr069PaCloneString(pAuthHeaderValue);
    }

    /* look for Set-Cookie headers */
    pCookie = pHttpBmoRep->GetHeaderValueById2((ANSC_HANDLE)pHttpBmoRep, HTTP_HEADER_ID_SET_COOKIE2, ulCookieIndex);

    if ( pCookie && AnscSizeOfString(pCookie) > 0 )
    {
        /*
        pMyObject->RemoveCookies((ANSC_HANDLE)pMyObject);
        bCookiesRemoved = TRUE;
        */

        while ( pCookie != NULL && AnscSizeOfString(pCookie) > 0)
        {
            pCookieHeader = CcspTr069PaAllocateMemory(AnscSizeOfString(pCookie) + 16);

            if ( pCookieHeader )
                _ansc_sprintf(pCookieHeader, "Set-Cookie2: %s", pCookie);

            pMyObject->AddCookie((ANSC_HANDLE)pMyObject, pCookieHeader);
            CcspTr069PaFreeMemory(pCookieHeader);

            pCookie = pHttpBmoRep->GetHeaderValueById2((ANSC_HANDLE)pHttpBmoRep, HTTP_HEADER_ID_SET_COOKIE2, ++ulCookieIndex);
        }
    }

    /* If Set-Cookie and Set-Cookie2 co-exist happily, we save them all */
    ulCookieIndex = 0;
    pCookie = pHttpBmoRep->GetHeaderValueById2((ANSC_HANDLE)pHttpBmoRep, HTTP_HEADER_ID_SET_COOKIE, ulCookieIndex);

    if( pCookie != NULL && AnscSizeOfString(pCookie) > 0)
    {
        /*
        if ( !bCookiesRemoved )
        {
            pMyObject->RemoveCookies((ANSC_HANDLE)pMyObject);
            bCookiesRemoved = TRUE;
        }
        */

        while ( pCookie && AnscSizeOfString(pCookie) )
        {
            pCookieHeader = CcspTr069PaAllocateMemory(AnscSizeOfString(pCookie) + 16);

            if ( pCookieHeader )
                _ansc_sprintf(pCookieHeader, "Set-Cookie: %s", pCookie);

            pMyObject->AddCookie((ANSC_HANDLE)pMyObject, pCookieHeader);
            CcspTr069PaFreeMemory(pCookieHeader);

            pCookie = pHttpBmoRep->GetHeaderValueById2((ANSC_HANDLE)pHttpBmoRep, HTTP_HEADER_ID_SET_COOKIE, ++ulCookieIndex);
        }
    }

    /*
    if ( !bCookiesRemoved )
    {
        CcspTr069PaTraceDebug(("No Cookie in the response.\n"));

        if( pMyObject->NumCookies != 0)
        {
            for ( i = 0; i < pMyObject->NumCookies; i ++ )
            {
                CcspTr069PaTraceDebug(("Keep the old cookie: %s\n", pMyObject->Cookies[i]));
            }
        }
        else
        {
            CcspTr069PaTraceDebug(("???No cookie exists...\n"));
        }
    }
    */

    if( HTTP_STATUS_UNAUTHORIZED == ulCode)
    {
        /* make sure if server sends back challenge, terminates the session if otherwise */
        char*                       pWwwAuth = NULL;

        pHttpGetReq->bUnauthorized = TRUE;
        
        pWwwAuth = pHttpBmoRep->GetHeaderValueByName((ANSC_HANDLE)pHttpBmoRep, "WWW-Authenticate");
        if ( pWwwAuth )
        {
            returnStatus = ANSC_STATUS_DO_IT_AGAIN; /* ANSC_STATUS_SUCCESS; */
        }
        else
        {
            returnStatus = ANSC_STATUS_FAILURE;
        }

        goto EXIT1;
    }

    if( ulCode == HTTP_STATUS_MOVED_PERMANENTLY || HTTP_STATUS_FOUND == ulCode || HTTP_STATUS_TEMP_REDIRECT == ulCode)
    {
        pHeaderLocation     = pHttpBmoRep->GetHeaderValueByName((ANSC_HANDLE)pHttpBmoRep, "Location"     );

        if( pHeaderLocation == NULL || AnscSizeOfString(pHeaderLocation) == 0)
        {
            returnStatus = ANSC_STATUS_FAILURE;

            goto  EXIT1;
        }

        CcspTr069PaTraceInfo(("ACS URL moved (HTTP code=%u) to: %s\n", ulCode, pHeaderLocation));

        pHttpGetReq->ulContentSize = AnscSizeOfString(pHeaderLocation);
        pHttpGetReq->pContent      = CcspTr069PaCloneString(pHeaderLocation);
        pHttpGetReq->bIsRedirect   = TRUE;

        /* notify underlying HTTP Webc Transaction object to clearn request
         * otherwise, in case ACS closes the socket first, we will get notified
         * again and current session will be terminated prematurely.
         */
        returnStatus = ANSC_STATUS_NO_MORE_DATA;
    }
    else
    {
        if ( ulResponseSize == 0 )
        {
             returnStatus = ANSC_STATUS_FAILURE;

            goto  EXIT1;
        }
        else
        {
            pHttpResponse = (char*)CcspTr069PaAllocateMemory(ulResponseSize + 1);  /* we must leave room for the NULL terminator */

            if ( !pHttpResponse )
            {
                returnStatus = ANSC_STATUS_RESOURCES;

                goto  EXIT1;
            }
            else
            {
                returnStatus =
                    pHttpBmoRep->CopyBodyFrom
                        (
                            (ANSC_HANDLE)pHttpBmoRep,
                            pHttpResponse,
                            &ulResponseSize
                        );
            }
        }

        pHttpGetReq->ulContentSize = ulResponseSize;
        pHttpGetReq->pContent      = (PVOID)pHttpResponse;
        pHttpGetReq->bIsRedirect   = FALSE;
    }

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

EXIT1:

    if ( pHttpGetReq )
    {
        pHttpGetReq->CompleteStatus = 
            (returnStatus == ANSC_STATUS_DO_IT_AGAIN || returnStatus == ANSC_STATUS_NO_MORE_DATA) ? ANSC_STATUS_SUCCESS : returnStatus;

        AnscSetEvent(&pHttpGetReq->CompleteEvent);
    }

    return  returnStatus;
}
ANSC_STATUS
CcspCwmpAcscoHttpBspPolish
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hBmoReq,
        ANSC_HANDLE                 hReqContext
    )
{
    PCCSP_CWMP_ACS_CONNECTION_OBJECT pMyObject       = (PCCSP_CWMP_ACS_CONNECTION_OBJECT)hThisObject;
    PANSC_ACS_INTERN_HTTP_CONTENT    pHttpGetReq     = (PANSC_ACS_INTERN_HTTP_CONTENT)hReqContext;
    ANSC_STATUS                      returnStatus    = ANSC_STATUS_SUCCESS;
    PHTTP_BMO_REQ_OBJECT             pBmoReqObj      = (PHTTP_BMO_REQ_OBJECT)hBmoReq;
    char                             pBuffer[64]     = { 0 };
    ULONG                            i, len          = 0;

    /* add Authorization header - last good one */
    if ( pMyObject->AuthHeaderValue )
    {
        pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "Authorization", pMyObject->AuthHeaderValue);
    }

    /*
     * If there's a cookie returned, add the cookie
     */
    for ( i = 0; i < pMyObject->NumCookies; i ++ )
    {
    	if ( pMyObject->Cookies[i] == NULL )
    		break;

    	len += _ansc_strlen(pMyObject->Cookies[i]);
    }

    if ( pMyObject->NumCookies == 0 )
    {
        CcspTr069PaTraceDebug(("No Cookie will be added.\n"));
    }
    else
    {
    	char *cookies = (char *)CcspTr069PaAllocateMemory(len + pMyObject->NumCookies*2);

    	if (cookies) {
        	AnscZeroMemory(cookies, len + pMyObject->NumCookies*2);

            for ( i = 0; i < pMyObject->NumCookies; i ++ )
            {
            	if ( pMyObject->Cookies[i] == NULL )
            		break;

            	_ansc_strcat(cookies, pMyObject->Cookies[i]);
            	if ( i < pMyObject->NumCookies - 1 )
            		_ansc_strcat(cookies, "; ");
            }

            pBmoReqObj->SetHeaderValueByName
				(
					(ANSC_HANDLE)pBmoReqObj,
					"Cookie",
					cookies
				);

			CcspTr069PaTraceDebug(("Add Cookie into message: %s\n", cookies));
			CcspTr069PaFreeMemory(cookies);
    	}

    }

    /* When there is more than one envelope in a single HTTP Request,
     * when there is a SOAP response in an HTTP Request, or when there is a
     * SOAP Fault response in an HTTP Request, the SOAPAction header in the
     * HTTP Request MUST have no value (with no quotes), indicating that this
     * header provides no information as to the intent of the message."
     */
    if( pHttpGetReq ==NULL || pHttpGetReq->SoapMessage == NULL || AnscSizeOfString(pHttpGetReq->SoapMessage) == 0)
    {
        /*
         * An empty HTTP POST MUST NOT contain a SOAPAction header.
         * An empty HTTP POST MUST NOT contain a Content-Type header.
         */
        pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "Content-Length", "0");
        /* pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "Content-Type", "text/xml;charset=utf-8"); */
    }
    else
    {
        pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "Content-Type", "text/xml;charset=utf-8");

        _ansc_sprintf(pBuffer, "%u", (unsigned int)AnscSizeOfString(pHttpGetReq->SoapMessage));
        pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "Content-Length", pBuffer);

        if( pHttpGetReq->MethodName == NULL || AnscSizeOfString(pHttpGetReq->MethodName) == 0)
        {
            pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "SOAPAction", "");
        }
        else
        {
            _ansc_sprintf(pBuffer, "\"%s\"", pHttpGetReq->MethodName);
            pBmoReqObj->SetHeaderValueByName((ANSC_HANDLE)pBmoReqObj, "SOAPAction", pBuffer);
        }

        returnStatus =
            pBmoReqObj->AppendBody
                (
                    pBmoReqObj,
                    pHttpGetReq->SoapMessage,
                    AnscSizeOfString(pHttpGetReq->SoapMessage)
                );
    }

    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;
}
/**********************************************************************

    prototype:

        ANSC_STATUS
        CcspCwmpAcscoRequestOny
            (
                ANSC_HANDLE                 hThisObject
            );

    description:

        This function is called to send the last empty request to ACS.

    argument:

                ANSC_HANDLE                 hThisObject
                The caller object.

    return:     the status of the operation;

**********************************************************************/
ANSC_STATUS
CcspCwmpAcscoRequestOnly
    (
        ANSC_HANDLE                 hThisObject
    )
{
    PCCSP_CWMP_ACS_CONNECTION_OBJECT pMyObject      = (PCCSP_CWMP_ACS_CONNECTION_OBJECT)hThisObject;

    return  pMyObject->Request((ANSC_HANDLE)pMyObject, NULL, NULL, 0, 0);

#if 0
    PHTTP_SIMPLE_CLIENT_OBJECT      pHttpClient     = (PHTTP_SIMPLE_CLIENT_OBJECT)pMyObject->hHttpSimpleClient;
    PCCSP_CWMP_SESSION_OBJECT       pWmpSession     = (PCCSP_CWMP_SESSION_OBJECT   )pMyObject->hCcspCwmpSession;
    PCCSP_CWMP_MCO_INTERFACE        pCcspCwmpMcoIf  = (PCCSP_CWMP_MCO_INTERFACE    )pWmpSession->hCcspCwmpMcoIf;
    PHTTP_HFP_INTERFACE             pHttpHfpIf      = (PHTTP_HFP_INTERFACE)pHttpClient->GetHfpIf((ANSC_HANDLE)pHttpClient);
    PHTTP_CAS_INTERFACE             pHttpCasIf      = NULL;
    PHTTP_REQUEST_URI               pHttpReqInfo    = NULL;
    ANSC_STATUS                     returnStatus    = ANSC_STATUS_SUCCESS;
    ANSC_ACS_INTERN_HTTP_CONTENT    intHttpContent  = { 0 };
    PANSC_ACS_INTERN_HTTP_CONTENT   pHttpGetReq     = &intHttpContent;
    BOOL                            bApplyTls       = FALSE;
    PCHAR                           pRequestURL     = NULL;
    PCHAR                           pTempString     = NULL;
    PHTTP_AUTH_CLIENT_OBJECT        pAuthClientObj  = NULL;
    char                            pNewUrl[257]    = { 0 };
    ULONG                           uRedirect       = 0;
    ULONG                           uMaxRedirect    = 5;

    if( pMyObject->AcsUrl == NULL || AnscSizeOfString(pMyObject->AcsUrl) <= 10 || pHttpHfpIf == NULL)
    {
        return ANSC_STATUS_NOT_READY;
    }

    CcspTr069PaTraceDebug(("CcspCwmpAcscoRequest -- AcsUrl = '%s'\n", pMyObject->AcsUrl));

    pRequestURL = pMyObject->AcsUrl;

    if ( AnscEqualString2(pRequestURL, "https", 5, FALSE) )
    {
        bApplyTls = TRUE;
    }
    else if ( AnscEqualString2(pRequestURL, "http", 4, FALSE) )
    {
        bApplyTls = FALSE;
    }
    else
    {
        return ANSC_STATUS_NOT_SUPPORTED;
    }

    pHttpCasIf  = (PHTTP_CAS_INTERFACE)pHttpClient->GetCasIf((ANSC_HANDLE)pHttpClient);

    if ( pHttpCasIf != NULL)
    {
        if( pMyObject->Username == NULL || AnscSizeOfString(pMyObject->Username) == 0)
        {
            pHttpCasIf->EnableAuth(pHttpCasIf->hOwnerContext, FALSE);
        }
        else
        {
            pHttpCasIf->EnableAuth(pHttpCasIf->hOwnerContext, TRUE);

            pAuthClientObj  = (PHTTP_AUTH_CLIENT_OBJECT)pHttpClient->GetClientAuthObj((ANSC_HANDLE)pHttpClient);

            if ( pAuthClientObj != NULL)
            {
                pAuthClientObj->SetAcmIf((ANSC_HANDLE)pAuthClientObj, (ANSC_HANDLE)pMyObject->hHttpAcmIf);
            }
            else
            {
                CcspTr069PaTraceError(("Failed to Get HttpAuthClient object.\n"));
            }
        }
    }

    pHttpReqInfo =
        (PHTTP_REQUEST_URI)pHttpHfpIf->ParseHttpUrl
            (
                pHttpHfpIf->hOwnerContext,
                pRequestURL,
                AnscSizeOfString(pRequestURL)
            );

    if ( !pHttpReqInfo )
    {
        return ANSC_STATUS_INTERNAL_ERROR;
    }

    pHttpReqInfo->Type = HTTP_URI_TYPE_ABS_PATH;


    CcspTr069PaTraceInfo(("Send empty request to now at: %u\n", (unsigned int)AnscGetTickInSeconds()));

    returnStatus =
        pHttpClient->Request
            (
                (ANSC_HANDLE)pHttpClient,
                (ULONG      )HTTP_METHOD_CODE_POST,
                (ANSC_HANDLE)pHttpReqInfo,
                (ANSC_HANDLE)NULL,
                bApplyTls
            );

    AnscSleep(500);

    CcspTr069PaFreeMemory(pHttpReqInfo);

    return returnStatus;
#endif
}
ANSC_STATUS
CcspCwmpAcscoRequest
    (
        ANSC_HANDLE                 hThisObject,
        char*                       pSoapMessage,
        char*                       pMethodName,
        ULONG                       ulReqEnvCount,
        ULONG                       ulRepEnvCount
    )
{
    PCCSP_CWMP_ACS_CONNECTION_OBJECT pMyObject      = (PCCSP_CWMP_ACS_CONNECTION_OBJECT)hThisObject;
    PHTTP_SIMPLE_CLIENT_OBJECT      pHttpClient     = (PHTTP_SIMPLE_CLIENT_OBJECT)pMyObject->hHttpSimpleClient;
    PCCSP_CWMP_SESSION_OBJECT       pWmpSession     = (PCCSP_CWMP_SESSION_OBJECT   )pMyObject->hCcspCwmpSession;
    PCCSP_CWMP_CPE_CONTROLLER_OBJECT pCcspCwmpCpeController = (PCCSP_CWMP_CPE_CONTROLLER_OBJECT)pWmpSession->hCcspCwmpCpeController;
    PCCSP_CWMP_STAT_INTERFACE       pCcspCwmpStatIf = (PCCSP_CWMP_STAT_INTERFACE)pCcspCwmpCpeController->hCcspCwmpStaIf;
	PCCSP_CWMP_CFG_INTERFACE		pCcspCwmpCfgIf	= (PCCSP_CWMP_CFG_INTERFACE)pCcspCwmpCpeController->hCcspCwmpCfgIf;
    PCCSP_CWMP_MCO_INTERFACE        pCcspCwmpMcoIf  = (PCCSP_CWMP_MCO_INTERFACE        )pWmpSession->hCcspCwmpMcoIf;
    PHTTP_HFP_INTERFACE             pHttpHfpIf      = (PHTTP_HFP_INTERFACE)pHttpClient->GetHfpIf((ANSC_HANDLE)pHttpClient);
    PHTTP_CAS_INTERFACE             pHttpCasIf      = NULL;
    PHTTP_REQUEST_URI               pHttpReqInfo    = NULL;
    ANSC_STATUS                     returnStatus    = ANSC_STATUS_SUCCESS;
    PANSC_ACS_INTERN_HTTP_CONTENT   pHttpGetReq     = &intHttpContent;
    BOOL                            bApplyTls       = FALSE;
    PCHAR                           pRequestURL     = NULL;
    PCHAR                           pTempString     = NULL;
    PHTTP_AUTH_CLIENT_OBJECT        pAuthClientObj  = NULL;
    char                            pNewUrl[257]    = { 0 };
    ULONG                           uRedirect       = 0;
    ULONG                           uMaxRedirect    = 5;
	ULONG							ulRpcCallTimeout= CCSP_CWMPSO_RPCCALL_TIMEOUT; 

    /* If the response is 401 authentication required, we need to try again */
    int                             nMaxAuthRetries = 2;

    if( pMyObject->AcsUrl == NULL || AnscSizeOfString(pMyObject->AcsUrl) <= 10 || pHttpHfpIf == NULL)
    {
        return ANSC_STATUS_NOT_READY;
    }

    AnscZeroMemory(pHttpGetReq, sizeof(ANSC_ACS_INTERN_HTTP_CONTENT));

    CcspTr069PaTraceDebug(("CcspCwmpAcscoRequest -- AcsUrl = '%s'\n", pMyObject->AcsUrl));

    pHttpCasIf  = (PHTTP_CAS_INTERFACE)pHttpClient->GetCasIf((ANSC_HANDLE)pHttpClient);

    if ( pHttpCasIf != NULL)
    {
        if( pMyObject->Username == NULL || AnscSizeOfString(pMyObject->Username) == 0)
        {
            pHttpCasIf->EnableAuth(pHttpCasIf->hOwnerContext, FALSE);
        }
        else
        {
            pHttpCasIf->EnableAuth(pHttpCasIf->hOwnerContext, TRUE);

            pAuthClientObj  = (PHTTP_AUTH_CLIENT_OBJECT)pHttpClient->GetClientAuthObj((ANSC_HANDLE)pHttpClient);

            if ( pAuthClientObj != NULL)
            {
                pAuthClientObj->SetAcmIf((ANSC_HANDLE)pAuthClientObj, (ANSC_HANDLE)pMyObject->hHttpAcmIf);
            }
            else
            {
                CcspTr069PaTraceError(("Failed to Get HttpAuthClient object.\n"));
            }
        }
    }

#ifdef   _DEBUG
    if ( !pSoapMessage )
    {
        CcspTr069PaTraceDebug(("CPE Request:\n<EMPTY>\n"));
    }
    else if ( AnscSizeOfString(pSoapMessage) <= CCSP_CWMP_TRACE_MAX_SOAP_MSG_LENGTH )
    {
        CcspTr069PaTraceDebug(("CPE Request:\n%s\n", pSoapMessage));
    }
    else
    {
        char                        partSoap[CCSP_CWMP_TRACE_MAX_SOAP_MSG_LENGTH+1+8];

        AnscCopyMemory(partSoap, pSoapMessage, CCSP_CWMP_TRACE_MAX_SOAP_MSG_LENGTH);
        partSoap[CCSP_CWMP_TRACE_MAX_SOAP_MSG_LENGTH] = '\n';
        partSoap[CCSP_CWMP_TRACE_MAX_SOAP_MSG_LENGTH+1] = '.';
        partSoap[CCSP_CWMP_TRACE_MAX_SOAP_MSG_LENGTH+2] = '.';
        partSoap[CCSP_CWMP_TRACE_MAX_SOAP_MSG_LENGTH+3] = '.';
        partSoap[CCSP_CWMP_TRACE_MAX_SOAP_MSG_LENGTH+4] = '\n';
        partSoap[CCSP_CWMP_TRACE_MAX_SOAP_MSG_LENGTH+5] = 0;
        CcspTr069PaTraceDebug(("CPE Request:\n%s\n", partSoap));
    }
#endif
    
START:
    pRequestURL = pMyObject->AcsUrl;

    pHttpReqInfo =
        (PHTTP_REQUEST_URI)pHttpHfpIf->ParseHttpUrl
            (
                pHttpHfpIf->hOwnerContext,
                pRequestURL,
                AnscSizeOfString(pRequestURL)
            );

    if ( !pHttpReqInfo )
    {
        return ANSC_STATUS_INTERNAL_ERROR;
    }

    pHttpReqInfo->Type = HTTP_URI_TYPE_ABS_PATH;

    /* init the request */
    AnscZeroMemory(pHttpGetReq, sizeof(ANSC_ACS_INTERN_HTTP_CONTENT));
    pHttpGetReq->bIsRedirect    = FALSE;
    pHttpGetReq->SoapMessage    = pSoapMessage;

    /* When there is more than one envelope in a single HTTP Request,
     * when there is a SOAP response in an HTTP Request, or when there is a
     * SOAP Fault response in an HTTP Request, the SOAPAction header in the
     * HTTP Request MUST have no value (with no quotes), indicating that this
     * header provides no information as to the intent of the message."
     */
    if( ulReqEnvCount == 1 && ulRepEnvCount == 0)
    {
        pHttpGetReq->MethodName     = pMethodName;
    }

    AnscInitializeEvent(&pHttpGetReq->CompleteEvent);

    while ( nMaxAuthRetries > 0 )
    {
        CcspTr069PaTraceInfo(("ACS Request now at: %u\n", (unsigned int)AnscGetTickInSeconds()));

        if ( AnscEqualString2(pRequestURL, "https", 5, FALSE) )
        {
            bApplyTls = TRUE;
        }
        else if ( AnscEqualString2(pRequestURL, "http", 4, FALSE) )
        {
            if ( bIsComcastImage() ){                
#ifdef _SUPPORT_HTTP
               CcspTr069PaTraceInfo(("HTTP request from ACS is supported\n"));
               bApplyTls = FALSE;
#else
               CcspTr069PaTraceInfo(("TR-069 blocked unsecured traffic from ACS\n"));
               pHttpGetReq->CompleteStatus = ANSC_STATUS_NOT_SUPPORTED;
               pHttpGetReq->bUnauthorized = TRUE;
               pHttpGetReq->bIsRedirect = FALSE;
               break;
#endif
            }
            else {
               bApplyTls = FALSE; 
            }
        }
        else
        {
             pHttpGetReq->CompleteStatus = ANSC_STATUS_NOT_SUPPORTED;
             pHttpGetReq->bUnauthorized = FALSE;
             pHttpGetReq->bIsRedirect = FALSE;
             break;
        }

        if(pHttpGetReq->pContent != NULL)
        {
            CcspTr069PaFreeMemory(pHttpGetReq->pContent);

            pHttpGetReq->pContent = NULL;
        }

        pHttpGetReq->CompleteStatus = ANSC_STATUS_FAILURE;
        pHttpGetReq->bUnauthorized  = FALSE;
        AnscResetEvent     (&pHttpGetReq->CompleteEvent);

        returnStatus =
            pHttpClient->Request
                (
                    (ANSC_HANDLE)pHttpClient,
                    (ULONG      )HTTP_METHOD_CODE_POST,
                    (ANSC_HANDLE)pHttpReqInfo,
                    (ANSC_HANDLE)pHttpGetReq,
                    bApplyTls
                );

        if( returnStatus != ANSC_STATUS_SUCCESS)
        {
            CcspTr069PaTraceError(("ACS Request failed: returnStatus = %.X\n", (unsigned int)returnStatus));
			break;
        }

		if ( pCcspCwmpCfgIf && pCcspCwmpCfgIf->GetCwmpRpcTimeout )
		{
			ulRpcCallTimeout = pCcspCwmpCfgIf->GetCwmpRpcTimeout(pCcspCwmpCfgIf->hOwnerContext);	
			if ( ulRpcCallTimeout < CCSP_CWMPSO_RPCCALL_TIMEOUT )
			{
				ulRpcCallTimeout = CCSP_CWMPSO_RPCCALL_TIMEOUT;
			}
		}

        AnscWaitEvent(&pHttpGetReq->CompleteEvent, ulRpcCallTimeout * 1000);
        if ( pHttpGetReq->CompleteStatus == ANSC_STATUS_SUCCESS && pHttpGetReq->bUnauthorized && nMaxAuthRetries > 0 )
        {
            CcspTr069PaTraceError(("ACS Request is not authenticated, try again.\n"));
            nMaxAuthRetries --;
			
#ifdef _ANSC_USE_OPENSSL_
            if( bApplyTls )
        	{
	        	if ( ANSC_STATUS_SUCCESS == CcspTr069PaSsp_GetTr069CertificateLocationForSyndication( &openssl_client_ca_certificate_files ) )
        		{
					openssl_load_ca_certificates( SSL_CLIENT_CALLS );
        		}
        	}
#endif /* _ANSC_USE_OPENSSL_ */
        }
        else
        {
            CcspTr069PaTraceInfo(("ACS Request has completed with status code %lu, at %lu\n", pHttpGetReq->CompleteStatus, AnscGetTickInSeconds()));

            break;
        }
    }

    /* AnscResetEvent (&pHttpGetReq->CompleteEvent); */
    AnscFreeEvent(&pHttpGetReq->CompleteEvent);

    CcspTr069PaFreeMemory(pHttpReqInfo);

    if ( pHttpGetReq->CompleteStatus != ANSC_STATUS_SUCCESS )
    {
        if ( pHttpGetReq->CompleteStatus == ANSC_STATUS_RESET_SESSION )
        {
            goto  REDIRECTED;
        }
        else
        {
            returnStatus = pHttpGetReq->CompleteStatus;

            goto  EXIT;
        }
    }
    else if( pHttpGetReq->bUnauthorized)
    {
        returnStatus = ANSC_STATUS_FAILURE;

        if( pCcspCwmpStatIf)
        {
            pCcspCwmpStatIf->IncTcpFailure(pCcspCwmpStatIf->hOwnerContext);
        }

        goto EXIT;
    }

REDIRECTED:
    if( pHttpGetReq->bIsRedirect)
    {
        if( _ansc_strstr((PCHAR)pHttpGetReq->pContent, "http") == pHttpGetReq->pContent)
        {
            if ( pMyObject->AcsUrl ) CcspTr069PaFreeMemory(pMyObject->AcsUrl);
            pMyObject->AcsUrl = CcspTr069PaCloneString(pHttpGetReq->pContent);
        }
        else
        {
            /* if it's partial path */
            pTempString = _ansc_strstr(pRequestURL, "//");

            if( pTempString == NULL)
            {
                returnStatus = ANSC_STATUS_FAILURE;

                goto EXIT;
            }

            pTempString += AnscSizeOfString("//");
            pTempString  = _ansc_strstr(pTempString, "/");

            if( pTempString == NULL)
            {
                returnStatus = ANSC_STATUS_FAILURE;

                goto EXIT;
            }

            AnscCopyMemory(pNewUrl, pRequestURL, (ULONG)(pTempString - pRequestURL));
            AnscCatString(pNewUrl, (PCHAR)pHttpGetReq->pContent);

            if ( pMyObject->AcsUrl ) CcspTr069PaFreeMemory(pMyObject->AcsUrl);
            pMyObject->AcsUrl = CcspTr069PaCloneString(pNewUrl);
        }

        uRedirect ++;

        if( uRedirect >= uMaxRedirect)
        {
            CcspTr069PaTraceDebug(("Maximum Redirection reached. Give up!\n"));

            returnStatus = ANSC_STATUS_FAILURE;

            goto EXIT;
        }
        else
        {
            CcspTr069PaTraceDebug(("Acs connection redirection #%u: '%s'\n", (unsigned int)uRedirect, pMyObject->AcsUrl));

            /* in case redirected ACS challenges CPE again */
            nMaxAuthRetries = 2;

            /* tear down current HTTP session before redirecting to new ACS,
             * otherwise, there might be case that ACS sends out redirection
             * response and immediately closes the socket, CWMP may be 
             * confused by closing CWMP session prematurely. 
             */
            pHttpClient->DelAllWcsos((ANSC_HANDLE)pHttpClient);

            goto START;
        }
    }

    if(pWmpSession != NULL)
    {
        if( pHttpGetReq->ulContentSize > 0 && pHttpGetReq->pContent != NULL)
        {
            CcspTr069PaTraceDebug(("Response:\n%s\n", (char*)pHttpGetReq->pContent));

            returnStatus =
                pWmpSession->RecvSoapMessage
                    (
                       pWmpSession,
                       (PCHAR)pHttpGetReq->pContent
                    );
        }
        else
        {
            CcspTr069PaTraceDebug(("Response: <EMPTY>\n"));

            returnStatus =
                pCcspCwmpMcoIf->NotifyAcsStatus
                    (
                        pCcspCwmpMcoIf->hOwnerContext,
                        TRUE,           /* no more requests */
                        FALSE
                    );
        }
    }

EXIT:

    if(pHttpGetReq->pContent != NULL)
    {
        CcspTr069PaFreeMemory(pHttpGetReq->pContent);

        pHttpGetReq->pContent = NULL;
    }

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

    return returnStatus;
}