worker.cpp
来自「funambol window mobile客户端源代码」· C++ 代码 · 共 1,085 行 · 第 1/3 页
CPP
1,085 行
case WAIT_OBJECT_0: {
GetExitCodeProcess(procinfo.hProcess, &exitcode);
responseCode = exitcode;
break;
}
default:
responseCode = exitcode;
}
//int responseCode = notifyAddressChange(TEXT(APPLICATION_URI));
//int responseCode = AN_AddressAccepted;
if(responseCode == AN_AddressAccepted ){
setServerNotified(true);
}
else {
setServerNotified(false);
}
LOG.debug("Exiting stpWorker thread: response = %d", responseCode);
return responseCode;
}
// -------------------- CTP --------------------------
/**
* This is the main CTP thread. Manages the CTP connection using CTPManager:
* 1. waits until the stpThread is finished, if successfully we exit this thread
* (STP is working), otherwise continue with CTP (STP is not working)
* 2. Opens the CTP socket connection
* 3. Authenticate the client
* 4. Starts threads to receive messages and to send 'ready' msg.
*
* @param lpv the HANDLE of the stpThread running (NULL if not started)
* @return a value >= 0 if no errors:
* 0 if CTP closed correctly (Client closed CTP)
* 1 if STP is working correctly, CTP not started
* 2 if CTP client not authenticated (at the 2nd AUTH msg)
* 3 if CTP client unauthorized
* 4 if CTP client authentication forbidden
* 5 if STP not working but CTP not started either
* 6 if CTP already active in another instance
* <0 if errors
*
* @note This thread exits only in case of:
* - STPThread ended succesfully (STP is working, CTP not started)
* - CTP client not authenticated
* - CTP in 'leaving state' (Client is closing CTP)
* - CTP started from another instance (code 6)
* In case of socket/Server errors, the whole CTP connection is pulled down
* and restored again in a while (after 'ctpRetry' seconds).
*/
DWORD WINAPI ctpWorker(LPVOID lpv) {
LOG.debug("Starting ctpWorker thread");
int ret = 0;
HANDLE stpThread = (HANDLE)lpv;
// Get the unique instance of CTPManager.
CTPManager* ctpManager = CTPManager::getInstance();
PowerPolicyNotify(PPN_UNATTENDEDMODE, TRUE);
//
// Wait for STPThread to finish.
// - if handle is NULL, no STP has been done -> go with CTP.
// - if STPThread returned error -> go with CTP.
// - if STPThread returned ok -> exit now (STP is running).
//
int timeout = ctpManager->getConfig()->getNotifyTimeout();
if (stpThread) {
LOG.info("Waiting for STP notification sync to finish (timeout = %d sec)...", timeout);
DWORD waitResult = WaitForSingleObject(stpThread, timeout*1000);
switch (waitResult) {
// Thread exited, get exit code.
case WAIT_ABANDONED:
LOG.info("STPThread abandoned");
case WAIT_OBJECT_0: {
DWORD exitcode = 0;
GetExitCodeThread(stpThread, &exitcode);
LOG.debug("STPThread ended with code %d", exitcode);
if (exitcode == 0) {
LOG.info("STP is running correctly, close CTP if active");
CloseHandle(stpThread);
ctpManager->stopCTP();
return 1;
}
else if (exitcode == 420 || exitcode == 401 ||
exitcode == 402 || exitcode == 403) {
// Codes 401/402/403 mean that auth failed, so we don't start CTP
// Code '420' returned by Server means that the Server does not support CTP
// (CTP is supported since Funambol Server 6.5 and code returned is '421')
LOG.info("STP failed, CTP won't start because code returned is %d", exitcode);
CloseHandle(stpThread);
ctpManager->stopCTP();
return 5;
}
else {
// STP failed, go with CTP
LOG.info("STP failed (code %d), go with CTP", exitcode);
break;
}
}
// Thread is still running after timeout -> kill it and continue.
case WAIT_TIMEOUT: {
LOG.info("Timeout - STPThread will now be terminated");
TerminateThread(stpThread, 1);
break;
}
// Some error occurred (case WAIT_FAILED)
default: {
LOG.info("Wait error on STPThread");
break;
}
}
CloseHandle(stpThread);
}
// Safe check: we could have retrieved the ctpManager instance 2 minutes ago...
if (!ctpManager) {
LOG.debug("error: ctpManager not instantiated, exiting.");
ret = 5;
goto finally;
}
// Refresh configuration from registry, save the ctpRetry original value in a buffer
ctpManager->getConfig()->readCTPConfig();
int defaultCtpRetry = ctpManager->getConfig()->getCtpRetry();
// Start the CTP connection process.
// *********************************
// Infinite cycle: always restore the connection if it's lost
// or in case of errors. Exit only if leavingState flag is up.
//
bool restore = false;
bool jump = false;
while (ctpManager->isLeaving() == false) {
if (restore) {
// Restoring from a broken connection: close socket and wait some seconds.
LOG.debug("Restoring CTP connection...");
ctpManager->closeConnection();
int sleepTime = ctpManager->getConfig()->getCtpRetry();
sleepTime = min(sleepTime, ctpManager->getConfig()->getMaxCtpRetry());
LOG.info("CTP will be restored in %d seconds...", sleepTime);
Sleep(sleepTime * 1000);
// CTP could have been restarted during the sleep time!
// So exit if the ctp is active.
if (ctpManager->getCtpState() > CTP_STATE_DISCONNECTED) {
LOG.debug("CTP already active -> don't restore ctp");
ret = 6;
goto finally;
}
// Save the new value to config
sleepTime *= CTP_RETRY_INCREASE_FACTOR; // Double the retry time
ctpManager->getConfig()->setCtpRetry(sleepTime);
restore = false;
}
if (jump) {
// Restoring from a JUMP status: close socket and reconnect immediately.
LOG.debug("Restoring CTP connection from a JUMP...");
ctpManager->closeConnection();
jump = false;
}
while (checkStartSync()) {
// Wait for sync to finish: CTP AUTH phase uses the same clientNonce
// used by sync authentication, so avoid interferences.
LOG.debug("Waiting for sync to finish...");
Sleep(5000);
}
//
// Open socket connection
// ----------------------
LOG.debug("Open CTP connection...");
if (ctpManager->openConnection()) {
restore = true;
continue;
}
//
// Authentication
// --------------
LOG.debug("Sending [AUTH] message...");
if (ctpManager->sendAuthMsg()) {
restore = true;
continue;
}
// Receiving AUTH status message
CTPMessage* authStatusMsg = ctpManager->receiveStatusMsg();
if (!authStatusMsg) {
LOG.error("Error receiving AUTH status msg.");
restore = true;
continue;
}
char authStatus = authStatusMsg->getGenericCommand();
list<CTPParam>::iterator param;
char* buf = NULL;
switch (authStatus) {
case ST_NOT_AUTHENTICATED:
//
// Retry with new nonce received
//
LOG.info("Client not authenticated: retry with new nonce");
if (saveNonceParam(authStatusMsg) == false) {
// NONCE not found -> restore connection
LOG.error("Error receiving NON_AUTHENTICATED Status message: NONCE param is missing");
restore = true;
continue;
}
// Send 2nd auth msg
LOG.info("Sending CTP authentication message...");
if (ctpManager->sendAuthMsg()) {
restore = true;
continue;
}
// Check 2nd status received, only OK allowed
authStatusMsg = ctpManager->receiveStatusMsg();
authStatus = authStatusMsg->getGenericCommand();
if (authStatus == ST_OK) {
// *** Authentication OK! ***
// Save nonce if any (go to case ST_OK)
}
else if (authStatus == ST_NOT_AUTHENTICATED) {
LOG.info("CTP error: Client not authenticated. Please check your credentials.");
showInvalidCredentialsMsgBox(INVALID_CREDENTIALS, 10); // code 401
ret = 2;
goto error;
}
else if (authStatus == ST_UNAUTHORIZED) {
LOG.info("CTP error: Client unauthorized by the Server. Please check your credentials.");
showInvalidCredentialsMsgBox(PAYMENT_REQUIRED, 10); // code 402
ret = 2;
goto error;
}
else {
LOG.info("CTP error: received status '0x%02x'.", authStatus);
ret = 2;
goto error;
}
// no 'break': need to enter into case ST_OK...
case ST_OK:
// *** Authentication OK! ***
LOG.info("Client authenticated successfully!");
ctpManager->setCtpState(CTP_STATE_READY);
ctpManager->getConfig()->setCtpRetry(defaultCtpRetry); // Restore the original ctpRetry time
// Save nonce if any
if (saveNonceParam(authStatusMsg) == false) {
LOG.info("No new nonce received.");
}
break;
// --- note: JUMP not implemented Server side ----
case ST_JUMP:
//
// Jump to desired server 'to' and save the 'from' value
//
LOG.info("Server requested a JUMP");
if (authStatusMsg->params.size() < 1) {
// Expected FROM and TO params -> restore connection
LOG.error("Error receiving JUMP Status message: some parameter is missing");
restore = true;
continue;
}
// Read FROM and TO parameters and update CTPConfig
param = authStatusMsg->params.begin();
while (param != authStatusMsg->params.end()) {
int valueLen = (*param).getValueLength();
void* value = (*param).getValue();
if ((*param).getParamCode() == P_FROM) {
char* from = stringdup((char*)value, valueLen);
ctpManager->getConfig()->setUrlFrom(from);
delete [] from;
}
else if ((*param).getParamCode() == P_TO) {
char* url = stringdup((char*)value, valueLen);
string to = ctpManager->getConfig()->getHostName(url);
int port = ctpManager->getConfig()->getHostPort(url);
ctpManager->getConfig()->setUrlTo(to);
ctpManager->getConfig()->setCtpPort(port);
delete [] url;
}
else {
// Unexpected Status param -> restore connection
LOG.error("Error receiving JUMP Status message: unexpected param '0x%02x'", (*param).getParamCode());
restore = true;
continue;
}
param++;
}
// Now restore the socket connection to the new Server address...
LOG.debug("JUMP status received: FROM %s TO %s:%d", ctpManager->getConfig()->getUrlFrom().c_str(),
ctpManager->getConfig()->getUrlTo().c_str(),
ctpManager->getConfig()->getCtpPort() );
jump = true;
continue;
case ST_UNAUTHORIZED:
// Not authorized -> save nonce if any, exit thread
LOG.info("Unauthorized by the Server, please check your credentials.");
showInvalidCredentialsMsgBox(PAYMENT_REQUIRED, 10); // code 402
if (saveNonceParam(authStatusMsg) == false) {
LOG.debug("No new nonce received.");
}
ret = 3;
goto error;
case ST_FORBIDDEN:
// Authentication forbidden -> exit thread
LOG.info("Authentication forbidden by the Server, please check your credentials.");
showInvalidCredentialsMsgBox(FORBIDDEN, 10); // code 403
ret = 4;
goto error;
case ST_ERROR:
// Error -> restore connection
LOG.info("Received ERROR status from Server: restore ctp connection");
//printErrorStatus(authStatusMsg);
restore = true;
continue;
default:
// Unexpected status -> restore connection
LOG.error("Unexpected status received '0x%02x' -> restore ctp connection", authStatus);
restore = true;
continue;
}
//
// Creates the thread that will be blocked waiting for server msg
// and waits until it ends (errors or ctpConnTimeout).
//
ctpManager->receive();
// If here, connection was broken or ctpConnTimeout -> restore connection
restore = true;
}
goto finally;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?