syncmanager.cpp

来自「funambol window mobile客户端源代码」· C++ 代码 · 共 1,631 行 · 第 1/5 页

CPP
1,631
字号
                    if (isGet) {
                        Get *get = (Get *)cmd;
                        ArrayList *items = get->getItems();
                        bool sendDevInf = false;

                        Results results;
                        for (int i = 0; i < items->size(); i++) {
                            Item *item = (Item *)items->get(i);

                            // we are not very picky: as long as the Item is
                            // called "./devinf11" as required by the standard
                            // we return our device infos
                            Target *target = item->getTarget();
                            if (target && target->getLocURI() &&
                                !strcmp(target->getLocURI(),
                                         DEVINF_URI)) {
                                sendDevInf = true;
                            } else {
                                LOG.debug("ignoring request to Get item #%d", i);
                            }
                        }

                        // cannot send if we have nothing, then simply acknowledge the request,
                        // but ignore it
                        if (sendDevInf && devInf) {
                            AbstractCommand *result = syncMLBuilder.prepareDevInf(cmd, *devInf);
                            if (result) {
                                commands.add(*result);
                                delete result;
                            }
                        }
                    } else {
                        // simply acknowledge Put
                    }

                    if (statusCode) {
                        status = syncMLBuilder.prepareCmdStatus(*cmd, statusCode);
                        if (status) {
		                    // Fire Sync Status Event: status from client
                            fireSyncStatusEvent(status->getCmd(), status->getStatusCode(), NULL, NULL, NULL , CLIENT_STATUS);

                            commands.add(*status);
                            deleteStatus(&status);
                        }
                    }
                }
            }
        }

        //
        // Client Authentication. The auth of the client on the server
        //
        clientChal = syncMLProcessor.getChal(syncml->getSyncBody());

        if (isAuthFailed(ret)) {
            if (clientChal == NULL) {
                requestedAuthType = credentialHandler.getClientAuthType();
            } else {
                requestedAuthType = clientChal->getType();
            }
            if (strcmp(credentialHandler.getClientAuthType(),requestedAuthType) != 0 ) {
                if (clientChal && strcmp(requestedAuthType, AUTH_TYPE_MD5) == 0) {
                    if (clientChal->getNextNonce()) {
                        credentialHandler.setClientNonce(clientChal->getNextNonce()->getValueAsBase64());
                    }
                }
            } else {
                if (strcmp(requestedAuthType, AUTH_TYPE_MD5) == 0 && clientAuthRetries == 1)  {
                    if (clientChal->getNextNonce()) {
                        credentialHandler.setClientNonce(clientChal->getNextNonce()->getValueAsBase64());
                    }

                } else {
                    //lastErrorCode = 401;
                    //sprintf(lastErrorMsg, "Client not authenticated");
                    setError(401, "Client not authenticated");
                    ret = getLastErrorCode();
                    goto finally;
                }
            }
            credentialHandler.setClientAuthType(requestedAuthType);
            clientAuthRetries++;

       } else {
            if (clientChal && strcmp(clientChal->getType(), AUTH_TYPE_MD5) == 0) {
                if (clientChal->getNextNonce()) {
                    credentialHandler.setClientNonce(clientChal->getNextNonce()->getValueAsBase64());
                }
            }
            isClientAuthenticated = true;

            // Get sorted source list from Alert commands sent by server.
            if (sortedSourcesFromServer) {
                delete [] sortedSourcesFromServer;
                sortedSourcesFromServer = NULL;
            }
            sortedSourcesFromServer = syncMLProcessor.getSortedSourcesFromServer(syncml, sourcesNumber);

            for (count = 0; count < sourcesNumber; count ++) {
                if (!sources[count]->getReport()->checkState())
                    continue;
                ret = syncMLProcessor.processServerAlert(*sources[count], syncml);
                if (isErrorStatus(ret)) {
                    setErrorF(ret, "AlertStatus from server %d", ret);
                    LOG.error("%s", getLastErrorMsg());
                    setSourceStateAndError(count, SOURCE_ERROR, ret, getLastErrorMsg());
                }
                fireSyncSourceEvent(sources[count]->getConfig().getURI(),
                                    sources[count]->getConfig().getName(),
                                    sources[count]->getSyncMode(),
                                    0, SYNC_SOURCE_SYNCMODE_REQUESTED);
            }
       }

    } while(isClientAuthenticated == false || isServerAuthenticated == false);

    config.setClientNonce(credentialHandler.getClientNonce());
    config.setServerNonce(credentialHandler.getServerNonce());
    config.setDevInfHash(devInfHash);

    if (isToExit()) {
        // error. no source to sync
        if (!ret) {
            // error: no source to sync
            //ret = lastErrorCode = ERR_NO_SOURCE_TO_SYNC;
            //sprintf(lastErrorMsg, ERRMSG_NO_SOURCE_TO_SYNC);
            setError(ERR_NO_SOURCE_TO_SYNC, ERRMSG_NO_SOURCE_TO_SYNC);
            ret = getLastErrorCode();
        }

        goto finally;
    }

    currentState = STATE_PKG1_SENT;


// ---------------------------------------------------------------------------------------
finally:

    if(ret) {
        //Fire Sync Error Event
        fireSyncEvent(getLastErrorMsg(), SYNC_ERROR);
    }

    if (respURI) {
        delete [] respURI;
    }
    if (responseMsg) {
        safeDelete(&responseMsg);
    }
    if (initMsg) {
        safeDelete(&initMsg);
    }
    if (devInfStr) {
        delete devInfStr;
    }

    deleteSyncML(&syncml);
    deleteCred(&cred);
    deleteAlert(&alert);
    deleteArrayList(&alerts);
    if (alerts){
        delete alerts;
        alerts = NULL;
    }
    deleteStatus(&status);
    deleteChal(&serverChal);
    return ret;
}

