ANSC_STATUS AnscLpccoTcpBwoRemove ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSocket ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_LPCCO_TCP_OBJECT pMyObject = (PANSC_LPCCO_TCP_OBJECT )hThisObject; PANSC_DAEMON_SERVER_TCP_OBJECT pDaemonServer = (PANSC_DAEMON_SERVER_TCP_OBJECT)pMyObject->hDaemonServer; PANSC_BROKER_SERVER_TCP_OBJECT pBrokerServer = (PANSC_BROKER_SERVER_TCP_OBJECT)pMyObject->hBrokerServer; PANSC_TIMER_DESCRIPTOR_OBJECT pConnTimerObj = (PANSC_TIMER_DESCRIPTOR_OBJECT )pMyObject->hConnTimerObj; PANSC_BROKER_SOCKET_TCP_OBJECT pBrokerSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)hSocket; PANSC_BUFFER_DESCRIPTOR pBufferDesp = (PANSC_BUFFER_DESCRIPTOR )pBrokerSocket->GetBufferContext((ANSC_HANDLE)pBrokerSocket); PANSC_LPC_PARTY_ADDR pPartyAddr = (PANSC_LPC_PARTY_ADDR )pBrokerSocket->GetClientContext((ANSC_HANDLE)pBrokerSocket); pBrokerSocket->SetClientContext((ANSC_HANDLE)pBrokerSocket, (ANSC_HANDLE)NULL ); pBrokerSocket->SetBufferContext((ANSC_HANDLE)pBrokerSocket, NULL, 0, (ANSC_HANDLE)NULL); if ( pBufferDesp ) { AnscFreeBdo((ANSC_HANDLE)pBufferDesp); } if ( pPartyAddr ) { pPartyAddr->Timestamp = AnscGetTickInSeconds(); pPartyAddr->PartyState &= ~ANSC_LPC_PARTY_STATE_connectedOut; pPartyAddr->PartySocket = (ANSC_HANDLE)NULL; /* * We shouldn't return until the reference count of 'pPartyAddr' reaches zero. Because if * we do, the socket may be deleted while there's still active task is trying to send * message to this party. For example: if LPC manager is issuing a LOCO call to all LPC * parties while one party is trying disconnect, a race condition is formed. */ while ( pPartyAddr->ActiveCalls > 0 ) { AnscSleep(20); } if ( !(pPartyAddr->PartyState & ANSC_LPC_PARTY_STATE_connectedIn ) && !(pPartyAddr->PartyState & ANSC_LPC_PARTY_STATE_connectedOut) ) { if ( pMyObject->bActive ) { pConnTimerObj->Stop ((ANSC_HANDLE)pConnTimerObj); pConnTimerObj->SetInterval((ANSC_HANDLE)pConnTimerObj, ANSC_LPCCO_DEF_CONN_TIMEOUT); pConnTimerObj->Start ((ANSC_HANDLE)pConnTimerObj); } } } return ANSC_STATUS_SUCCESS; }
BOOL Process_IsUpdated ( ANSC_HANDLE hInsContext ) { if (!last_tick) { last_tick = AnscGetTickInSeconds(); return TRUE; } if (last_tick >= TIME_NO_NEGATIVE(AnscGetTickInSeconds() - REFRESH_INTERVAL)) { return FALSE; } else { last_tick = AnscGetTickInSeconds(); return TRUE; } }
/********************************************************************** caller: owner of this object prototype: ULONG Host_Synchronize ( ANSC_HANDLE hInsContext ); description: This function is called to synchronize the table. argument: ANSC_HANDLE hInsContext, The instance handle; return: The status of the operation. **********************************************************************/ ULONG Host_Synchronize ( ANSC_HANDLE hInsContext ) { ULONG count,i; CosaDmlHostsGetHosts(NULL,&count); HostsUpdateTime = AnscGetTickInSeconds(); return 0; }
ANSC_STATUS TlsSeoInitialize ( ANSC_HANDLE hThisObject ) { PTLS_SESSION_ENTRY_OBJECT pMyObject = (PTLS_SESSION_ENTRY_OBJECT)hThisObject; PTLS_SESSION_STATE pSessionState = (PTLS_SESSION_STATE )&pMyObject->SessionState; /* * Until you have to simulate C++ object-oriented progtlsming style with standard C, you don't * appreciate all the nice little things come with C++ language and all the dirty works that * have been done by the C++ compilers. Member initialization is one of these things. While in * C++ you don't have to initialize all the member fields inherited from the base class since * the compiler will do it for you, such is not the case with C. */ AnscCoInitialize((ANSC_HANDLE)pMyObject); /* * Although we have initialized some of the member fields in the "create" member function, we * repeat the work here for completeness. While this simulation approach is pretty stupid from * a C++/Java progtlsmer perspective, it's the best we can get for universal embedded network * progtlsming. Before we develop our own operating system (don't expect that to happen any * time soon), this is the way things gonna be. */ pMyObject->Oid = TLS_SESSION_ENTRY_OID; pMyObject->Create = TlsSeoCreate; pMyObject->Remove = TlsSeoRemove; pMyObject->EnrollObjects = TlsSeoEnrollObjects; pMyObject->Initialize = TlsSeoInitialize; pMyObject->Timestamp = AnscGetTickInSeconds(); pMyObject->GetSessionState = TlsSeoGetSessionState; pMyObject->SetSessionState = TlsSeoSetSessionState; pMyObject->Reset = TlsSeoReset; pMyObject->Match1 = TlsSeoMatch1; pMyObject->Match2 = TlsSeoMatch2; /* * We shall initialize the object properties to the default values, which may be changed later * via the exposed member functions. If any of the future extensions needs to change the object * property, the following code also needs to be changed. */ TlsInitSessionState(pSessionState); return ANSC_STATUS_SUCCESS; }
/********************************************************************** caller: owner of this object prototype: BOOL Host_IsUpdated ( ANSC_HANDLE hInsContext ); description: This function is checking whether the table is updated or not. argument: ANSC_HANDLE hInsContext, The instance handle; return: TRUE or FALSE. **********************************************************************/ BOOL Host_IsUpdated ( ANSC_HANDLE hInsContext ) { if ( HostsUpdateTime == 0 ) { HostsUpdateTime = AnscGetTickInSeconds(); return TRUE; } if ( HostsUpdateTime >= TIME_NO_NEGATIVE(AnscGetTickInSeconds() - COSA_DML_USERS_USER_ACCESS_INTERVAL ) ) { return FALSE; } else { HostsUpdateTime = AnscGetTickInSeconds(); return TRUE; } }
BOOL Eventlog_IsUpdated ( ANSC_HANDLE hInsContext ) { if ( !eventlog_last_tick ) { eventlog_last_tick = AnscGetTickInSeconds(); return TRUE; } if ( eventlog_last_tick >= TIME_NO_NEGATIVE(AnscGetTickInSeconds() - REFRESH_INTERVAL) ) { return FALSE; } else { eventlog_last_tick = AnscGetTickInSeconds(); return TRUE; } }
ANSC_HANDLE BwrmPmoGetPage ( ANSC_HANDLE hThisObject, char* root_path, char* file_path ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PBWRM_PAGE_MANAGER_OBJECT pMyObject = (PBWRM_PAGE_MANAGER_OBJECT )hThisObject; PBWRM_PAGE_MANAGER_PROPERTY pProperty = (PBWRM_PAGE_MANAGER_PROPERTY )&pMyObject->Property; PANSC_TIMER_DESCRIPTOR_OBJECT pCacheTimerObject = (PANSC_TIMER_DESCRIPTOR_OBJECT)pMyObject->hCacheTimerObject; PBWRM_COOKED_PAGE_OBJECT pCookedPage = (PBWRM_COOKED_PAGE_OBJECT )NULL; PSINGLE_LINK_ENTRY pSLinkEntry = (PSINGLE_LINK_ENTRY )NULL; ULONG ulHashIndex = (ULONG )AnscHashString(file_path, AnscSizeOfString(file_path), BWRM_PMO_CPO_TABLE_SIZE); ULONG ulCurTime = AnscGetTickInSeconds(); pMyObject->Timestamp = ulCurTime; AnscAcquireLock(&pMyObject->CpoTableLock); pSLinkEntry = AnscSListGetFirstEntry(&pMyObject->CpoTable[ulHashIndex]); while ( pSLinkEntry ) { pCookedPage = ACCESS_BWRM_COOKED_PAGE_OBJECT(pSLinkEntry); pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry); if ( pCookedPage->MatchPath ( (ANSC_HANDLE)pCookedPage, root_path, file_path ) ) { pCookedPage->SetTimestamp((ANSC_HANDLE)pCookedPage, ulCurTime); pCookedPage->IncRefCount ((ANSC_HANDLE)pCookedPage); AnscReleaseLock(&pMyObject->CpoTableLock); return (ANSC_HANDLE)pCookedPage; } } AnscReleaseLock(&pMyObject->CpoTableLock); return (ANSC_HANDLE)NULL; }
ANSC_STATUS PsmSysroSysRamNotify ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSysRepFolder, ULONG ulEvent ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PPSM_SYS_REGISTRY_OBJECT pMyObject = (PPSM_SYS_REGISTRY_OBJECT )hThisObject; PPSM_SYS_REGISTRY_PROPERTY pProperty = (PPSM_SYS_REGISTRY_PROPERTY )&pMyObject->Property; PPSM_FILE_LOADER_OBJECT pPsmFileLoader = (PPSM_FILE_LOADER_OBJECT )pMyObject->hPsmFileLoader; PANSC_TIMER_DESCRIPTOR_OBJECT pRegTimerObj = (PANSC_TIMER_DESCRIPTOR_OBJECT)pMyObject->hRegTimerObj; //CcspTraceInfo(("\n##PsmSysroSysRamNotify() begins##\n")); if ( pMyObject->bNoSave || pMyObject->bSaveInProgress ) { return ANSC_STATUS_SUCCESS; } switch ( ulEvent ) { case SYS_RAM_EVENT_folderAdded : case SYS_RAM_EVENT_folderUpdated : case SYS_RAM_EVENT_folderDeleted : case SYS_RAM_EVENT_folderCleared : case SYS_RAM_EVENT_recordAdded : case SYS_RAM_EVENT_recordUpdated : case SYS_RAM_EVENT_recordDeleted : /* pRegTimerObj->Stop ((ANSC_HANDLE)pRegTimerObj); pRegTimerObj->Start((ANSC_HANDLE)pRegTimerObj); */ pMyObject->LastRegWriteAt = AnscGetTickInSeconds(); pMyObject->bNeedFlush = TRUE; break; default : break; } //CcspTraceInfo(("\n##PsmSysroSysRamNotify() ends##\n")); return returnStatus; }
BOOL SlapEcoGetPendingCallInfo ( ANSC_HANDLE hThisObject, char** call_name, ULONG* call_timestamp, /* in number of seconds after system is up */ ULONG* call_age /* in number of seconds */ ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PSLAP_ENV_CONTROLLER_OBJECT pMyObject = (PSLAP_ENV_CONTROLLER_OBJECT)hThisObject; *call_name = AnscCloneString(pMyObject->PendingCallName); *call_timestamp = pMyObject->PendingCallTimestamp; *call_age = AnscGetTickInSeconds() - pMyObject->PendingCallTimestamp; return pMyObject->bCallPending; }
ANSC_STATUS BwrmPmoCacheTimerInvoke ( ANSC_HANDLE hThisObject ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PBWRM_PAGE_MANAGER_OBJECT pMyObject = (PBWRM_PAGE_MANAGER_OBJECT )hThisObject; PBWRM_PAGE_MANAGER_PROPERTY pProperty = (PBWRM_PAGE_MANAGER_PROPERTY )&pMyObject->Property; PANSC_TIMER_DESCRIPTOR_OBJECT pCacheTimerObject = (PANSC_TIMER_DESCRIPTOR_OBJECT)pMyObject->hCacheTimerObject; ULONG ulCurTime = AnscGetTickInSeconds(); if ( (ulCurTime - pMyObject->Timestamp) > pProperty->CacheTimeout ) { pMyObject->DelAllPages((ANSC_HANDLE)pMyObject); } return ANSC_STATUS_SUCCESS; }
ANSC_STATUS TlsSmoAddSession ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSession ) { PTLS_SESSION_MANAGER_OBJECT pMyObject = (PTLS_SESSION_MANAGER_OBJECT )hThisObject; PTLS_SESSION_ENTRY_OBJECT pSessionEntry = (PTLS_SESSION_ENTRY_OBJECT )hSession; ULONG ulHashIndex = AnscHashUlong(pSessionEntry->SessionState.PeerID, TLS_SMO_SEO_TABLE_SIZE); pSessionEntry->Timestamp = AnscGetTickInSeconds(); AnscAcquireLock (&pMyObject->SeoTableLock); AnscQueuePushEntry(&pMyObject->SeoTable[ulHashIndex], &pSessionEntry->Linkage); AnscReleaseLock (&pMyObject->SeoTableLock); return ANSC_STATUS_SUCCESS; }
ANSC_STATUS AnscSstoStsAdjustClock1 ( ANSC_HANDLE hThisObject, ULONG ulSeconds, int iTimeOffset ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_SIMPLE_SYS_TIME_OBJECT pMyObject = (PANSC_SIMPLE_SYS_TIME_OBJECT)hThisObject; pMyObject->AcquireAccess(hThisObject); pMyObject->LastTick = AnscGetTickInSeconds(); pMyObject->LastSecond = ulSeconds; pMyObject->iTimeOffset = iTimeOffset; pMyObject->ReleaseAccess(hThisObject); return returnStatus; }
ANSC_STATUS AnscSstoStsSysTickToCalendar ( ANSC_HANDLE hThisObject, ULONG ulTicks, ANSC_HANDLE hCalendar ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_SIMPLE_SYS_TIME_OBJECT pMyObject = (PANSC_SIMPLE_SYS_TIME_OBJECT)hThisObject; ULONG ulCurTick = (ULONG )AnscGetTickInSeconds(); ULONG ulCurSecs = (ULONG )pMyObject->GetCurrSecond((ANSC_HANDLE)pMyObject); int iTbpSecs = (int )0; iTbpSecs = (int)ulCurSecs - ((int)ulCurTick - (int)ulTicks); iTbpSecs += pMyObject->iTimeOffset; return pMyObject->SecondToCalendar ( (ANSC_HANDLE)pMyObject, (ULONG )iTbpSecs, hCalendar ); }
ANSC_STATUS AnscDeuoClean ( ANSC_HANDLE hThisObject ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_DAEMON_ENGINE_UDP_OBJECT pMyObject = (PANSC_DAEMON_ENGINE_UDP_OBJECT)hThisObject; PANSC_DAEMON_SERVER_UDP_OBJECT pServer = (PANSC_DAEMON_SERVER_UDP_OBJECT)pMyObject->hDaemonServer; PANSC_DSUO_WORKER_OBJECT pWorker = (PANSC_DSUO_WORKER_OBJECT )pServer->hWorker; PANSC_DAEMON_SOCKET_UDP_OBJECT pSocket = NULL; PSINGLE_LINK_ENTRY pSLinkEntry = NULL; ULONG ulHashIndex = 0; BOOL bSocketFound = FALSE; ULONG ulCurTime = AnscGetTickInSeconds(); if ( !pMyObject->bStarted ) { return ANSC_STATUS_SUCCESS; } else if ( pMyObject->ControlFlags & ANSC_DEUO_FLAG_NO_TIMEOUT ) { return ANSC_STATUS_SUCCESS; } ulHashIndex = 0; bSocketFound = FALSE; while ( ulHashIndex < ANSC_DEUO_SOCKET_TABLE_SIZE ) { AnscAcquireLock(&pMyObject->SocketTableLock); bSocketFound = FALSE; pSLinkEntry = AnscSListGetFirstEntry(&pMyObject->SocketTable[ulHashIndex]); while ( pSLinkEntry ) { pSocket = ACCESS_ANSC_DAEMON_SOCKET_UDP_OBJECT(pSLinkEntry); pSLinkEntry = AnscSListGetNextEntry(pSLinkEntry); if ( ((ulCurTime - pSocket->LastRecvAt) >= pMyObject->SocketTimeOut) && ((ulCurTime - pSocket->LastSendAt) >= pMyObject->SocketTimeOut) ) { bSocketFound = TRUE; break; } } AnscReleaseLock(&pMyObject->SocketTableLock); if ( bSocketFound ) { returnStatus = pWorker->Notify ( pWorker->hWorkerContext, (ANSC_HANDLE)pSocket, ANSC_DSUOWO_EVENT_TIME_OUT, (ANSC_HANDLE)NULL ); returnStatus = pMyObject->DelSocket ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pSocket ); } else { ulHashIndex++; } } return ANSC_STATUS_SUCCESS; }
ANSC_STATUS AnscBetoSendTask ( ANSC_HANDLE hThisObject ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_BROKER_ENGINE_TCP_OBJECT pMyObject = (PANSC_BROKER_ENGINE_TCP_OBJECT)hThisObject; ansc_fd_set* pSendSet1 = (ansc_fd_set* )pMyObject->SendSocketSet; xskt_fd_set* pSendSet2 = (xskt_fd_set* )pMyObject->SendSocketSet; PANSC_BROKER_SERVER_TCP_OBJECT pServer = (PANSC_BROKER_SERVER_TCP_OBJECT)pMyObject->hBrokerServer; PANSC_BSTO_WORKER_OBJECT pWorker = (PANSC_BSTO_WORKER_OBJECT )pServer->hWorker; PANSC_BETO_PACKET_OBJECT pPacket = NULL; PANSC_BROKER_SOCKET_TCP_OBJECT pSocket = NULL; PSINGLE_LINK_ENTRY pSLinkEntry = NULL; BOOL bSendable = FALSE; int s_result = 0; int s_error = 0; AnscTrace("AnscBetoSendTask is activated ...!\n"); /* * As a scalable server implemention, we shall accept as many incoming client connections as * possible and can only be limited by the system resources. Once the listening socket becomes * readable, which means an incoming connection attempt has arrived. We create a new socket * object and associate it with the client. This is a repeated process until the socket owner * closes the socket. */ while ( pMyObject->bStarted ) { AnscAcquireLock(&pMyObject->PacketQueueLock); pSLinkEntry = AnscQueuePopEntry(&pMyObject->PacketQueue); AnscReleaseLock(&pMyObject->PacketQueueLock); if ( !pSLinkEntry ) { continue; } else { pPacket = ACCESS_ANSC_BETO_PACKET_OBJECT(pSLinkEntry); pSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)pPacket->hSocket; } #if !defined(_ANSC_KERNEL) || !defined(_ANSC_LINUX) AnscAcquireLock(&pMyObject->SendSocketSetLock); bSendable = (pServer->Mode & ANSC_BSTO_MODE_XSOCKET)? XSKT_SOCKET_FD_ISSET(pSocket->Socket, pSendSet2) : ANSC_SOCKET_FD_ISSET(pSocket->Socket, pSendSet1); AnscReleaseLock(&pMyObject->SendSocketSetLock); if ( !bSendable ) { returnStatus = pWorker->SendComplete ( pWorker->hWorkerContext, (ANSC_HANDLE)pSocket, pPacket->hWorkerReserved, ANSC_STATUS_FAILURE ); AnscFreeMemory(pPacket); continue; } #endif if ( pServer->Mode & ANSC_BSTO_MODE_XSOCKET ) { s_result = _xskt_send(((XSKT_SOCKET)pSocket->Socket), pPacket->PacketBuffer, (int)pPacket->PacketSize, 0); } else { s_result = _ansc_send(pSocket->Socket, pPacket->PacketBuffer, (int)pPacket->PacketSize, 0); } if ( ((s_result == XSKT_SOCKET_ERROR) && (pServer->Mode & ANSC_BSTO_MODE_XSOCKET)) || ((s_result == ANSC_SOCKET_ERROR) && !(pServer->Mode & ANSC_BSTO_MODE_XSOCKET)) ) { s_error = (pServer->Mode & ANSC_BSTO_MODE_XSOCKET)? _xskt_get_last_error() : _ansc_get_last_error(); returnStatus = pWorker->SendComplete ( pWorker->hWorkerContext, (ANSC_HANDLE)pSocket, pPacket->hWorkerReserved, ANSC_STATUS_FAILURE ); if ( pServer->Mode & ANSC_BSTO_MODE_AUTO_CLOSE ) { pMyObject->DelSocket((ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pSocket); } } else { returnStatus = pWorker->SendComplete ( pWorker->hWorkerContext, (ANSC_HANDLE)pSocket, pPacket->hWorkerReserved, ANSC_STATUS_SUCCESS ); pSocket->SendBytesCount += pPacket->PacketSize; pSocket->LastSendAt = AnscGetTickInSeconds(); } } AnscSetEvent(&pMyObject->SendEvent); return ANSC_STATUS_SUCCESS; }
ANSC_HANDLE Bmc2ReqcoPecGetCookedPage ( ANSC_HANDLE hThisObject, char* page_path ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PBMC2_REQ_CONTROLLER_OBJECT pMyObject = (PBMC2_REQ_CONTROLLER_OBJECT)hThisObject; PBMC2_ENV_CONTROLLER_OBJECT pBmc2EnvController = (PBMC2_ENV_CONTROLLER_OBJECT)pMyObject->hBmc2EnvController; PBMC2_COM_DOMAIN_OBJECT pBmc2ComDomain = (PBMC2_COM_DOMAIN_OBJECT )pMyObject->hBmc2ComDomain; PBMC2_COM_TERMINAL_OBJECT pBmc2ComTerminal = (PBMC2_COM_TERMINAL_OBJECT )pBmc2ComDomain->hBmc2ComTerminal; PBMC2_COM_EXECUTOR_OBJECT pBmc2ComExecutor = (PBMC2_COM_EXECUTOR_OBJECT )pBmc2EnvController->hBmc2ComExecutor; PBWRM_ENV_CONTROLLER_OBJECT pBwrmEnvController = (PBWRM_ENV_CONTROLLER_OBJECT)pBmc2EnvController->hBwrmEnvController; PBWRM_RAM_INTERFACE pBwrmRamIf = (PBWRM_RAM_INTERFACE )pBwrmEnvController->GetBwrmRamIf((ANSC_HANDLE)pBwrmEnvController); char* pRootPath = (char* )pBmc2EnvController->Property.RootPath; PBWRM_COOKED_PAGE_OBJECT pBwrmCookedPage = (PBWRM_COOKED_PAGE_OBJECT )NULL; void* pPageBuffer = (void* )NULL; ULONG ulPageSize = (ULONG )0; /* * The script parsing can take fairly long time, which mandates some sort of page caching * mechanism to be used. The BWRM (BroadWay Web Resource Manager) module is responsible for * file-based page access and page caching. We first try to retrieve the requested page from * the in-memory cache, and only load the page from the underlying storage system if the * requested page is not in the cache. */ returnStatus = pBwrmRamIf->GetCookedPage ( pBwrmRamIf->hOwnerContext, pRootPath, page_path, &pBwrmCookedPage ); if ( returnStatus != ANSC_STATUS_SUCCESS ) { returnStatus = pBwrmRamIf->GetRawPage ( pBwrmRamIf->hOwnerContext, pRootPath, page_path, &pPageBuffer, &ulPageSize ); if ( returnStatus != ANSC_STATUS_SUCCESS ) { return (ANSC_HANDLE)NULL; } else { pBwrmCookedPage = (PBWRM_COOKED_PAGE_OBJECT)pBmc2ComExecutor->PreparePage ( (ANSC_HANDLE)pBmc2ComExecutor, page_path, pPageBuffer, ulPageSize ); } if ( !pBwrmCookedPage ) { AnscFreeMemory(pPageBuffer); return (ANSC_HANDLE)NULL; } else if ( pBmc2EnvController->Property.bCacheScpPages || pBwrmRamIf->IsPageCacheForced(pBwrmRamIf->hOwnerContext, page_path) ) { returnStatus = pBwrmRamIf->AddCookedPage ( pBwrmRamIf->hOwnerContext, pRootPath, page_path, (ANSC_HANDLE)pBwrmCookedPage ); } else { pBwrmCookedPage->SetRootPath ((ANSC_HANDLE)pBwrmCookedPage, pRootPath ); pBwrmCookedPage->SetPagePath ((ANSC_HANDLE)pBwrmCookedPage, page_path ); pBwrmCookedPage->SetTimestamp((ANSC_HANDLE)pBwrmCookedPage, AnscGetTickInSeconds()); } } return (ANSC_HANDLE)pBwrmCookedPage; }
ANSC_STATUS SlapEcoUoaInvokeObject ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSlapObject, char* method_name, SLAP_PARAMETER_LIST* params_in, SLAP_PARAMETER_LIST** params_out, SLAP_VARIABLE** return_var ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PSLAP_ENV_CONTROLLER_OBJECT pMyObject = (PSLAP_ENV_CONTROLLER_OBJECT)hThisObject; PSLAP_OBJ_MAPPER_OBJECT pSlapObjMapper = (PSLAP_OBJ_MAPPER_OBJECT )pMyObject->hSlapObjMapper; PSLAP_OBJ_CONTAINER_OBJECT pSlapObjContainer = (PSLAP_OBJ_CONTAINER_OBJECT )NULL; PSLAP_OBJ_ENTITY_OBJECT pSlapObjEntity = (PSLAP_OBJ_ENTITY_OBJECT )NULL; PSLAP_OBJ_RECORD_OBJECT pSlapObjRecord = (PSLAP_OBJ_RECORD_OBJECT )hSlapObject; PSLAP_SRV_COMPONENT_OBJECT pSlapSrvComponent = (PSLAP_SRV_COMPONENT_OBJECT )pSlapObjRecord->hSlapSrvComponent; ULONG ulObjType = (ULONG )0; pMyObject->bCallPending = TRUE; pMyObject->PendingCallTimestamp = AnscGetTickInSeconds(); AnscZeroMemory(pMyObject->PendingCallName, 256); AnscCopyString(pMyObject->PendingCallName, method_name); /* * There're certain object methods should not be simply relayed to the target logic object. For * example, the external modules may try to invoke method "Remove" to delete the target object. * Handling of such methods should be taken care by UOA interface. */ if ( AnscEqualString(method_name, "Remove", FALSE) && (params_in != NULL ) && (params_in->ParamCount == 0 ) ) { returnStatus = pMyObject->UoaDeleteObject ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pSlapObjRecord ); pMyObject->bCallPending = FALSE; return returnStatus; } if ( !pSlapSrvComponent ) { pMyObject->bCallPending = FALSE; return ANSC_STATUS_UNAPPLICABLE; } else { ulObjType = pSlapSrvComponent->ObjType; if ( ulObjType & SLAP_OBJ_TYPE_serializedCalls ) { pSlapObjRecord->AcqAccess((ANSC_HANDLE)pSlapObjRecord); } returnStatus = pSlapSrvComponent->InvokeDispatch ( (ANSC_HANDLE)pSlapSrvComponent, method_name, params_in, params_out, return_var ); if ( ulObjType & SLAP_OBJ_TYPE_serializedCalls ) { pSlapObjRecord->RelAccess((ANSC_HANDLE)pSlapObjRecord); } } pMyObject->bCallPending = FALSE; return returnStatus; }
ANSC_STATUS AnscBetoRecvTask ( ANSC_HANDLE hThisObject ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_BROKER_ENGINE_TCP_OBJECT pMyObject = (PANSC_BROKER_ENGINE_TCP_OBJECT)hThisObject; PANSC_BROKER_SERVER_TCP_OBJECT pServer = (PANSC_BROKER_SERVER_TCP_OBJECT)pMyObject->hBrokerServer; ansc_fd_set* pRecvSet1 = (ansc_fd_set* )pMyObject->RecvSocketSet; xskt_fd_set* pRecvSet2 = (xskt_fd_set* )pMyObject->RecvSocketSet; PANSC_BROKER_SOCKET_TCP_OBJECT pSocket = NULL; ULONG ulLastCleanAt = AnscGetTickInSeconds(); ANSC_SOCKET s_socket = ANSC_SOCKET_INVALID_SOCKET; int s_result = 0; int s_result_excp = 0; int s_error = 0; int i = 0; uni_fd_set read_fd_set; /*uni_fd_set excp_fd_set;*/ uni_timeval timeval; AnscTrace("AnscBetoRecvTask is activated ...!\n"); /* * As a scalable server implemention, we shall accept as many incoming client connections as * possible and can only be limited by the system resources. Once the listening socket becomes * readable, which means an incoming connection attempt has arrived. We create a new socket * object and associate it with the client. This is a repeated process until the socket owner * closes the socket. */ while ( pMyObject->bStarted ) { ANSC_COMMIT_TASK(); /* * To avoid letting the old half-dead sockets hogging up the system resource, we need to * periodically invoke the cleaning routine. The default interval is 10 seconds, and the * idle timeout value is 90 seconds. */ if ( pMyObject->bCleaningDemanded || (AnscGetTickInSeconds() - ulLastCleanAt) >= ANSC_BETO_CLEAN_TASK_INTERVAL ) { pMyObject->Clean((ANSC_HANDLE)pMyObject); ulLastCleanAt = AnscGetTickInSeconds(); pMyObject->bCleaningDemanded = FALSE; } /* * The _ansc_select() function returns the total number of socket handles that are ready * and contained in the fd_set structures, zero if the time limit expired, or SOCKET_ERROR * if an error occurred. Upon return, the structures are updated to reflect the subset of * these sockets that meet the specified condition. */ if ( pServer->Mode & ANSC_BSTO_MODE_XSOCKET ) { /* * no need to use lock for read_fd_set here, dirty read does not matter. */ read_fd_set.xset = *pRecvSet2; if( XSKT_SOCKET_FD_ISNUL(&read_fd_set.xset) ) { if ( pServer->Mode & ANSC_BSTO_MODE_EVENT_SYNC ) { AnscWaitEvent (&pMyObject->NewSocketEvent, ANSC_BETO_WAIT_EVENT_INTERVAL); AnscResetEvent(&pMyObject->NewSocketEvent); } else { AnscSleep(ANSC_BETO_TASK_BREAK_INTERVAL); } continue; } timeval.xtv.tv_sec = (ANSC_BETO_POLL_INTERVAL_MS / 1000); /* number of seconds */ timeval.xtv.tv_usec = (ANSC_BETO_POLL_INTERVAL_MS % 1000) * 1000; /* number of microseconds */ s_result = _xskt_select(XSKT_SOCKET_FD_SETSIZE, &read_fd_set.xset, NULL, NULL, &timeval.xtv); if ( s_result == 0 ) { continue; } if ( s_result == XSKT_SOCKET_ERROR ) { s_error = _xskt_get_last_error(); pMyObject->Reset((ANSC_HANDLE)pMyObject); continue; } } else { /* * no need to use lock for read_fd_set here, dirty read does not matter. */ read_fd_set.aset = *pRecvSet1; if( ANSC_SOCKET_FD_ISNUL(&read_fd_set.aset) ) { if ( pServer->Mode & ANSC_BSTO_MODE_EVENT_SYNC ) { AnscWaitEvent (&pMyObject->NewSocketEvent, ANSC_BETO_WAIT_EVENT_INTERVAL); AnscResetEvent(&pMyObject->NewSocketEvent); } else { AnscSleep(ANSC_BETO_TASK_BREAK_INTERVAL); } continue; } timeval.atv.tv_sec = (ANSC_BETO_POLL_INTERVAL_MS / 1000); /* number of seconds */ timeval.atv.tv_usec = (ANSC_BETO_POLL_INTERVAL_MS % 1000) * 1000; /* number of microseconds */ s_result = _ansc_select(ANSC_SOCKET_FD_SETSIZE, &read_fd_set.aset, NULL, NULL, &timeval.atv); if ( s_result == 0 ) { continue; } if ( s_result == ANSC_SOCKET_ERROR ) { s_error = _ansc_get_last_error(); pMyObject->Reset((ANSC_HANDLE)pMyObject); continue; } } /* * If there're multiple sockets are receiving data, we loop through the returned fd_set * structure and process them one-by-one. However, we have a slight problem: the resulted * fd_set consists of only the native socket handles, not the associated Socket Objects. * We have to first retrieve the peer's IP address from the socket, and use it to find * the associated socket object. */ for ( i = 0; i < s_result; i++ ) { if ( !pMyObject->bStarted ) { break; } if ( pServer->Mode & ANSC_BSTO_MODE_XSOCKET ) { XSKT_SOCKET_FD_GET(&read_fd_set.xset, s_socket, (ULONG)i); if( s_socket == XSKT_SOCKET_INVALID_SOCKET ) { break; } if( ! XSKT_SOCKET_FD_ISSET(s_socket, pRecvSet2) ) { AnscTraceError(("AnscBetoRecvTask: XSKT_SOCKET_FD_ISSET returned FALSE.\n")); continue; } } else { ANSC_SOCKET_FD_GET(&read_fd_set.aset, s_socket, (ULONG)i); if( s_socket == ANSC_SOCKET_INVALID_SOCKET ) { break; } if( ! ANSC_SOCKET_FD_ISSET(s_socket, pRecvSet1) ) { AnscTraceError(("AnscBetoRecvTask: XSKT_SOCKET_FD_ISSET returned FALSE.\n")); continue; } } pSocket = (PANSC_BROKER_SOCKET_TCP_OBJECT)pMyObject->GetSocketByOsocket ( (ANSC_HANDLE)pMyObject, s_socket ); if ( !pSocket ) { continue; } /* * We should make sure this socket is still valid before proceeding with the socket * receive operations. For example, the peer may have already closed or reset the * TCP connection while we're serving the previous socket request. * * 10/06/04 - It's believed this modification is slowing down the GUI and we're not * seeing tangible evidence that GUI responsivenss has been improved. So we disable * it for now. * * 11/20/09 - Re-activate the following code segment to validate the socket before * proceeding. */ /* if ( pServer->Mode & ANSC_BSTO_MODE_XSOCKET ) { XSKT_SOCKET_FD_ZERO((&excp_fd_set.xset)); XSKT_SOCKET_FD_SET ((XSKT_SOCKET)s_socket, (&excp_fd_set.xset)); timeval.xtv.tv_sec = 0; timeval.xtv.tv_usec = 0; s_result_excp = _xskt_select(XSKT_SOCKET_FD_SETSIZE, NULL, NULL, &excp_fd_set.xset, &timeval.xtv); } else { ANSC_SOCKET_FD_ZERO((&excp_fd_set.aset)); ANSC_SOCKET_FD_SET (s_socket, (&excp_fd_set.aset)); timeval.atv.tv_sec = 0; timeval.atv.tv_usec = 0; s_result_excp = _ansc_select(ANSC_SOCKET_FD_SETSIZE, NULL, NULL, &excp_fd_set.aset, &timeval.atv); } if ( ((s_result_excp == 1 ) ) || ((s_result_excp == XSKT_SOCKET_ERROR) && (pServer->Mode & ANSC_BSTO_MODE_XSOCKET)) || ((s_result_excp == ANSC_SOCKET_ERROR) && !(pServer->Mode & ANSC_BSTO_MODE_XSOCKET)) ) { if ( TRUE ) { pSocket->bBroken = TRUE; pSocket->bToBeCleaned = TRUE; pMyObject->EnableRecv((ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pSocket, FALSE); pMyObject->EnableSend((ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pSocket, FALSE); } if ( pServer->Mode & ANSC_BSTO_MODE_AUTO_CLOSE ) { pMyObject->DelSocket((ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pSocket); } continue; } */ returnStatus = pMyObject->Recv ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pSocket ); } } AnscSetEvent(&pMyObject->RecvEvent); return ANSC_STATUS_SUCCESS; }
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; }
ANSC_STATUS HttpWcsoRequest ( ANSC_HANDLE hThisObject, ULONG ulMethod, ANSC_HANDLE hReqUri, ANSC_HANDLE hReqContext ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PHTTP_WEBC_SESSION_OBJECT pMyObject = (PHTTP_WEBC_SESSION_OBJECT )hThisObject; PHTTP_WEBC_SESSION_PROPERTY pProperty = (PHTTP_WEBC_SESSION_PROPERTY)&pMyObject->Property; PHTTP_BSP_INTERFACE pBspIf = (PHTTP_BSP_INTERFACE )pMyObject->hBspIf; PHTTP_REQUEST_URI pReqUri = (PHTTP_REQUEST_URI )hReqUri; PHTTP_WEBC_TRANS_OBJECT pWebcTrans = NULL; PHTTP_REQUEST_URI pHttpReqUri = NULL; if ( pMyObject->SessionState != HTTP_WCSO_STATE_SERVER_CONNECTED ) { return ANSC_STATUS_UNAPPLICABLE; } else { pWebcTrans = (PHTTP_WEBC_TRANS_OBJECT)pMyObject->GetCurWcto((ANSC_HANDLE)pMyObject); } if ( !pWebcTrans ) { return ANSC_STATUS_UNAPPLICABLE; } else if ( pWebcTrans->GetTransState((ANSC_HANDLE)pWebcTrans) != HTTP_WCTO_STATE_INITIALIZED ) { pWebcTrans->ReleaseAccess((ANSC_HANDLE)pWebcTrans); return ANSC_STATUS_UNAPPLICABLE; } pHttpReqUri = (PHTTP_REQUEST_URI)AnscAllocateMemory(sizeof(HTTP_REQUEST_URI)); if ( !pHttpReqUri ) { AnscTrace("HttpWcsoRequest - can't create http request URI!\n"); return ANSC_STATUS_RESOURCES; } *pHttpReqUri = *pReqUri; if ( pMyObject->hReqUri ) { AnscFreeMemory(pMyObject->hReqUri); } pMyObject->hReqUri = (ANSC_HANDLE)pHttpReqUri; pMyObject->ReqMethod = ulMethod; pMyObject->Timestamp = AnscGetTickInSeconds(); pMyObject->bRemoveMe = FALSE; returnStatus = pWebcTrans->Request ( (ANSC_HANDLE)pWebcTrans, ulMethod, (ANSC_HANDLE)pReqUri, hReqContext ); pWebcTrans->ReleaseAccess((ANSC_HANDLE)pWebcTrans); return returnStatus; }
ANSC_STATUS DslhWmpdoMonitorTimerInvoke ( ANSC_HANDLE hThisObject ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PDSLH_WMP_DATABASE_OBJECT pMyObject = (PDSLH_WMP_DATABASE_OBJECT )hThisObject; PDSLH_WMP_DATABASE_PROPERTY pProperty = (PDSLH_WMP_DATABASE_PROPERTY)&pMyObject->Property; PDSLH_CPE_CONTROLLER_OBJECT pDslhCpeController = (PDSLH_CPE_CONTROLLER_OBJECT)pMyObject->hDslhCpeController; PDSLH_WMPDO_MONITOR_PARAM pMonitorParam = (PDSLH_WMPDO_MONITOR_PARAM )NULL; PDSLH_VAR_RECORD_OBJECT pDslhVarRecord = (PDSLH_VAR_RECORD_OBJECT )NULL; PDSLH_VAR_ENTITY_OBJECT pDslhVarEntity = (PDSLH_VAR_ENTITY_OBJECT )NULL; PDSLH_CWMP_PARAM_DESCR pParamDesp = (PDSLH_CWMP_PARAM_DESCR )NULL; PSLAP_VARIABLE pNewParamValue = (PSLAP_VARIABLE )NULL; BOOL bValueNotUpdated = (BOOL )TRUE; char* pParamFullName = (char* )NULL; PSINGLE_LINK_ENTRY pSLinkEntry = (PSINGLE_LINK_ENTRY )NULL; BOOL bActiveNotify = FALSE; int oldValue = 0; /* Only for notification with threshold */ int newValue = 0; /* Only for notification with threshold */ AnscAcquireLock(&pMyObject->MpoQueueLock); pSLinkEntry = AnscQueueGetFirstEntry(&pMyObject->MpoQueue); while ( pSLinkEntry ) { pMonitorParam = ACCESS_DSLH_WMPDO_MONITOR_PARAM(pSLinkEntry); pDslhVarRecord = (PDSLH_VAR_RECORD_OBJECT)pMonitorParam->hVarRecord; pSLinkEntry = AnscQueueGetNextEntry(pSLinkEntry); /* * DO NOT synchronize the value if value-changing is in progress... */ if ( pDslhVarRecord->TempParamValue ) { continue; } /* * DO NOT synchronize the value if the active notification parameter is rate-regulated and * the last update was notified less than "NotificationLimit" seconds ago. */ if ( (pDslhVarRecord->Notification == DSLH_CWMP_NOTIFICATION_active) && (pMonitorParam ->NotificationLimit > 0 ) ) { if ( (AnscGetTickInSeconds() - pMonitorParam->Timestamp) < pMonitorParam->NotificationLimit ) { continue; } } if ( pMonitorParam->PreviousValue ) { pNewParamValue = pDslhVarRecord->GetValue((ANSC_HANDLE)pDslhVarRecord); bValueNotUpdated = TRUE; if ( !pNewParamValue ) { continue; } else { SlapEqualVariables(pMonitorParam->PreviousValue, pNewParamValue, bValueNotUpdated); } if ( !bValueNotUpdated ) { /* Notificatoin with threshold check */ pDslhVarEntity = (PDSLH_VAR_ENTITY_OBJECT)pDslhVarRecord->hDslhVarEntity; pParamDesp = (PDSLH_CWMP_PARAM_DESCR )pDslhVarEntity->ParamDescr; if ( pParamDesp && pParamDesp->bThresholdEnabled == TRUE ) { oldValue = pMonitorParam ->PreviousValue->Variant.varInt; newValue = pNewParamValue->Variant.varInt; if ( (oldValue < pParamDesp->NotifyThresholdMin && newValue < pParamDesp->NotifyThresholdMin) || (oldValue > pParamDesp->NotifyThresholdMax && newValue > pParamDesp->NotifyThresholdMax) || (oldValue >= pParamDesp->NotifyThresholdMin && oldValue <= pParamDesp->NotifyThresholdMax && newValue >= pParamDesp->NotifyThresholdMin && newValue <= pParamDesp->NotifyThresholdMax) ) { if ( pMonitorParam->PreviousValue ) { SlapFreeVariable(pMonitorParam->PreviousValue); } pMonitorParam->PreviousValue = pNewParamValue; continue; } } /* save the previous value as old */ if( pDslhVarRecord->OldParamValue != NULL) { SlapFreeVariable(pDslhVarRecord->OldParamValue); } pDslhVarRecord->OldParamValue = pMonitorParam->PreviousValue; /* SlapFreeVariable(pMonitorParam->PreviousValue); */ pMonitorParam->PreviousValue = pNewParamValue; pParamFullName = pDslhVarRecord->GetFullName((ANSC_HANDLE)pDslhVarRecord); if ( pParamFullName ) { bActiveNotify |= (pDslhVarRecord->Notification == DSLH_CWMP_NOTIFICATION_active); pMonitorParam->Timestamp = AnscGetTickInSeconds(); pDslhVarRecord->NotifyValueChanged(pDslhVarRecord); AnscTraceWarning(("DslhWmpdoMonitorTimerInvoke - value change detected on parameter <%s>.\n", pParamFullName)); pDslhVarRecord->ReqSenderID = 0; pMonitorParam->PreviousValue->ReqSenderID = 0; AnscFreeMemory(pParamFullName); } } else { SlapFreeVariable(pNewParamValue); } } else { pMonitorParam->PreviousValue = pDslhVarRecord->GetValue((ANSC_HANDLE)pDslhVarRecord); } } AnscReleaseLock(&pMyObject->MpoQueueLock); 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_HANDLE HttpScoAddWcso ( ANSC_HANDLE hThisObject, char* host, USHORT port, ANSC_HANDLE hReqContext, BOOL bUseTls ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PHTTP_SIMPLE_CLIENT_OBJECT pMyObject = (PHTTP_SIMPLE_CLIENT_OBJECT )hThisObject; PHTTP_SIMPLE_CLIENT_PROPERTY pProperty = (PHTTP_SIMPLE_CLIENT_PROPERTY)&pMyObject->Property; PHTTP_BSP_INTERFACE pBspIf = (PHTTP_BSP_INTERFACE )pMyObject->hBspIf; PHTTP_HFP_INTERFACE pHfpIf = (PHTTP_HFP_INTERFACE )pMyObject->hHfpIf; PHTTP_WEBC_SESSION_OBJECT pWebcSession = (PHTTP_WEBC_SESSION_OBJECT )pMyObject->AcquireWcso((ANSC_HANDLE)pMyObject); ULONG ulHashIndex = AnscHashString2(host, AnscSizeOfString(host), HTTP_SCO_WCSO_TABLE_SIZE); if ( !pWebcSession ) { AnscTrace("HttpScoAddWcso - can't acquire web client session object!\n"); return (ANSC_HANDLE)NULL; } else { ULONG ulWebcSessionMode = bUseTls? HTTP_WCSO_FLAG_tlsEnabled : 0; if ( pMyObject->ClientMode & HTTP_SCO_MODE_XSOCKET ) { ulWebcSessionMode |= HTTP_WCSO_FLAG_xsocketEnabled; } if ( pMyObject->ClientMode & HTTP_SCO_MODE_NOTIFY_ON_ALL_CONN_ONCE ) { ulWebcSessionMode |= HTTP_WCSO_FLAG_BspNotifyOnAllConnOnce; } pWebcSession->hBspReqContext = hReqContext; pWebcSession->Timestamp = AnscGetTickInSeconds(); pWebcSession->HashIndex = ulHashIndex; pWebcSession->SetPeerName ((ANSC_HANDLE)pWebcSession, host ); pWebcSession->SetPeerPort ((ANSC_HANDLE)pWebcSession, port ); pWebcSession->SetHostPort ((ANSC_HANDLE)pWebcSession, 0 ); pWebcSession->SetSessionFlags((ANSC_HANDLE)pWebcSession, ulWebcSessionMode ); pWebcSession->SetBspIf ((ANSC_HANDLE)pWebcSession, (ANSC_HANDLE)pBspIf); pWebcSession->SetHfpIf ((ANSC_HANDLE)pWebcSession, (ANSC_HANDLE)pHfpIf); } returnStatus = pWebcSession->Open((ANSC_HANDLE)pWebcSession); if ( returnStatus != ANSC_STATUS_SUCCESS ) { pWebcSession->Return((ANSC_HANDLE)pWebcSession); return (ANSC_HANDLE)NULL; } AnscAcquireLock (&pMyObject->WcsoTableLock); AnscSListPushEntry(&pMyObject->WcsoTable[ulHashIndex], &pWebcSession->Linkage); pWebcSession->AcquireAccess((ANSC_HANDLE)pWebcSession); AnscReleaseLock (&pMyObject->WcsoTableLock); return (ANSC_HANDLE)pWebcSession; }
ANSC_STATUS AnscDeuoSend ( ANSC_HANDLE hThisObject, ANSC_HANDLE hSocket, PVOID buffer, ULONG ulSize, ANSC_HANDLE hReserved ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_DAEMON_ENGINE_UDP_OBJECT pMyObject = (PANSC_DAEMON_ENGINE_UDP_OBJECT)hThisObject; PANSC_DAEMON_SERVER_UDP_OBJECT pServer = (PANSC_DAEMON_SERVER_UDP_OBJECT)pMyObject->hDaemonServer; PANSC_DSUO_WORKER_OBJECT pWorker = (PANSC_DSUO_WORKER_OBJECT )pServer->hWorker; PANSC_DAEMON_SOCKET_UDP_OBJECT pSocket = (PANSC_DAEMON_SOCKET_UDP_OBJECT)hSocket; int s_result = 0; int s_error = 0; ansc_socket_addr_in to_addr; xskt_socket_addr_in xskt_to_addr; if ( pSocket->bClosed ) { return ANSC_STATUS_UNAPPLICABLE; } else { if ( pServer->Mode & ANSC_DSUO_MODE_XSOCKET ) { xskt_to_addr.sin_family = XSKT_SOCKET_AF_INET; ((pansc_socket_addr_in)&xskt_to_addr)->sin_addr.s_addr = pSocket->PeerAddress.Value; xskt_to_addr.sin_port = _xskt_htons(pSocket->PeerPort); } else { to_addr.sin_family = ANSC_SOCKET_AF_INET; to_addr.sin_addr.s_addr = pSocket->PeerAddress.Value; to_addr.sin_port = _ansc_htons(pSocket->PeerPort); } } if ( pMyObject->ControlFlags & ANSC_DEUO_FLAG_ASYNC_SEND ) { returnStatus = ANSC_STATUS_UNAPPLICABLE; } else { if ( pServer->Mode & ANSC_DSUO_MODE_XSOCKET ) { s_result = _xskt_sendto(pSocket->Socket, buffer, (int)ulSize, 0, (xskt_socket_addr*)&xskt_to_addr, sizeof(xskt_to_addr)); } else { s_result = _ansc_sendto(pSocket->Socket, buffer, (int)ulSize, 0, (ansc_socket_addr*)&to_addr, sizeof(to_addr)); } if ( s_result == ANSC_SOCKET_ERROR ) { s_error = _ansc_get_last_error(); returnStatus = pWorker->SendComplete ( pWorker->hWorkerContext, (ANSC_HANDLE)pSocket, hReserved, ANSC_STATUS_FAILURE ); returnStatus = pWorker->Notify ( pWorker->hWorkerContext, (ANSC_HANDLE)pSocket, ANSC_DSUOWO_EVENT_SOCKET_ERROR, hReserved ); if ( pServer->Mode & ANSC_DSUO_MODE_AUTO_CLOSE ) { pMyObject->DelSocket((ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pSocket); } returnStatus = ANSC_STATUS_FAILURE; } else { returnStatus = pWorker->SendComplete ( pWorker->hWorkerContext, (ANSC_HANDLE)pSocket, hReserved, ANSC_STATUS_SUCCESS ); pSocket->SendBytesCount += ulSize; pSocket->LastSendAt = AnscGetTickInSeconds(); returnStatus = ANSC_STATUS_SUCCESS; } } return returnStatus; }
ANSC_STATUS AnscSctoEngage ( ANSC_HANDLE hThisObject ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_SIMPLE_CLIENT_TCP_OBJECT pMyObject = (PANSC_SIMPLE_CLIENT_TCP_OBJECT)hThisObject; PANSC_SCTO_WORKER_OBJECT pWorker = (PANSC_SCTO_WORKER_OBJECT )pMyObject->hWorker; int s_error = 0; ansc_socket_addr_in ansc_client_addr; ansc_socket_addr_in ansc_server_addr; xskt_socket_addr_in xskt_client_addr; xskt_socket_addr_in xskt_server_addr; #ifdef _ANSC_IPV6_COMPATIBLE_ ansc_addrinfo ansc_hints = {0}; ansc_addrinfo* pansc_server_addrinfo = NULL; ansc_addrinfo* pansc_client_addrinfo = NULL; xskt_addrinfo xskt_hints = {0}; xskt_addrinfo* pxskt_server_addrinfo = NULL; xskt_addrinfo* pxskt_client_addrinfo = NULL; USHORT usPort = 0; char port[6] = {0}; #endif if ( pMyObject->bActive ) { return ANSC_STATUS_SUCCESS; } else if ( !pWorker ) { return ANSC_STATUS_UNAPPLICABLE; } else { /* * Just like any other socket-based ANSC object, we will create a separate async recv task * which is dedicated to receiving packets. This async recv task is controlled by 'bActive' * flag. What if at this moment right before we're about to enable the socket operation and * setting 'bActive' flag to TRUE, the old recv task created by the last call of Engage() * is still running? While it may not cause crash, but it certainly confuses the owner * object because all async recv tasks share the same worker interface. The most obvious * solution is to wait for previous recv task to exit before creating a new one. */ while ( pMyObject->EngineTaskCount != 0 ) { AnscSleep(50); } pMyObject->bActive = TRUE; pMyObject->bClosed = FALSE; } /* * The underlying socket wrapper may require an explicit startup() call, such is the case on * Microsoft windows platforms. The wrapper initialization has to done for each task. On most * real-time operating systems, this call is not required. */ if ( pMyObject->Mode & ANSC_SCTO_MODE_XSOCKET ) { AnscStartupXsocketWrapper((ANSC_HANDLE)pMyObject); } else { AnscStartupSocketWrapper((ANSC_HANDLE)pMyObject); } #ifdef _ANSC_IPV6_COMPATIBLE_ if ( pMyObject->Mode & ANSC_SCTO_MODE_XSOCKET ) { xskt_hints.ai_family = AF_UNSPEC; xskt_hints.ai_socktype = XSKT_SOCKET_STREAM; xskt_hints.ai_flags = AI_CANONNAME; usPort = pMyObject->GetPeerPort((ANSC_HANDLE)pMyObject); _ansc_sprintf(port, "%d", usPort); AnscTrace("!!! Peer Port: %s !!!\n", port); char * pPeerName = pMyObject->GetPeerName((ANSC_HANDLE)pMyObject); AnscTrace("Peer Name: %s!!!\n", pPeerName); /* struct addrinfo hints,*res=NULL; memset(&hints,0,sizeof(hints)); hints.ai_family=PF_UNSPEC; hints.ai_socktype=SOCK_DGRAM; hints.ai_protocol=IPPROTO_UDP; s_error=getaddrinfo("127.0.0.1","123",&hints,&res); */ /* s_error = _xskt_getaddrinfo ( "10.74.52.92", port, &xskt_hints, &pxskt_server_addrinfo ); AnscTrace("!!!!!! _xskt_getaddrinfo returns: %d %s !!!\n", s_error, gai_strerror(s_error)); */ if ( _xskt_getaddrinfo ( pMyObject->GetPeerName((ANSC_HANDLE)pMyObject), port, &xskt_hints, &pxskt_server_addrinfo ) || _xskt_getaddrinfo ( "localhost", NULL, &xskt_hints, &pxskt_client_addrinfo ) ) { AnscTrace("!!! error 1 !!!\n"); if ( pMyObject->Mode & ANSC_SCTO_MODE_NO_BSP_NOTIFY_CONN_ERR == 0 ) { pWorker->Notify ( pWorker->hWorkerContext, ANSC_SCTOWO_EVENT_SOCKET_ERROR, (ANSC_HANDLE)NULL ); } returnStatus = ANSC_STATUS_FAILURE; goto EXIT1; } AnscTrace("!!! after getaddrinfo !!!\n"); } else { ansc_hints.ai_family = AF_UNSPEC; ansc_hints.ai_socktype = ANSC_SOCKET_STREAM; ansc_hints.ai_flags = AI_CANONNAME; usPort = pMyObject->GetPeerPort((ANSC_HANDLE)pMyObject); _ansc_sprintf(port, "%d", usPort); if ( _ansc_getaddrinfo ( pMyObject->GetPeerName((ANSC_HANDLE)pMyObject), port, &ansc_hints, &pansc_server_addrinfo ) || _ansc_getaddrinfo ( "localhost", NULL, &ansc_hints, &pansc_client_addrinfo ) ) { if ( pMyObject->Mode & ANSC_SCTO_MODE_NO_BSP_NOTIFY_CONN_ERR == 0 ) { pWorker->Notify ( pWorker->hWorkerContext, ANSC_SCTOWO_EVENT_SOCKET_ERROR, (ANSC_HANDLE)NULL ); } returnStatus = ANSC_STATUS_FAILURE; goto EXIT1; } } #endif /* * To engage the Tcp Client, we need to perform following acts in the respective order: * * (1) create the os-dependent socket * (2) bind to the newly socket * (3) connect to the specified server address * (4) allocate a buffer for receiving * (5) spawn a separate thread and start receiving */ if ( pMyObject->Mode & ANSC_SCTO_MODE_XSOCKET ) { #ifdef _ANSC_IPV6_COMPATIBLE_ pMyObject->Socket = (ANSC_SOCKET)_xskt_socket(pxskt_server_addrinfo->ai_family, pxskt_server_addrinfo->ai_socktype, 0); #else pMyObject->Socket = (ANSC_SOCKET)_xskt_socket(XSKT_SOCKET_AF_INET, XSKT_SOCKET_STREAM, 0); #endif if ( (XSKT_SOCKET)pMyObject->Socket == XSKT_SOCKET_INVALID_SOCKET ) { AnscTrace("!!!!!!!!!! _xskt_socket error !!!!!!!!!!\n"); if ( pMyObject->Mode & ANSC_SCTO_MODE_NO_BSP_NOTIFY_CONN_ERR == 0 ) { pWorker->Notify ( pWorker->hWorkerContext, ANSC_SCTOWO_EVENT_SOCKET_ERROR, (ANSC_HANDLE)NULL ); } returnStatus = ANSC_STATUS_FAILURE; goto EXIT1; } else AnscTrace("Opening IPv4 socket Ok\n"); } else { #ifdef _ANSC_IPV6_COMPATIBLE_ pMyObject->Socket = _ansc_socket(pansc_server_addrinfo->ai_family, pansc_server_addrinfo->ai_socktype, 0); #else pMyObject->Socket = _ansc_socket(ANSC_SOCKET_AF_INET, ANSC_SOCKET_STREAM, 0); #endif if ( pMyObject->Socket == ANSC_SOCKET_INVALID_SOCKET ) { if ( pMyObject->Mode & ANSC_SCTO_MODE_NO_BSP_NOTIFY_CONN_ERR == 0 ) { pWorker->Notify ( pWorker->hWorkerContext, ANSC_SCTOWO_EVENT_SOCKET_ERROR, (ANSC_HANDLE)NULL ); } returnStatus = ANSC_STATUS_FAILURE; goto EXIT1; } } /* * Normally we don't need to know which local network interface we shall bind to, and the * underlying operating system usually supports such notation as "any address". */ #ifndef _ANSC_IPV6_COMPATIBLE_ if ( pMyObject->Mode & ANSC_SCTO_MODE_XSOCKET ) { xskt_client_addr.sin_family = XSKT_SOCKET_AF_INET; xskt_client_addr.sin_port = _xskt_htons(pMyObject->HostPort); if (pMyObject->bSocketBindToDevice && *(pMyObject->SocketDeviceName)) { if (_xskt_setsocketopt ( pMyObject->Socket, XSKT_SOCKET_SOL_SOCKET, XSKT_SOCKET_SO_BINDTODEVICE, pMyObject->SocketDeviceName, _ansc_strlen(pMyObject->SocketDeviceName) + 1 ) < 0) { perror("setsockopt-SOL_SOCKET-SO_BINDTODEVICE"); returnStatus = ANSC_STATUS_FAILURE; goto EXIT2; } } // fprintf(stderr, "<RT XSKT> Binding socket to Device '%s'.\n", pMyObject->SocketDeviceName); if ( pMyObject->HostAddress.Value == 0 ) { ((pansc_socket_addr_in)&xskt_client_addr)->sin_addr.s_addr = XSKT_SOCKET_ANY_ADDRESS; } else { ((pansc_socket_addr_in)&xskt_client_addr)->sin_addr.s_addr = pMyObject->HostAddress.Value; } if ( _xskt_bind((XSKT_SOCKET)pMyObject->Socket, (xskt_socket_addr*)&xskt_client_addr, sizeof(xskt_client_addr)) != 0 ) { AnscTrace("!!!!!!!!!! _xskt_bind error: socket=%d, error=%d !!!!!!!!!!\n", (XSKT_SOCKET)pMyObject->Socket, errno); { int j; char s[256]; char *ptr1 = ((xskt_socket_addr*)(&xskt_client_addr))->sa_data; char stmp[16]; s[0] = '\0'; for(j=0; j<13; j++) { sprintf(stmp, "%.2x:", *(ptr1++)); strcat(s, stmp); } sprintf(stmp, "%.2x", *ptr1); strcat(s, stmp); AnscTrace("!!!!!!!!!! _xskt_bind error: client_addr=%s\n", s); } perror("_xskt_bind error"); if ( pMyObject->Mode & ANSC_SCTO_MODE_NO_BSP_NOTIFY_CONN_ERR == 0 ) { pWorker->Notify ( pWorker->hWorkerContext, ANSC_SCTOWO_EVENT_SOCKET_ERROR, (ANSC_HANDLE)NULL ); } returnStatus = ANSC_STATUS_FAILURE; goto EXIT2; } } else { ansc_client_addr.sin_family = ANSC_SOCKET_AF_INET; ansc_client_addr.sin_port = _ansc_htons(pMyObject->HostPort); if (pMyObject->bSocketBindToDevice && *(pMyObject->SocketDeviceName)) { if (_xskt_setsocketopt ( pMyObject->Socket, ANSC_SOCKET_SOL_SOCKET, ANSC_SOCKET_SO_BINDTODEVICE, pMyObject->SocketDeviceName, _ansc_strlen(pMyObject->SocketDeviceName) + 1 ) < 0) { perror("setsockopt-SOL_SOCKET-SO_BINDTODEVICE"); returnStatus = ANSC_STATUS_FAILURE; goto EXIT2; } } // fprintf(stderr, "<RT AnscSKT> Binding socket to Device '%s'.\n", pMyObject->SocketDeviceName); if ( pMyObject->HostAddress.Value == 0 ) { ansc_client_addr.sin_addr.s_addr = ANSC_SOCKET_ANY_ADDRESS; } else { ansc_client_addr.sin_addr.s_addr = pMyObject->HostAddress.Value; } if ( _ansc_bind(pMyObject->Socket, (ansc_socket_addr*)&ansc_client_addr, sizeof(ansc_client_addr)) != 0 ) { AnscTrace("!!!!!!!!!! _ansc_bind error: socket=%d, error=%d !!!!!!!!!!\n", (XSKT_SOCKET)pMyObject->Socket, errno); { int j; char s[256]; char *ptr1 = ((ansc_socket_addr*)(&ansc_client_addr))->sa_data; char stmp[16]; s[0] = '\0'; for(j=0; j<13; j++) { sprintf(stmp, "%.2x:", *(ptr1++)); strcat(s, stmp); } sprintf(stmp, "%.2x", *ptr1); strcat(s, stmp); AnscTrace("!!!!!!!!!! _ansc_bind error: client_addr=%s\n", s); } perror("_ansc_bind error"); if ( pMyObject->Mode & ANSC_SCTO_MODE_NO_BSP_NOTIFY_CONN_ERR == 0 ) { pWorker->Notify ( pWorker->hWorkerContext, ANSC_SCTOWO_EVENT_SOCKET_ERROR, (ANSC_HANDLE)NULL ); } returnStatus = ANSC_STATUS_FAILURE; goto EXIT2; } } #endif /* * As a Tcp client application, we now try to connect the network server, whose address is * specified by the "peer address" and "peer port" fields. */ if ( pMyObject->Mode & ANSC_SCTO_MODE_XSOCKET ) { #ifdef _ANSC_IPV6_COMPATIBLE_ BOOL bNoConn = TRUE; #endif _ansc_memset(&xskt_server_addr, 0, sizeof(xskt_server_addr)); xskt_server_addr.sin_family = XSKT_SOCKET_AF_INET; xskt_server_addr.sin_addr.s_addr = pMyObject->PeerAddress.Value; xskt_server_addr.sin_port = _xskt_htons(pMyObject->PeerPort); #ifdef _ANSC_IPV6_COMPATIBLE_ while ( bNoConn && pxskt_server_addrinfo ) { if ( _xskt_connect((XSKT_SOCKET)pMyObject->Socket, pxskt_server_addrinfo->ai_addr, pxskt_server_addrinfo->ai_addrlen) != 0 ) { pxskt_server_addrinfo = pxskt_server_addrinfo->ai_next; /* try next ip address */ } else { bNoConn = FALSE; break; } } if ( bNoConn ) #else if ( _xskt_connect((XSKT_SOCKET)pMyObject->Socket, (xskt_socket_addr*)&xskt_server_addr, sizeof(xskt_server_addr)) != 0 ) #endif { AnscTrace("!!!!!!!!!! _xskt_connect error: socket=%d, error=%d !!!!!!!!!!\n", (XSKT_SOCKET)pMyObject->Socket, errno); { int j; char s[256]; char *ptr1 = ((xskt_socket_addr*)(&xskt_server_addr))->sa_data; char stmp[16]; s[0] = '\0'; for(j=0; j<13; j++) { sprintf(stmp, "%.2x:", *(ptr1++)); strcat(s, stmp); } sprintf(stmp, "%.2x", *ptr1); strcat(s, stmp); AnscTrace("!!!!!!!!!! _xskt_connect error: server_addr=%s\n", s); } perror("_xskt_connect error"); s_error = _xskt_get_last_error(); if ( pMyObject->Mode & ANSC_SCTO_MODE_NO_BSP_NOTIFY_CONN_ERR == 0 ) { pWorker->Notify ( pWorker->hWorkerContext, ANSC_SCTOWO_EVENT_SOCKET_TIMEOUT, (ANSC_HANDLE)NULL ); } returnStatus = ANSC_STATUS_FAILURE; goto EXIT2; } } else { _ansc_memset(&ansc_server_addr, 0, sizeof(ansc_server_addr)); ansc_server_addr.sin_family = ANSC_SOCKET_AF_INET; ansc_server_addr.sin_addr.s_addr = pMyObject->PeerAddress.Value; ansc_server_addr.sin_port = _ansc_htons(pMyObject->PeerPort); #ifdef _ANSC_IPV6_COMPATIBLE_ if ( _ansc_connect(pMyObject->Socket, pansc_server_addrinfo->ai_addr, pansc_server_addrinfo->ai_addrlen) != 0 ) #else if ( _ansc_connect(pMyObject->Socket, (ansc_socket_addr*)&ansc_server_addr, sizeof(ansc_server_addr)) != 0 ) #endif { s_error = _ansc_get_last_error(); AnscTrace("!!! Connect error: %d, %s !!!\n", s_error, strerror(s_error)); if ( pMyObject->Mode & ANSC_SCTO_MODE_NO_BSP_NOTIFY_CONN_ERR == 0 ) { pWorker->Notify ( pWorker->hWorkerContext, ANSC_SCTOWO_EVENT_SOCKET_TIMEOUT, (ANSC_HANDLE)NULL ); } returnStatus = ANSC_STATUS_FAILURE; goto EXIT2; } } /* * We have gone so far that all socket operations succeeded, we want to allocate a buffer that * is big enough for any incoming message. */ if ( !pMyObject->RecvBuffer && !(pMyObject->Mode & ANSC_SCTO_MODE_FOREIGN_BUFFER) ) { pMyObject->RecvBuffer = AnscAllocateMemory(pMyObject->RecvBufferSize); pMyObject->RecvPacketSize = 0; pMyObject->RecvOffset = 0; if ( !pMyObject->RecvBuffer ) { returnStatus = ANSC_STATUS_RESOURCES; goto EXIT2; } } pMyObject->RecvBytesCount = 0; pMyObject->SendBytesCount = 0; pMyObject->LastRecvAt = AnscGetTickInSeconds(); pMyObject->LastSendAt = AnscGetTickInSeconds(); /* * If the compilation option '_ANSC_SOCKET_TLS_LAYER_' is enabled, we can simply let the ANSC * socket layer to perform the SSL/TLS functionality; otherwise, we need to prepare for doing * SSL/TLS internally. */ if ( pMyObject->Mode & ANSC_SCTO_MODE_TLS_ENABLED ) { #ifdef _ANSC_USE_OPENSSL_ pMyObject->bTlsEnabled = TRUE; if ( !openssl_init(SSL_CLIENT_CALLS) ) { AnscTrace("AnscSctoEngage - openssl_init() failed!\n"); returnStatus = ANSC_STATUS_FAILURE; goto EXIT2; } #else #ifdef _ANSC_SOCKET_TLS_LAYER_ { _ansc_en_usetls(pMyObject->Socket); pMyObject->bTlsEnabled = FALSE; } #else { pMyObject->hTlsScsIf = (pMyObject->hTlsScsIf != NULL)? pMyObject->hTlsScsIf : AnscSocketTlsGetScsIf(); pMyObject->bTlsEnabled = TRUE; } #endif #endif } /* * To save the worker object from having to deal with blocking/non-blocking/async receiving * functions provided by underlying socket layer, we create a separate task to do that. */ returnStatus = pMyObject->SpawnTask3 ( (ANSC_HANDLE)pMyObject, (void* )pMyObject->RecvTask, (ANSC_HANDLE)pMyObject, ANSC_SCTO_RECV_TASK_NAME, USER_DEFAULT_TASK_PRIORITY, 11*USER_DEFAULT_TASK_STACK_SIZE ); #ifdef _ANSC_USE_OPENSSL_ if ( pMyObject->bTlsEnabled ) { SSL *ssl = NULL; ssl = openssl_connect (pMyObject->Socket); if ( !ssl ) { pMyObject->bTlsConnected = FALSE; returnStatus = ANSC_STATUS_FAILURE; //PANSC_SCTO_WORKER_OBJECT pWorker = (PANSC_SCTO_WORKER_OBJECT)pMyObject->hWorker; if ( pMyObject->Mode & ANSC_SCTO_MODE_NO_BSP_NOTIFY_CONN_ERR == 0 ) { pWorker->Notify ( pWorker->hWorkerContext, ANSC_SCTOWO_EVENT_TLS_ERROR, (ANSC_HANDLE)0L ); } } else { s_error = openssl_validate_certificate (pMyObject->Socket, pMyObject->HostName, ssl, SSL_CLIENT_CALLS); if ( s_error == 0 ) { AnscTrace("AnscSctoEngage - openssl_validate_certificate() failed %p.\n", ssl); //PANSC_SCTO_WORKER_OBJECT pWorker = (PANSC_SCTO_WORKER_OBJECT )pMyObject->hWorker; if ( pMyObject->Mode & ANSC_SCTO_MODE_NO_BSP_NOTIFY_CONN_ERR == 0 ) { pWorker->Notify ( pWorker->hWorkerContext, ANSC_SCTOWO_EVENT_TLS_ERROR, (ANSC_HANDLE)NULL ); } returnStatus = ANSC_STATUS_FAILURE; } pMyObject->hTlsConnection = ssl; pMyObject->bTlsConnected = TRUE; } } #else /* * If SSL/TLS is enabled, we should complete TLS handshake before returning from Engage(). This * behavior allows a single consistent API to used between this object and the worker object. * Since the handshake will take multiple messages to complete, we need to block the current * task until being notified by the TLS module. */ if ( pMyObject->bTlsEnabled && pMyObject->hTlsScsIf ) { pMyObject->bTlsConnected = FALSE; pMyObject->InitTlsClient((ANSC_HANDLE)pMyObject); } #endif if ( returnStatus != ANSC_STATUS_SUCCESS ) { goto EXIT2; } return ANSC_STATUS_SUCCESS; /****************************************************************** GRACEFUL ROLLBACK PROCEDURES AND EXIT DOORS ******************************************************************/ EXIT2: AnscTrace("AnscSctoEngage - failed with status %lu, socket error %d!\n", returnStatus, s_error); if ( pMyObject->Mode & ANSC_SCTO_MODE_XSOCKET ) { _xskt_closesocket((XSKT_SOCKET)pMyObject->Socket); } else { _ansc_closesocket(pMyObject->Socket); } EXIT1: if ( returnStatus != ANSC_STATUS_SUCCESS ) { pMyObject->bActive = FALSE; pMyObject->Reset((ANSC_HANDLE)pMyObject); } return returnStatus; }
ANSC_STATUS AnscDsuoAcceptTask ( ANSC_HANDLE hThisObject ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_DAEMON_SERVER_UDP_OBJECT pMyObject = (PANSC_DAEMON_SERVER_UDP_OBJECT)hThisObject; PANSC_DSUO_WORKER_OBJECT pWorker = (PANSC_DSUO_WORKER_OBJECT )pMyObject->hWorker; PANSC_DAEMON_ENGINE_UDP_OBJECT pCurEngine = NULL; PANSC_DSUO_PACKET_OBJECT pNewPacket = NULL; int s_result = 0; int s_error = 0; char* recv_buffer = NULL; int recv_size = 0; ansc_fd_set read_fd_set; xskt_fd_set read_fd_set2; ansc_timeval timeval; xskt_timeval timeval2; ansc_socket_addr_in client_addr; xskt_socket_addr_in client_addr2; int addrlen; AnscTrace("AnscDsuoAcceptTask is activated ...!\n"); /* * As a scalable server implemention, we shall accept as many incoming client connections as * possible and can only be limited by the system resources. Once the listening socket becomes * readable, which means an incoming connection attempt has arrived. We create a new socket * object and associate it with the client. This is a repeated process until the socket owner * closes the socket. */ while ( pMyObject->bActive ) { ANSC_COMMIT_TASK(); /* * Since the original bsd compatible socket api doesn't support asynchronous operation, the * nonblocking status polling is the best we can get. As a matter of fact, the current unix * and linux actually still don't support asynchronous notification on any socket operation. */ /* * Since only one socket is included in the fd_set, we only distinguish the result between * one and non-one values. If error is detected, we shall close the socket and notify the * socket owner immediately. */ if ( pMyObject->Mode & ANSC_DSUO_MODE_XSOCKET ) { XSKT_SOCKET_FD_ZERO(&read_fd_set2); XSKT_SOCKET_FD_SET ((XSKT_SOCKET)pMyObject->Socket, &read_fd_set2); timeval2.tv_sec = (ANSC_DSUO_POLL_INTERVAL_MS / 1000); /* number of seconds */ timeval2.tv_usec = (ANSC_DSUO_POLL_INTERVAL_MS % 1000) * 1000; /* number of microseconds */ s_result = _xskt_select(pMyObject->Socket + 1, &read_fd_set2, NULL, NULL, &timeval2); } else { ANSC_SOCKET_FD_ZERO(&read_fd_set); ANSC_SOCKET_FD_SET (pMyObject->Socket, &read_fd_set); timeval.tv_sec = (ANSC_DSUO_POLL_INTERVAL_MS / 1000); /* number of seconds */ timeval.tv_usec = (ANSC_DSUO_POLL_INTERVAL_MS % 1000) * 1000; /* number of microseconds */ s_result = _ansc_select(pMyObject->Socket + 1, &read_fd_set, NULL, NULL, &timeval); } if ( s_result == 0 ) { continue; } else if ( s_result == ANSC_SOCKET_ERROR ) { s_error = _ansc_get_last_error(); continue; } /* * According to de facto standards of bsd compatible socket api, if the socket is currently * in the listen state, it will be marked as readable if an incoming connection request has * been received such that an accept is guaranteed to complete without blocking. */ pNewPacket = (PANSC_DSUO_PACKET_OBJECT)pMyObject->AcquirePacket ( (ANSC_HANDLE)pMyObject ); if ( !pNewPacket ) { continue; } else { recv_buffer = pNewPacket->RecvBuffer; recv_size = pNewPacket->RecvBufferSize; } if ( pMyObject->Mode & ANSC_DSUO_MODE_XSOCKET ) { client_addr2.sin_family = ANSC_SOCKET_AF_INET; ((pansc_socket_addr_in)&client_addr2)->sin_addr.s_addr = 0; client_addr2.sin_port = _xskt_htons(pMyObject->HostPort); addrlen = sizeof(client_addr2); s_result = _xskt_recvfrom(pMyObject->Socket, recv_buffer, recv_size, 0, (xskt_socket_addr*)&client_addr2, &addrlen); } else { client_addr.sin_family = ANSC_SOCKET_AF_INET; client_addr.sin_addr.s_addr = 0; client_addr.sin_port = _ansc_htons(pMyObject->HostPort); addrlen = sizeof(client_addr); s_result = _ansc_recvfrom(pMyObject->Socket, recv_buffer, recv_size, 0, (ansc_socket_addr*)&client_addr, &addrlen); } if ( s_result == ANSC_SOCKET_ERROR ) { s_error = _ansc_get_last_error(); returnStatus = pMyObject->ReleasePacket ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pNewPacket ); continue; } else if ( !pMyObject->bActive ) { returnStatus = pMyObject->ReleasePacket ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pNewPacket ); break; } else { recv_size = s_result; } if ( pMyObject->Mode & ANSC_DSUO_MODE_XSOCKET ) { pNewPacket->PeerAddress.Value = ((pansc_socket_addr_in)&client_addr2)->sin_addr.s_addr; pNewPacket->PeerPort = _ansc_ntohs(client_addr2.sin_port); } else { pNewPacket->PeerPort = _ansc_ntohs(client_addr.sin_port); pNewPacket->PeerAddress.Value = client_addr.sin_addr.s_addr; } pNewPacket->RecvPacketSize = (ULONG)recv_size; pNewPacket->RecvAt = AnscGetTickInSeconds(); /* * We have to assign an engine object to this new packet object. The assignment is done by * address-hashing. However, we need to make sure that the assigned engine object is not * over-loaded. If it is, there're nothing we can do except throwing the packet away. */ pCurEngine = (PANSC_DAEMON_ENGINE_UDP_OBJECT)pMyObject->AssignEngine ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pNewPacket ); if ( !pCurEngine ) { returnStatus = pMyObject->ReleasePacket ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pNewPacket ); continue; } else { returnStatus = pCurEngine->AddPacket ( (ANSC_HANDLE)pCurEngine, (ANSC_HANDLE)pNewPacket ); } if ( returnStatus != ANSC_STATUS_SUCCESS ) { returnStatus = pMyObject->ReleasePacket ( (ANSC_HANDLE)pMyObject, (ANSC_HANDLE)pNewPacket ); } } AnscSetEvent(&pMyObject->AcceptEvent); return ANSC_STATUS_SUCCESS; }
ANSC_STATUS BbhmDiageoResultQueryTask ( ANSC_HANDLE hThisObject ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PBBHM_DIAG_EXEC_OBJECT pMyObject = (PBBHM_DIAG_EXEC_OBJECT )hThisObject; PDSLH_DIAG_INFO_BASE pDiagInfo = NULL; BOOLEAN bQueryDone = FALSE; AnscTraceFlow(("BbhmDiageoResultQueryTask ...\n")); do { returnStatus = pMyObject->RetrieveResult((ANSC_HANDLE)pMyObject); if ( returnStatus == ANSC_STATUS_SUCCESS ) { pDiagInfo = (PDSLH_DIAG_INFO_BASE)pMyObject->hDslhDiagInfo; bQueryDone = TRUE; if ( (pDiagInfo->DiagnosticState != DSLH_DIAG_STATE_TYPE_Inprogress) && (pDiagInfo->DiagnosticState != DSLH_DIAG_STATE_TYPE_Requested) ) { pMyObject->ResultTimestamp = AnscGetTickInSeconds(); break; } } else { /* internal error occurs, quit immediatelly */ break; } AnscWaitEvent(&pMyObject->ResultQueryEvent, 1000); } while ( pMyObject->bResultQueryRunning ); if ( TRUE/*pDiagInfo->RequestType == DSLH_DIAGNOSTIC_REQUEST_TYPE_Acs*/ ) { /* Always notify the initiator */ CcspTraceInfo(("BbhmDiageoResultQueryTask -- notify initiator.....\n")); /* send out the notification */ if ( ANSC_STATUS_SUCCESS != CosaSendDiagCompleteSignal() ) { AnscTraceWarning(("Failed to send event for diagnostics completion.\n")); } } AnscAcquireLock(&pMyObject->AccessLock); AnscTraceFlow(("BbhmDiageoResultQueryTask -- quiting...\n")); /* * stop the diagnostic process */ pMyObject->bResultQueryRunning = FALSE; if ( !bQueryDone ) { pMyObject->StopDiag((ANSC_HANDLE)pMyObject); } AnscSetEvent(&pMyObject->ResultQueryExitEvent); AnscReleaseLock(&pMyObject->AccessLock); AnscTraceFlow(("BbhmDiageoStartDiag -- exit...\n")); return ANSC_STATUS_SUCCESS; }
ANSC_STATUS BwrmPmoInitialize ( ANSC_HANDLE hThisObject ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PBWRM_PAGE_MANAGER_OBJECT pMyObject = (PBWRM_PAGE_MANAGER_OBJECT)hThisObject; ULONG i = 0; /* * Until you have to simulate C++ object-oriented programming style with standard C, you don't * appreciate all the nice little things come with C++ language and all the dirty works that * have been done by the C++ compilers. Member initialization is one of these things. While in * C++ you don't have to initialize all the member fields inherited from the base class since * the compiler will do it for you, such is not the case with C. */ AnscCoInitialize((ANSC_HANDLE)pMyObject); /* * Although we have initialized some of the member fields in the "create" member function, we * repeat the work here for completeness. While this simulation approach is pretty stupid from * a C++/Java programmer perspective, it's the best we can get for universal embedded network * programming. Before we develop our own operating system (don't expect that to happen any * time soon), this is the way things gonna be. */ pMyObject->Oid = BWRM_PAGE_MANAGER_OID; pMyObject->Create = BwrmPmoCreate; pMyObject->Remove = BwrmPmoRemove; pMyObject->EnrollObjects = BwrmPmoEnrollObjects; pMyObject->Initialize = BwrmPmoInitialize; pMyObject->Timestamp = AnscGetTickInSeconds(); pMyObject->bActive = FALSE; pMyObject->GetCacheEnabled = BwrmPmoGetCacheEnabled; pMyObject->SetCacheEnabled = BwrmPmoSetCacheEnabled; pMyObject->GetCacheEntryCount = BwrmPmoGetCacheEntryCount; pMyObject->SetCacheEntryCount = BwrmPmoSetCacheEntryCount; pMyObject->GetCacheMemorySize = BwrmPmoGetCacheMemorySize; pMyObject->SetCacheMemorySize = BwrmPmoSetCacheMemorySize; pMyObject->GetCacheTimeout = BwrmPmoGetCacheTimeout; pMyObject->SetCacheTimeout = BwrmPmoSetCacheTimeout; pMyObject->GetProperty = BwrmPmoGetProperty; pMyObject->SetProperty = BwrmPmoSetProperty; pMyObject->ResetProperty = BwrmPmoResetProperty; pMyObject->Reset = BwrmPmoReset; pMyObject->Engage = BwrmPmoEngage; pMyObject->Cancel = BwrmPmoCancel; pMyObject->CacheTimerInvoke = BwrmPmoCacheTimerInvoke; pMyObject->GetPageCount = BwrmPmoGetPageCount; pMyObject->GetOldestPage = BwrmPmoGetOldestPage; pMyObject->GetPage = BwrmPmoGetPage; pMyObject->AddPage = BwrmPmoAddPage; pMyObject->DelPage = BwrmPmoDelPage; pMyObject->DelAllPages = BwrmPmoDelAllPages; for ( i = 0; i < BWRM_PMO_CPO_TABLE_SIZE; i++ ) { AnscSListInitializeHeader(&pMyObject->CpoTable[i]); } AnscInitializeLock(&pMyObject->CpoTableLock); /* * We shall initialize the configuration properties to the default values, which may be changed * later via the set_property() member function. Note that this call may not guarantee a valid * and legtimate configuration. */ pMyObject->ResetProperty((ANSC_HANDLE)pMyObject); return ANSC_STATUS_SUCCESS; }
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 AnscSctoTsaRecvAppMessage ( ANSC_HANDLE hThisObject, ANSC_HANDLE hMessageBdo ) { ANSC_STATUS returnStatus = ANSC_STATUS_SUCCESS; PANSC_SIMPLE_CLIENT_TCP_OBJECT pMyObject = (PANSC_SIMPLE_CLIENT_TCP_OBJECT)hThisObject; PANSC_SCTO_WORKER_OBJECT pWorker = (PANSC_SCTO_WORKER_OBJECT )pMyObject->hWorker; PANSC_BUFFER_DESCRIPTOR pPayloadBdo = (PANSC_BUFFER_DESCRIPTOR )hMessageBdo; void* pRecvBuffer = (void* )NULL; ANSC_HANDLE hRecvHandle = (ANSC_HANDLE )NULL; ULONG ulRecvSize = (ULONG )0; ULONG ulLeftSize = (ULONG )AnscBdoGetBlockSize(pPayloadBdo); ULONG ulCopySize = (ULONG )0; while ( ulLeftSize > 0 ) { pRecvBuffer = pMyObject->GetRecvBuffer ( (ANSC_HANDLE)pMyObject, &ulRecvSize ); if ( !pRecvBuffer ) { returnStatus = pWorker->Notify ( pWorker->hWorkerContext, ANSC_SCTOWO_EVENT_RESOURCES, (ANSC_HANDLE)NULL ); break; } if ( ulRecvSize >= ulLeftSize ) { ulCopySize = ulLeftSize; } else { ulCopySize = ulRecvSize; } if ( TRUE ) { AnscCopyMemory ( pRecvBuffer, AnscBdoGetBlock(pPayloadBdo), ulCopySize ); AnscBdoShrinkRight(pPayloadBdo, ulCopySize); ulLeftSize -= ulCopySize; } pMyObject->RecvBytesCount += ulCopySize; pMyObject->LastRecvAt = AnscGetTickInSeconds(); returnStatus = pMyObject->Recv ( (ANSC_HANDLE)pMyObject, pRecvBuffer, ulCopySize ); } goto EXIT1; /****************************************************************** GRACEFUL ROLLBACK PROCEDURES AND EXIT DOORS ******************************************************************/ EXIT1: if ( pPayloadBdo ) { AnscFreeBdo((ANSC_HANDLE)pPayloadBdo); } return returnStatus; }