/********************************************************************** prototype: ANSC_STATUS CcspCwmpSoappoUtilGetParamAttribute ( ANSC_HANDLE hXmlHandle, ANSC_HANDLE hAttrHandle ); description: This function is called to get the parameter attribute from the xml handle. argument: ANSC_HANDLE hXmlHandle, The XML node; ANSC_HANDLE hAttrHandle The parameter attribute handle return: the status of the operation. **********************************************************************/ ANSC_STATUS CcspCwmpSoappoUtilGetParamAttribute ( ANSC_HANDLE hXmlHandle, ANSC_HANDLE hAttrHandle ) { PANSC_XML_DOM_NODE_OBJECT pXmlNode = (PANSC_XML_DOM_NODE_OBJECT)hXmlHandle; PANSC_XML_DOM_NODE_OBJECT pListNode = (PANSC_XML_DOM_NODE_OBJECT)NULL; PANSC_XML_DOM_NODE_OBJECT pChildNode = (PANSC_XML_DOM_NODE_OBJECT)NULL; PCCSP_CWMP_SET_PARAM_ATTRIB pParamAttr = (PCCSP_CWMP_SET_PARAM_ATTRIB)hAttrHandle; ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; CHAR pValue[2048] = { 0 }; PCHAR pBegin = NULL; ULONG length = 2048; ULONG uLeft = 2048; /*************************************************************************** * Argument | Type | Description * *************************************************************************** * Name | string(256) | This is the name of a Parameter. * *-------------------------------------------------------------------------* * Notification | boolean | notification update .* * Change | | . * *-------------------------------------------------------------------------* * Notification | int(0:2) | notification value .* *-------------------------------------------------------------------------* * AccessList | boolean | change accesslist or not .* * Change | | . * *-------------------------------------------------------------------------* * AccesList | string(64)[] | array of access list .* ***************************************************************************/ /* * Get the name first; */ pChildNode = (PANSC_XML_DOM_NODE_OBJECT) AnscXmlDomNodeGetHeadChild(pXmlNode); if( pChildNode == NULL) { CcspTr069PaTraceError(("Invalid arguments for ParameterAttributeStruct.\n")); return ANSC_STATUS_FAILURE; } length = 256; returnStatus = AnscXmlDomNodeGetDataString ( pChildNode, NULL, pValue, &length ); if( returnStatus != ANSC_STATUS_SUCCESS) { CcspTr069PaTraceError(("Failed to get the parameter name.\n")); return returnStatus; } pParamAttr->Name = CcspTr069PaCloneString(pValue); /* * Get the notification change flag */ pChildNode = (PANSC_XML_DOM_NODE_OBJECT) AnscXmlDomNodeGetNextChild(pXmlNode, pChildNode); if( pChildNode == NULL) { CcspTr069PaTraceError(("Invalid arguments for ParameterAttributeStruct.\n")); return ANSC_STATUS_FAILURE; } returnStatus = AnscXmlDomNodeGetDataBoolean ( pChildNode, NULL, &pParamAttr->bNotificationChange ); if( returnStatus != ANSC_STATUS_SUCCESS) { CcspTr069PaTraceError(("Failed to get the notification flag.\n")); return returnStatus; } /* * Get the notificateion value */ pChildNode = (PANSC_XML_DOM_NODE_OBJECT) AnscXmlDomNodeGetNextChild(pXmlNode, pChildNode); if( pChildNode == NULL) { CcspTr069PaTraceError(("Invalid arguments for ParameterAttributeStruct.\n")); return ANSC_STATUS_FAILURE; } returnStatus = AnscXmlDomNodeGetDataUlong ( pChildNode, NULL, &pParamAttr->Notification ); if( returnStatus != ANSC_STATUS_SUCCESS) { CcspTr069PaTraceError(("Failed to get the notification value.\n")); return returnStatus; } /* * Get the accesslist change flag */ pChildNode = (PANSC_XML_DOM_NODE_OBJECT) AnscXmlDomNodeGetNextChild(pXmlNode, pChildNode); if( pChildNode == NULL) { CcspTr069PaTraceError(("Invalid arguments for ParameterAttributeStruct.\n")); return ANSC_STATUS_FAILURE; } returnStatus = AnscXmlDomNodeGetDataBoolean ( pChildNode, NULL, &pParamAttr->bAccessListChange ); if( returnStatus != ANSC_STATUS_SUCCESS) { CcspTr069PaTraceError(("Failed to get the AccessListChange flag.\n")); return returnStatus; } /* * Get the accesslist */ pParamAttr->AccessList = NULL; pListNode = (PANSC_XML_DOM_NODE_OBJECT) AnscXmlDomNodeGetNextChild(pXmlNode, pChildNode); if( pListNode == NULL) { return ANSC_STATUS_SUCCESS; } length = 2048; AnscZeroMemory(pValue, length); pBegin = pValue; pChildNode = (PANSC_XML_DOM_NODE_OBJECT) AnscXmlDomNodeGetHeadChild(pListNode); while( pChildNode != NULL) { if( pBegin != pValue) { AnscCopyMemory(pBegin, CCSP_CWMP_COMMA, AnscSizeOfString(CCSP_CWMP_COMMA)); pBegin += AnscSizeOfString(CCSP_CWMP_COMMA); uLeft -= AnscSizeOfString(CCSP_CWMP_COMMA); length = uLeft; } returnStatus = AnscXmlDomNodeGetDataString ( pChildNode, NULL, pBegin, &length ); if( returnStatus != ANSC_STATUS_SUCCESS) { CcspTr069PaTraceError(("Failed to get the AccessList value.\n")); return returnStatus; } pBegin += length; uLeft -= length; length = uLeft; pChildNode = (PANSC_XML_DOM_NODE_OBJECT) AnscXmlDomNodeGetNextChild(pListNode, pChildNode); } if( pBegin != pValue) { pParamAttr->AccessList = CcspTr069PaCloneString(pValue); } 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; }
/********************************************************************** prototype: ANSC_STATUS CcspCwmpSoappoUtilGetParamValue ( ANSC_HANDLE hXmlHandle, ANSC_HANDLE hParamHandle ); description: This function is called to get the parameter value from the xml handle. argument: ANSC_HANDLE hXmlHandle, The XML node; ANSC_HANDLE hParamHandle The parameter handle return: the status of the operation. **********************************************************************/ ANSC_STATUS CcspCwmpSoappoUtilGetParamValue ( ANSC_HANDLE hCcspCwmpMcoIf, ANSC_HANDLE hXmlHandle, ANSC_HANDLE hParamHandle ) { PCCSP_CWMP_MCO_INTERFACE pCcspCwmpMcoIf = (PCCSP_CWMP_MCO_INTERFACE)hCcspCwmpMcoIf; PANSC_XML_DOM_NODE_OBJECT pXmlNode = (PANSC_XML_DOM_NODE_OBJECT)hXmlHandle; PANSC_XML_DOM_NODE_OBJECT pNameNode = (PANSC_XML_DOM_NODE_OBJECT)NULL; PANSC_XML_DOM_NODE_OBJECT pValueNode = (PANSC_XML_DOM_NODE_OBJECT)NULL; PCCSP_CWMP_PARAM_VALUE pCwmpParam = (PCCSP_CWMP_PARAM_VALUE)hParamHandle; PSLAP_VARIABLE pSlapVariable= (PSLAP_VARIABLE)NULL; ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; CHAR pValue[1024] = { 0 }; ULONG dataType = CCSP_CWMP_TR069_DATA_TYPE_Unspecified; ULONG length = 1024; ULONG uLongValue = 0; LONG longValue = 0; BOOL bBool = FALSE; BOOL bIsInteger = FALSE; PANSC_XML_ATTRIBUTE pAttribute = NULL; char* pDataType = NULL; char pTemp[64] = { 0 }; CHAR pHugeValue[32000] = { 0 }; /* Config file value could be as big as 32K */ pCwmpParam->Value = NULL; /*************************************************************************** * Argument | Type | Description * *************************************************************************** * Name | string(256) | This is the name of a Parameter. * *-------------------------------------------------------------------------* * Value | any | Teh is the value to be set .* ***************************************************************************/ pNameNode = (PANSC_XML_DOM_NODE_OBJECT) AnscXmlDomNodeGetHeadChild(pXmlNode); pValueNode = (PANSC_XML_DOM_NODE_OBJECT) AnscXmlDomNodeGetTailChild(pXmlNode); if( pNameNode == NULL || pValueNode == NULL || pNameNode == pValueNode) { CcspTr069PaTraceError(("Invalid arguments for ParameterValueStruct.\n")); return ANSC_STATUS_FAILURE; } /* * Get the name first; */ length = 256; returnStatus = AnscXmlDomNodeGetDataString ( pNameNode, NULL, pValue, &length ); if( returnStatus != ANSC_STATUS_SUCCESS) { CcspTr069PaTraceError(("Failed to get the parameter name.\n")); return returnStatus; } if( length == 0) { CcspTr069PaTraceError(("Empty parameter name in SetParameterValues.\n")); return ANSC_STATUS_FAILURE; } pCwmpParam->Name = CcspTr069PaCloneString(pValue); length = 1024; AnscZeroMemory(pValue, length); pSlapVariable = (PSLAP_VARIABLE)CcspTr069PaAllocateMemory(sizeof(SLAP_VARIABLE)); if ( !pSlapVariable ) { return ANSC_STATUS_RESOURCES; } SlapInitVariable(pSlapVariable); pCwmpParam->Value = pSlapVariable; pSlapVariable->Name = NULL; pSlapVariable->ContentType = 0; pSlapVariable->UsageType = 0; /* check the value */ length = 32000; returnStatus = AnscXmlDomNodeGetDataString ( pValueNode, NULL, pHugeValue, &length ); if( returnStatus != ANSC_STATUS_SUCCESS) { CcspTr069PaTraceError(("Failed to get the string parameter value.\n")); CcspTr069PaFreeMemory(pSlapVariable); pCwmpParam->Value = NULL; } else { pSlapVariable->ContentType = SLAP_CONTENT_TYPE_UNSPECIFIED; pSlapVariable->UsageType = 0; pSlapVariable->Syntax = SLAP_VAR_SYNTAX_string; pSlapVariable->Variant.varString = CcspTr069PaCloneString(pHugeValue); } pCwmpParam->Tr069DataType = CCSP_CWMP_TR069_DATA_TYPE_Unspecified; /* retrieve data type */ if ( TRUE ) { PANSC_XML_ATTRIBUTE pAttribute; pCwmpParam->Tr069DataType = pCcspCwmpMcoIf->GetParamDataType(pCcspCwmpMcoIf->hOwnerContext, pCwmpParam->Name); pAttribute = (PANSC_XML_ATTRIBUTE)AnscXmlDomNodeGetFirstAttr(pValueNode); if ( pAttribute ) { char* pDataType; AnscCopyMemory(pValue, pAttribute->StringData, pAttribute->DataSize); pDataType = _ansc_strstr(pValue, ":"); if ( !pDataType ) { pDataType = pValue; } else { pDataType ++; } if ( AnscEqualString(pDataType, CCSP_CWMP_DATA_NAME_string, TRUE) ) { pCwmpParam->Tr069DataType = CCSP_CWMP_TR069_DATA_TYPE_String; } else if ( AnscEqualString(pDataType, CCSP_CWMP_DATA_NAME_int, TRUE) ) { pCwmpParam->Tr069DataType = CCSP_CWMP_TR069_DATA_TYPE_Int; } else if ( AnscEqualString(pDataType, CCSP_CWMP_DATA_NAME_unsignedInt, TRUE) ) { pCwmpParam->Tr069DataType = CCSP_CWMP_TR069_DATA_TYPE_UnsignedInt; } else if ( AnscEqualString(pDataType, CCSP_CWMP_DATA_NAME_boolean, TRUE) ) { pCwmpParam->Tr069DataType = CCSP_CWMP_TR069_DATA_TYPE_Boolean; } else if ( AnscEqualString(pDataType, CCSP_CWMP_DATA_NAME_dateTime, TRUE) ) { pCwmpParam->Tr069DataType = CCSP_CWMP_TR069_DATA_TYPE_DateTime; } else if ( AnscEqualString(pDataType, CCSP_CWMP_DATA_NAME_base64, TRUE) ) { pCwmpParam->Tr069DataType = CCSP_CWMP_TR069_DATA_TYPE_Base64; } else { pCwmpParam->Tr069DataType = CCSP_CWMP_TR069_DATA_TYPE_Unspecified; } } } if ( pCwmpParam->Tr069DataType == CCSP_CWMP_TR069_DATA_TYPE_Unspecified ) { return ANSC_STATUS_BAD_PARAMETER; } return ANSC_STATUS_SUCCESS; }
/********************************************************************** prototype: ANSC_STATUS CcspCwmpSoappoUtilGetCwmpMethodName ( ULONG uMethod, BOOL bFromServer PCHAR pOutBuffer ); description: This function is called to find method name based on the value. argument: ULONG uMethod, The method value; BOOL bFromServer It's a server side method or not PCHAR pOutBuffer The output method name. return: the status of the operation. **********************************************************************/ ANSC_STATUS CcspCwmpSoappoUtilGetCwmpMethodName ( ULONG uMethod, BOOL bFromServer, PCHAR pOutBuffer ) { if( uMethod == CCSP_CWMP_METHOD_GetRPCMethods) { AnscCopyString(pOutBuffer,"GetRPCMethods"); return ANSC_STATUS_SUCCESS; } if(!bFromServer) { switch ( uMethod ) { case CCSP_CWMP_METHOD_SetParameterValues: AnscCopyString(pOutBuffer,"SetParameterValues"); break; case CCSP_CWMP_METHOD_GetParameterValues: AnscCopyString(pOutBuffer,"GetParameterValues"); break; case CCSP_CWMP_METHOD_GetParameterNames: AnscCopyString(pOutBuffer,"GetParameterNames"); break; case CCSP_CWMP_METHOD_SetParameterAttributes: AnscCopyString(pOutBuffer,"SetParameterAttributes"); break; case CCSP_CWMP_METHOD_GetParameterAttributes: AnscCopyString(pOutBuffer,"GetParameterAttributes"); break; case CCSP_CWMP_METHOD_AddObject: AnscCopyString(pOutBuffer,"AddObject"); break; case CCSP_CWMP_METHOD_DeleteObject: AnscCopyString(pOutBuffer,"DeleteObject"); break; case CCSP_CWMP_METHOD_Reboot: AnscCopyString(pOutBuffer,"Reboot"); break; case CCSP_CWMP_METHOD_Download: AnscCopyString(pOutBuffer,"Download"); break; case CCSP_CWMP_METHOD_Upload: AnscCopyString(pOutBuffer,"Upload"); break; case CCSP_CWMP_METHOD_FactoryReset: AnscCopyString(pOutBuffer,"FactoryReset"); break; case CCSP_CWMP_METHOD_GetQueuedTransfers: AnscCopyString(pOutBuffer,"GetQueuedTransfers"); break; case CCSP_CWMP_METHOD_ScheduleInform: AnscCopyString(pOutBuffer,"ScheduleInform"); break; case CCSP_CWMP_METHOD_SetVouchers: AnscCopyString(pOutBuffer,"SetVouchers"); break; case CCSP_CWMP_METHOD_GetOptions: AnscCopyString(pOutBuffer,"GetOptions"); break; default: CcspTr069PaTraceError(("Unknown CWMP Client method type: %d\n", uMethod)); return ANSC_STATUS_FAILURE; } } else { switch ( uMethod ) { case CCSP_CWMP_METHOD_Inform: AnscCopyString(pOutBuffer,"Inform"); break; case CCSP_CWMP_METHOD_TransferComplete: AnscCopyString(pOutBuffer,"TransferComplete"); break; case CCSP_CWMP_METHOD_RequestDownload: AnscCopyString(pOutBuffer,"RequestDownload"); break; case CCSP_CWMP_METHOD_Kicked: AnscCopyString(pOutBuffer,"Kicked"); break; default: CcspTr069PaTraceError(("Unknown CWMP Server method type: %d\n", uMethod)); return ANSC_STATUS_FAILURE; } } 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; }