//
// utility function to process any <Sync> command that the server might
// have included in its <SyncBody>
//
// @param syncml       the server response
// @param statusList   list to which statuses for changes are to be added
// @return true if a fatal error occurred
//
bool SyncManager::checkForServerChanges(SyncML* syncml, ArrayList &statusList)
{
    bool result = false;

    // Danger, danger: count is a member variable!
    // It has to be because that's the context for some of
    // the other methods. Modifying it has to be careful to
    // restore the initial value before returning because
    // our caller might use it, too.
    int oldCount = this->count;


    //
    // Get the server modifications for each syncsource.
    // We need to work on syncsources in the same order as the server sends them.
    // (use 'sortedSourcesFromServer' list of source names)
    //
    char* sourceUri = NULL;
    int i=0;
    while (sortedSourcesFromServer[i]) {

        sourceUri = sortedSourcesFromServer[i];

        // Retrieve the correspondent index for this syncsource.
        for (count = 0; count < sourcesNumber; count ++) {
            if ( !strcmp(sourceUri, sources[count]->getConfig().getName()) ) {
                break;
            }
        }
        if (count >= sourcesNumber) {
            LOG.error("Source uri not recognized: %s", sourceUri);
            goto finally;
        }

        Sync* sync = syncMLProcessor.getSyncResponse(syncml, i);

        if (sync) {
            const char *locuri = ((Target*)(sync->getTarget()))->getLocURI();

            for (int k = 0; k < sourcesNumber; k++) {
                if (strcmp(locuri, sources[k]->getConfig().getName()) == 0) {
                    count = k;
                    break;
                }
            }
            if (count >= sourcesNumber) {
                LOG.error("Source uri not recognized: %s", sourceUri);
                goto finally;
            }

            if (!sources[count]->getReport()->checkState()) {
                i++;
                continue;
            }

            if (strcmp(prevSourceName, "") == 0) {
                strcpy(prevSourceName, locuri);
            }
            if (strcmp(prevSourceName, locuri) != 0) {
                isFiredSyncEventBEGIN = false;
                fireSyncSourceEvent(prevSourceUri, prevSourceName, prevSyncMode, 0, SYNC_SOURCE_END);
                strcpy(prevSourceName, locuri);
            }
        }

        if (sync) {
            // Fire SyncSource event: BEGIN sync of a syncsource (server modifications)
            // (fire only if <sync> tag exist)
            if (isFiredSyncEventBEGIN == false) {
                fireSyncSourceEvent(sources[count]->getConfig().getURI(),
                        sources[count]->getConfig().getName(),
                        sources[count]->getSyncMode(), 0, SYNC_SOURCE_BEGIN);

                strcpy(prevSourceUri,  sources[count]->getConfig().getURI());
                prevSyncMode = sources[count]->getSyncMode();

                long noc = sync->getNumberOfChanges();
                fireSyncSourceEvent(sources[count]->getConfig().getURI(),
                        sources[count]->getConfig().getName(),
                        sources[count]->getSyncMode(), noc, SYNC_SOURCE_TOTAL_SERVER_ITEMS);

                isFiredSyncEventBEGIN = true;
            }

            ArrayList* items = sync->getCommands();
            Status* status = syncMLBuilder.prepareSyncStatus(*sources[count], sync);
			statusList.add(*status);
            deleteStatus(&status);

            ArrayList* previousStatus = new ArrayList();
            for (int i = 0; i < items->size(); i++) {
                CommandInfo cmdInfo;
                ModificationCommand* modificationCommand = (ModificationCommand*)(items->get(i));
                Meta* meta = modificationCommand->getMeta();
                ArrayList* list = modificationCommand->getItems();

                cmdInfo.commandName = modificationCommand->getName();
                cmdInfo.cmdRef = modificationCommand->getCmdID()->getCmdID();

                if (meta) {
                    cmdInfo.dataType = meta->getType();
                    cmdInfo.format = meta->getFormat();
                    cmdInfo.size = meta->getSize();
                }
                else {
                    cmdInfo.dataType = 0;
                    cmdInfo.format = 0;
                    cmdInfo.size = 0;
                }

                for (int j = 0; j < list->size(); j++) {
                    Item *item = (Item*)list->get(j);
                    if (item == NULL) {
                        LOG.error("SyncManager::checkForServerChanges() - unexpected NULL item.");
                        result = true;
                        goto finally;
                    }
                    // Size might have been included in either the command or the item meta information.
                    // The check for size > 0 is necessary because the function returns 0 even if no
                    // size information was sent by the server - that's okay, for items that really have
                    // size 0 the value doesn't matter as they shouldn't be split into chunks.
                    Meta *itemMeta = item->getMeta();
                    if (itemMeta && itemMeta->getSize() > 0) {
                        cmdInfo.size = itemMeta->getSize();
                    }

                    //
                    // set the syncItem element
                    //
                    status = processSyncItem(item, cmdInfo, syncMLBuilder);

                    if (status) {
                        syncMLBuilder.addItemStatus(previousStatus, status);
                        deleteStatus(&status);
                    }
                }

                if (previousStatus) {
                    statusList.add(previousStatus);
                    deleteArrayList(&previousStatus);
                }
            }
        // Fire SyncSourceEvent: END sync of a syncsource (server modifications)
        //fireSyncSourceEvent(sources[count]->getConfig().getURI(), sources[count]->getConfig().getName(), sources[count]->getSyncMode(), 0, SYNC_SOURCE_END);
            if (previousStatus){
                delete previousStatus;
                previousStatus = NULL;
            }
        }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?