예제 #1
0
void DefaultOperationTcpChannel::sync(TransportType type)
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (isShutdown_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't sync: channel is shut down") % getId());
        return;
    }

    if (isPaused_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't sync: channel is paused") % getId());
        return;
    }

    const auto& suppportedTypes = getSupportedTransportTypes();
    auto it = suppportedTypes.find(type);
    if (it == suppportedTypes.end() || it->second == ChannelDirection::DOWN) {
        KAA_LOG_ERROR(boost::format("Channel [%1%] ignore sync: unsupported transport type %2%")
                                                                        % getId()
                                                                        % LoggingUtils::toString(type));
        return;
    }

    if (!currentServer_) {
        KAA_LOG_DEBUG(boost::format("Channel [%1%] can't sync: server is null") % getId());
        return;
    }

    if (isFirstResponseReceived_) {
        KAA_MUTEX_UNLOCKING("channelGuard_");
        KAA_UNLOCK(lock);
        KAA_MUTEX_UNLOCKED("channelGuard_");

        std::map<TransportType, ChannelDirection> syncTypes;
        syncTypes.insert(std::make_pair(type, it->second));
        for (const auto& typeIt : suppportedTypes) {
            if (typeIt.first != type) {
                syncTypes.insert(std::make_pair(typeIt.first, ChannelDirection::DOWN));
            }
        }

        boost::system::error_code errorCode = sendKaaSync(syncTypes);
        if (errorCode) {
            KAA_LOG_ERROR(boost::format("Channel [%1%] failed to sync: %2%")
                                                                % getId()
                                                                % errorCode.message());
            onServerFailed();
        }
    } else {
        KAA_LOG_DEBUG(boost::format("Channel [%1%] can't sync: waiting for CONNACK + KAASYNC") % getId());
        isPendingSyncRequest_ = true;
    }
}
예제 #2
0
void DefaultOperationTcpChannel::onConnack(const ConnackMessage& message)
{
    KAA_LOG_DEBUG(boost::format("Channel [%1%] received Connack: status %2%")
                                                            % getId()
                                                            % message.getMessage());

    switch (message.getReturnCode()) {
        case ConnackReturnCode::ACCEPTED:
            break;
        case ConnackReturnCode::REFUSE_VERIFICATION_FAILED:
        case ConnackReturnCode::REFUSE_BAD_CREDENTIALS:
            KAA_LOG_WARN(boost::format("Channel [%1%] failed server authentication: %2%")
                                            % getId()
                                            % ConnackMessage::returnCodeToString(message.getReturnCode()));

            onServerFailed(KaaFailoverReason::ENDPOINT_NOT_REGISTERED);

            break;
        default:
            KAA_LOG_ERROR(boost::format("Channel [%1%] failed to connect to server: %2%")
                                                                    % getId()
                                                                    % message.getMessage());
            onServerFailed(KaaFailoverReason::CURRENT_OPERATIONS_SERVER_NA);
            break;
    }
}
예제 #3
0
void DefaultOperationTcpChannel::doShutdown()
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    KAA_LOG_DEBUG(boost::format("Channel [%1%] is shutting down: isShutdown '%2%'")
                                                    % getId()
                                                    % boost::io::group(std::boolalpha, isShutdown_));

    if (!isShutdown_) {
        isShutdown_ = true;
        KAA_MUTEX_UNLOCKING("channelGuard_");
        KAA_UNLOCK(lock);
        KAA_MUTEX_UNLOCKED("channelGuard_");

        closeConnection();

        KAA_LOG_TRACE(boost::format("Channel [%1%] stopping IO service: isStopped '%2%'")
                                                    % getId()
                                                    % boost::io::group(std::boolalpha, io_.stopped()));

        if (!io_.stopped()) {
            io_.stop();
        }

        stopThreads();
    }
}
예제 #4
0
kaa_error_t kaa_platform_protocol_serialize_client_sync(kaa_platform_protocol_t *self
        , const kaa_serialize_info_t *info
        , char **buffer
        , size_t *buffer_size)
{
    KAA_RETURN_IF_NIL4(self, info, buffer, buffer_size, KAA_ERR_BADPARAM);
    KAA_RETURN_IF_NIL3(info->allocator, info->services, info->services_count, KAA_ERR_BADDATA);

    KAA_LOG_TRACE(self->logger, KAA_ERR_NONE, "Serializing client sync...");

    *buffer_size = 0;
    kaa_error_t error = kaa_client_sync_get_size(self, info->services, info->services_count, buffer_size);
    KAA_RETURN_IF_ERR(error)

    KAA_LOG_DEBUG(self->logger, KAA_ERR_NONE, "Going to request sync buffer (size %zu)", *buffer_size);

    *buffer = info->allocator(info->allocator_context, *buffer_size);
    if (*buffer) {
        self->request_id++;
        error = kaa_client_sync_serialize(self, info->services, info->services_count, *buffer, buffer_size);
    } else {
        error = KAA_ERR_WRITE_FAILED;
    }

    if (error) {
        self->request_id--;
    } else {
        KAA_LOG_TRACE(self->logger, KAA_ERR_NONE, "Client sync successfully serialized");
    }

    return error;
}
예제 #5
0
void DefaultOperationTcpChannel::onPingTimeout(const boost::system::error_code& err)
{
    if (!err) {
        sendPingRequest();
    } else {
        KAA_MUTEX_LOCKING("channelGuard_");
        KAA_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
        KAA_MUTEX_LOCKED("channelGuard_");
        if (err != boost::asio::error::operation_aborted && isConnected_) {
            KAA_MUTEX_UNLOCKING("channelGuard_");
            KAA_UNLOCK(channelLock);
            KAA_MUTEX_UNLOCKED("channelGuard_")

            KAA_LOG_ERROR(boost::format("Channel [%1%] failed to process PING: %2%") % getId() % err.message());
            onServerFailed();
            return;
        } else {
            KAA_LOG_DEBUG(boost::format("Channel [%1%] PING timer aborted") % getId());
            return;
        }
    }

    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (isConnected_) {
        setPingTimer();
    }
}
예제 #6
0
void test_empty_log_collector_extension_count(void)
{
    kaa_service_t service = KAA_SERVICE_LOGGING;
    info = (kaa_serialize_info_t *) KAA_MALLOC(sizeof(kaa_serialize_info_t));
    info->services = &service;
    info->services_count = 1;
    info->allocator = &allocator;
    info->allocator_context = mock;

    void *log_storage_context         = NULL;
    void *log_upload_strategy_context = NULL;

    kaa_error_t error_code = ext_unlimited_log_storage_create(&log_storage_context, kaa_context->logger);
    ASSERT_EQUAL(error_code, KAA_ERR_NONE);

    error_code = ext_log_upload_strategy_create(kaa_context
                                              , &log_upload_strategy_context
                                              , KAA_LOG_UPLOAD_VOLUME_STRATEGY);
    ASSERT_EQUAL(error_code, KAA_ERR_NONE);

    error_code = kaa_logging_init(kaa_context->log_collector, log_storage_context, log_upload_strategy_context);
    ASSERT_EQUAL(error_code, KAA_ERR_NONE);

    error_code = kaa_platform_protocol_serialize_client_sync(kaa_context->platform_protocol, info, &buffer, &buffer_size);
    KAA_FREE(info);
    ASSERT_EQUAL(error_code, KAA_ERR_NONE);

    char count_of_extensions = *(buffer + 7);
    KAA_LOG_DEBUG(kaa_context->logger, KAA_ERR_NONE, "count of extensions is %d, expected 1", count_of_extensions);
    ASSERT_EQUAL(count_of_extensions, 1);
}
예제 #7
0
void KaaChannelManager::onTransportConnectionInfoUpdated(ITransportConnectionInfoPtr connectionInfo) {
    if (isShutdown_) {
        KAA_LOG_WARN("Can't update server. Channel manager is down");
        return;
    }
    if (!connectionInfo) {
        KAA_LOG_WARN("Failed to update connection info: bad input data")
        throw KaaException("empty connection info pointer");
    }

    connectionInfo->resetFailedState();

    TransportProtocolId protocolId = connectionInfo->getTransportId();
    if (connectionInfo->getServerType() == ServerType::OPERATIONS) {
        KAA_MUTEX_LOCKING("lastOpsServersGuard_");
        KAA_MUTEX_UNIQUE_DECLARE(lastOpsServers_Lock, lastOpsServersGuard_);
        KAA_MUTEX_LOCKED("lastOpsServersGuard_");

        lastOpsServers_[protocolId] = connectionInfo;
    }

    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    for (auto& channel : channels_) {
        if (channel->getServerType() == connectionInfo->getServerType() && channel->getTransportProtocolId() == protocolId) {
            KAA_LOG_DEBUG(boost::format("Setting a new connection data for channel \"%1%\" %2%")
                        % channel->getId() % LoggingUtils::TransportProtocolIdToString(protocolId));
            channel->setServer(connectionInfo);
        }
    }
}
예제 #8
0
void DefaultOperationTcpChannel::onConnAckTimeout(const boost::system::error_code& err)
{
    if (!err) {
        KAA_LOG_DEBUG(boost::format("Channel [%1%] CONNACK timeout") % getId());
        onServerFailed();
        return;
    } else {
        if (err != boost::asio::error::operation_aborted){
            KAA_LOG_ERROR(boost::format("Channel [%1%] failed to process CONNACK timeout: %2%") % getId() % err.message());
        } else {
            if (isConnected_) {
                KAA_LOG_DEBUG(boost::format("Channel [%1%] CONNACK processed") % getId());
            } else {
                KAA_LOG_DEBUG(boost::format("Channel [%1%] CONNACK timer aborted") % getId());
            }
        }
    }
}
예제 #9
0
boost::system::error_code DefaultOperationTcpChannel::sendKaaSync(const std::map<TransportType, ChannelDirection>& transportTypes)
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");
    KAA_LOG_DEBUG(boost::format("Channel [%1%] sending KAASYNC") % getId());
    const auto& requestBody = multiplexer_->compileRequest(transportTypes);
    const auto& requestEncoded = encDec_->encodeData(requestBody.data(), requestBody.size());
    return sendData(KaaSyncRequest(false, true, 0, requestEncoded, KaaSyncMessageType::SYNC));
}
예제 #10
0
void print_mem_stat(kaa_client_t *kaa_client)
{
    if (!kaa_client)
        return;
    sndc_mem_getStats(&kaa_client->mem_stat);
    KAA_LOG_DEBUG(kaa_client->kaa_context->logger,
            KAA_ERR_NONE,
            "Memory: Total(%d)/Allocated(%d)",
            kaa_client->mem_stat.total,
            kaa_client->mem_stat.allocated);
}
예제 #11
0
void DefaultOperationTcpChannel::syncAck(TransportType type)
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    KAA_LOG_DEBUG(boost::format("Channel [%1%] adding ACK for transport '%2%'")
                                                        % getId()
                                                        % LoggingUtils::toString(type));
    ackTypes_.push_back(type);
}
예제 #12
0
boost::system::error_code DefaultOperationTcpChannel::sendConnect()
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");
    KAA_LOG_DEBUG(boost::format("Channel [%1%] sending CONNECT") % getId());
    const auto& requestBody = multiplexer_->compileRequest(getSupportedTransportTypes());
    const auto& requestEncoded = encDec_->encodeData(requestBody.data(), requestBody.size());
    const auto& sessionKey = encDec_->getEncodedSessionKey();
    const auto& signature = encDec_->signData(sessionKey.data(), sessionKey.size());
    return sendData(ConnectMessage(CHANNEL_TIMEOUT, KAA_PLATFORM_PROTOCOL_AVRO_ID, signature, sessionKey, requestEncoded));
}
예제 #13
0
void DefaultOperationTcpChannel::onDisconnect(const DisconnectMessage& message)
{
    KAA_LOG_DEBUG(boost::format("Channel [%1%] received Disconnect: %2%")
                                                              % getId()
                                                              % message.getMessage());

    KaaFailoverReason failover = (message.getReason() == DisconnectReason::CREDENTIALS_REVOKED ?
                                                            KaaFailoverReason::CREDENTIALS_REVOKED :
                                                            KaaFailoverReason::CURRENT_OPERATIONS_SERVER_NA);

    onServerFailed(failover);
}
예제 #14
0
void KaaChannelManager::onServerFailed(ITransportConnectionInfoPtr connectionInfo) {
    if (isShutdown_) {
        KAA_LOG_WARN("Can't update server. Channel manager is down");
        return;
    }
    if (!connectionInfo) {
        KAA_LOG_WARN("Failed to process server failure: bad input data")
        throw KaaException("empty connection info pointer");
    }

    if (connectionInfo->isFailedState()) {
        KAA_LOG_DEBUG("Connection already failed. Ignoring connection failover!");
        return;
    } else {
        connectionInfo->setFailedState();
    }

    if (connectionInfo->getServerType() == ServerType::BOOTSTRAP) {
        ITransportConnectionInfoPtr nextConnectionInfo = getNextBootstrapServer(connectionInfo->getTransportId(), false);
        if (nextConnectionInfo) {
            onTransportConnectionInfoUpdated(nextConnectionInfo);
        } else {
            FailoverStrategyDecision decision = failoverStrategy_->onFailover(Failover::BOOTSTRAP_SERVERS_NA);
            switch (decision.getAction()) {
                 case FailoverStrategyAction::NOOP:
                     KAA_LOG_WARN("No operation is performed according to failover strategy decision.");
                     break;
                 case FailoverStrategyAction::RETRY:
                 {
                     std::size_t period = decision.getRetryPeriod();
                     KAA_LOG_WARN(boost::format("Attempt to reconnect to first bootstrap server will be made in %1% secs "
                             "according to failover strategy decision.") % period);
                     bsTransportId_ = connectionInfo->getTransportId();
                     retryTimer_.stop();
                     retryTimer_.start(period, [&]
                         {
                             onTransportConnectionInfoUpdated(getNextBootstrapServer(bsTransportId_, true));
                         });
                     break;
                 }
                 case FailoverStrategyAction::STOP_APP:
                     KAA_LOG_WARN("Stopping application according to failover strategy decision!");
                     exit(EXIT_FAILURE);
                     break;
                 default:
                    break;
             }
        }
    } else {
        bootstrapManager_.useNextOperationsServer(connectionInfo->getTransportId());
    }
}
예제 #15
0
void BootstrapManager::useNextOperationsServerByAccessPointId(std::int32_t id)
{
    KAA_R_MUTEX_UNIQUE_DECLARE(lock, guard_);

    KAA_LOG_DEBUG(boost::format("Going to use new operations server: access_point=0x%X") % id);

    auto servers = getOPSByAccessPointId(id);
    if (servers.size() > 0) {
        notifyChannelManangerAboutServer(servers);
    } else {
        serverToApply.reset(new std::int32_t(id));
        bootstrapTransport_->sync();
    }
}
예제 #16
0
void KaaTcpResponseProcessor::processResponseBuffer(const char *buf, std::uint32_t size)
{
    parser_.parseBuffer(buf, size);
    const auto& messages_ = parser_.releaseMessages();
    for (auto it = messages_.begin(); it != messages_.end(); ++it) {
        switch (it->first) {
            case KaaTcpMessageType::MESSAGE_CONNACK:
                KAA_LOG_DEBUG("KaaTcp: CONNACK message received");
                if (onConnack_) {
                    onConnack_(ConnackMessage(it->second.first.get(), it->second.second));
                }
                break;
            case KaaTcpMessageType::MESSAGE_KAASYNC:
                KAA_LOG_DEBUG("KaaTcp: KAASYNC message received");
                if (onKaaSyncResponse_) {
                    onKaaSyncResponse_(KaaSyncResponse(it->second.first.get(), it->second.second));
                }
                break;
            case KaaTcpMessageType::MESSAGE_PINGRESP:
                KAA_LOG_DEBUG("KaaTcp: PINGRESP message received");
                if (onPingResp_) {
                    onPingResp_();
                }
                break;
            case KaaTcpMessageType::MESSAGE_DISCONNECT:
                KAA_LOG_DEBUG("KaaTcp: DISCONNECT message received");
                if (onDisconnect_) {
                    onDisconnect_(DisconnectMessage(it->second.first.get(), it->second.second));
                }
                break;
            default:
                KAA_LOG_ERROR(boost::format("KaaTcp: unexpected message type %1%") % (int) it->first);
                throw KaaException(boost::format("KaaTcp: unexpected message type: %1%") % (int) it->first);
        }
    }
}
예제 #17
0
void DefaultOperationTcpChannel::onReadEvent(const boost::system::error_code& err)
{
    if (!err) {
        std::ostringstream responseStream;
        responseStream << responseBuffer_.get();
        const auto& responseStr = responseStream.str();
        try {
            if (responseStr.empty()) {
                 KAA_LOG_ERROR(boost::format("Channel [%1%] no data read from socket") % getId());
            } else {
                responseProcessor.processResponseBuffer(responseStr.data(), responseStr.size());
            }
        } catch (const TransportRedirectException& exception) {
            KAA_LOG_INFO(boost::format("Channel [%1%] received REDIRECT response") % getId());
            return;
        } catch (const KaaException& exception) {
            KAA_LOG_ERROR(boost::format("Channel [%1%] failed to process data: %2%") % getId() % exception.what());
            onServerFailed();
        }
    } else {
        KAA_LOG_WARN(boost::format("Channel [%1%] socket error: %2%") % getId() % err.message());

        KAA_MUTEX_LOCKING("channelGuard_");
        KAA_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
        KAA_MUTEX_LOCKED("channelGuard_");

        if (err != boost::asio::error::operation_aborted && isConnected_) {
            KAA_MUTEX_UNLOCKING("channelGuard_");
            KAA_UNLOCK(channelLock);
            KAA_MUTEX_UNLOCKED("channelGuard_")

            onServerFailed();
            return;
        } else {
            KAA_LOG_DEBUG(boost::format("Channel [%1%] socket operations aborted") % getId());
            return;
        }
    }

    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (isConnected_) {
        readFromSocket();
    }
}
예제 #18
0
bool KaaChannelManager::addChannelToList(IDataChannelPtr channel)
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_R_MUTEX_UNIQUE_DECLARE(channelLock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    auto res = channels_.insert(channel);

    if (res.second) {
    	channel->setFailoverStrategy(failoverStrategy_);
        channel->setConnectivityChecker(connectivityChecker_);

        ITransportConnectionInfoPtr connectionInfo;

        TransportProtocolId protocolId = channel->getTransportProtocolId();
        if (channel->getServerType() == ServerType::BOOTSTRAP) {
            connectionInfo = getCurrentBootstrapServer(protocolId);
        } else {
            KAA_MUTEX_LOCKING("lastOpsServersGuard_");
            KAA_MUTEX_UNIQUE_DECLARE(lastOpsServers_Lock, lastOpsServersGuard_);
            KAA_MUTEX_LOCKED("lastOpsServersGuard_");

            auto it = lastOpsServers_.find(channel->getTransportProtocolId());
            if (it != lastOpsServers_.end()) {
                connectionInfo = it->second;
            }
        }

        if (connectionInfo) {
            KAA_LOG_DEBUG(boost::format("Setting a new server for channel \"%1%\" %2%")
                        % channel->getId() % LoggingUtils::TransportProtocolIdToString(protocolId));
            channel->setServer(connectionInfo);
        } else {
            if (channel->getServerType() == ServerType::BOOTSTRAP) {
                KAA_LOG_WARN(boost::format("Failed to find bootstrap server for channel \"%1%\" %2%")
                            % channel->getId() % LoggingUtils::TransportProtocolIdToString(protocolId));
            } else {
                KAA_LOG_INFO(boost::format("Failed to find operations server for channel \"%1%\" %2%")
                            % channel->getId() % LoggingUtils::TransportProtocolIdToString(protocolId));
            }
        }
    }

    return res.second;
}
예제 #19
0
void LogCollector::processLogUploadDecision(LogUploadStrategyDecision decision)
{
    switch (decision) {
    case LogUploadStrategyDecision::UPLOAD: {
        KAA_LOG_DEBUG("Going to upload logs");
        doSync();
        break;
    }
    case LogUploadStrategyDecision::NOOP:
        KAA_LOG_TRACE("Nothing to do now");
        if (storage_->getStatus().getRecordsCount() > 0) {
            startLogUploadCheckTimer();
        }
        break;
    default:
        KAA_LOG_WARN("Unknown log upload decision");
        break;
    }
}
예제 #20
0
void EventManager::produceEvent(const std::string& fqn, const std::vector<std::uint8_t>& data,
                                const std::string& target, TransactionIdPtr trxId)
{
    if (fqn.empty()) {
        KAA_LOG_WARN("Failed to process outgoing event: bad input data");
        return;
    }

    KAA_LOG_DEBUG(boost::format("Going to produce Event [FQN: %1%, target: %2%, data_size = %3%]") % fqn
                  % (target.empty() ? "broadcast" : target) % data.size());

    Event event;
    event.eventClassFQN = fqn;
    event.eventData.assign(data.begin(), data.end());

    if (target.empty()) {
        event.target.set_null();
    } else {
        event.target.set_string(target);
    }

    if (trxId) {
        getContainerByTrxId(trxId, context_).push_back(event);
        return;
    }

    KAA_LOG_TRACE(boost::format("New event %1% is produced for %2%") % fqn % target);

    {
        KAA_MUTEX_LOCKING("pendingEventsGuard_");
        KAA_MUTEX_UNIQUE_DECLARE(eventsLock, pendingEventsGuard_);
        KAA_MUTEX_LOCKED("pendingEventsGuard_");
        pendingEvents_.insert(std::make_pair(currentEventIndex_++, event));
        KAA_MUTEX_UNLOCKED("pendingEventsGuard_");
    }

    doSync();
}
예제 #21
0
void DefaultOperationTcpChannel::syncAll()
{
    KAA_MUTEX_LOCKING("channelGuard_");
    KAA_MUTEX_UNIQUE_DECLARE(lock, channelGuard_);
    KAA_MUTEX_LOCKED("channelGuard_");

    if (isShutdown_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't sync: channel is shut down") % getId());
        return;
    }

    if (isPaused_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't sync: channel is on oause") % getId());
        return;
    }

    if (!currentServer_) {
        KAA_LOG_WARN(boost::format("Channel [%1%] can't sync: server is null") % getId());
        return;
    }

    if (isFirstResponseReceived_) {
        KAA_MUTEX_UNLOCKING("channelGuard_");
        KAA_UNLOCK(lock);
        KAA_MUTEX_UNLOCKED("channelGuard_");

        boost::system::error_code errorCode = sendKaaSync(getSupportedTransportTypes());
        if (errorCode) {
            KAA_LOG_ERROR(boost::format("Channel [%1%]. Failed to sync: %2%") % getId() % errorCode.message());
            onServerFailed();
        }
    } else {
        KAA_LOG_DEBUG(boost::format("Can't sync channel [%1%]. Waiting for CONNACK message + KAASYNC message") % getId());
        isPendingSyncRequest_ = true;
    }
}
예제 #22
0
void ConfigurationPersistenceManager::readStoredConfiguration()
{
    if (state_->isSDKPropertiesUpdated()) {
        KAA_LOG_INFO("Ignore loading configuration from storage: configuration version updated");
        return;
    }

    auto hash = configurationHash_.getHashDigest();
    if (hash.empty()) {
        KAA_LOG_DEBUG("Going to read stored configuration.");

        auto bytes = storage_->loadConfiguration();

        if (!bytes.empty()) {
            if (processor_) {
                ignoreConfigurationUpdate_ = true;
                processor_->processConfigurationData(bytes.data(), bytes.size(), true);
            }

            configurationHash_ = EndpointObjectHash(bytes.data(), bytes.size());
            KAA_LOG_INFO(boost::format("Calculated configuration hash: %1%") % LoggingUtils::ByteArrayToString(configurationHash_.getHashDigest()));
        }
    }
}
예제 #23
0
std::vector<std::uint8_t> SyncDataProcessor::compileRequest(const std::map<TransportType, ChannelDirection>& transportTypes)
{
    SyncRequest request;

    request.requestId = ++requestId;
    request.bootstrapSyncRequest.set_null();
    request.configurationSyncRequest.set_null();
    request.eventSyncRequest.set_null();
    request.logSyncRequest.set_null();
    request.notificationSyncRequest.set_null();
    request.profileSyncRequest.set_null();
    request.userSyncRequest.set_null();

    KAA_LOG_DEBUG(boost::format("Compiling sync request. RequestId: %1%") % requestId);

    auto metaRequest = metaDataTransport_->createSyncRequestMetaData();
    request.syncRequestMetaData.set_SyncRequestMetaData(*metaRequest);
    KAA_LOG_DEBUG(boost::format("Compiled SyncRequestMetaData: %1%")
                        % LoggingUtils::toString(request.syncRequestMetaData));

    for (const auto& t : transportTypes) {
        bool isDownDirection = (t.second == ChannelDirection::DOWN);
        switch (t.first) {
            case TransportType::BOOTSTRAP :
                if (isDownDirection) {
                    request.bootstrapSyncRequest.set_null();
                } else if (bootstrapTransport_) {
                    auto ptr = bootstrapTransport_->createBootstrapSyncRequest();
                    if (ptr) {
                        request.bootstrapSyncRequest.set_BootstrapSyncRequest(*ptr);
                    } else {
                        request.bootstrapSyncRequest.set_null();
                    }
                } else {
                    KAA_LOG_WARN("Bootstrap transport was not specified.");
                }
                KAA_LOG_DEBUG(boost::format("Compiled BootstrapSyncRequest: %1%")
                    % LoggingUtils::toString(request.bootstrapSyncRequest));
            break;
            case TransportType::PROFILE :
                if (isDownDirection) {
                    request.profileSyncRequest.set_null();
                } else if (profileTransport_) {
                    auto ptr = profileTransport_->createProfileRequest();
                    if (ptr) {
                        request.profileSyncRequest.set_ProfileSyncRequest(*ptr);
                    } else {
                        request.profileSyncRequest.set_null();
                    }
                } else {
                    KAA_LOG_WARN("Profile transport was not specified.");
                }
                KAA_LOG_DEBUG(boost::format("Compiled ProfileSyncRequest: %1%")
                    % LoggingUtils::toString(request.profileSyncRequest));
                break;
            case TransportType::CONFIGURATION:
#ifdef KAA_USE_CONFIGURATION
                if (configurationTransport_) {
                    auto ptr = configurationTransport_->createConfigurationRequest();
                    if (ptr) {
                        request.configurationSyncRequest.set_ConfigurationSyncRequest(*ptr);
                    } else {
                        request.configurationSyncRequest.set_null();
                    }
                } else {
                    KAA_LOG_WARN("Configuration transport was not specified.");
                }
#endif
                KAA_LOG_DEBUG(boost::format("Compiled ConfigurationSyncRequest: %1%")
                   % LoggingUtils::toString(request.configurationSyncRequest));
                break;
            case TransportType::NOTIFICATION:
#ifdef KAA_USE_NOTIFICATIONS
                if (notificationTransport_) {
                    if (isDownDirection) {
                        request.notificationSyncRequest.set_NotificationSyncRequest(*notificationTransport_->createEmptyNotificationRequest());
                    } else {
                        auto ptr = notificationTransport_->createNotificationRequest();
                        if (ptr) {
                            request.notificationSyncRequest.set_NotificationSyncRequest(*ptr);
                        } else {
                            request.notificationSyncRequest.set_null();
                        }
                    }
                } else {
                    KAA_LOG_WARN("Notification transport was not specified.");
                }
#endif
                KAA_LOG_DEBUG(boost::format("Compiled NotificationSyncRequest: %1%")
                   % LoggingUtils::toString(request.notificationSyncRequest));
                break;
            case TransportType::USER:
#ifdef KAA_USE_EVENTS
                if (isDownDirection) {
                    UserSyncRequest user;
                    user.endpointAttachRequests.set_null();
                    user.endpointDetachRequests.set_null();
                    user.userAttachRequest.set_null();
                    request.userSyncRequest.set_UserSyncRequest(user);
                } else if (userTransport_) {
                    auto ptr = userTransport_->createUserRequest();
                    if (ptr) {
                        request.userSyncRequest.set_UserSyncRequest(*ptr);
                    } else {
                        request.userSyncRequest.set_null();
                    }
                } else {
                    KAA_LOG_WARN("User transport was not specified.");
                }
#endif
                KAA_LOG_DEBUG(boost::format("Compiled UserSyncRequest: %1%")
                    % LoggingUtils::toString(request.userSyncRequest));
                break;
            case TransportType::EVENT:
#ifdef KAA_USE_EVENTS
                if (isDownDirection) {
                    EventSyncRequest event;
                    event.eventListenersRequests.set_null();
                    event.events.set_null();
                    request.eventSyncRequest.set_EventSyncRequest(event);
                } else if (eventTransport_) {
                    auto ptr = eventTransport_->createEventRequest(requestId);
                    if (ptr) {
                        request.eventSyncRequest.set_EventSyncRequest(*ptr);
                    } else {
                        request.eventSyncRequest.set_null();
                    }
                } else {
                    KAA_LOG_WARN("Event transport was not specified.");
                }
#endif
                KAA_LOG_DEBUG(boost::format("Compiled EventSyncRequest: %1%")
                    % LoggingUtils::toString(request.eventSyncRequest));
                break;
            case TransportType::LOGGING:
#ifdef KAA_USE_LOGGING
                if (isDownDirection) {
                    LogSyncRequest log;
                    log.logEntries.set_null();
                    log.requestId = 0;
                    request.logSyncRequest.set_LogSyncRequest(log);
                } else if (loggingTransport_) {
                    auto ptr = loggingTransport_->createLogSyncRequest();
                    if (ptr) {
                        request.logSyncRequest.set_LogSyncRequest(*ptr);
                    } else {
                        request.logSyncRequest.set_null();
                    }
                } else {
                    KAA_LOG_WARN("Log upload transport was not specified.");
                }
#endif
                KAA_LOG_DEBUG(boost::format("Compiled LogSyncRequest: %1%")
                    % LoggingUtils::toString(request.logSyncRequest));
                break;
            default:
                break;
        }
    }

    std::vector<std::uint8_t> encodedData;
    requestConverter_.toByteArray(request, encodedData);

    return encodedData;
}
예제 #24
0
DemultiplexerReturnCode SyncDataProcessor::processResponse(const std::vector<std::uint8_t> &response)
{
    if (response.empty()) {
        return DemultiplexerReturnCode::FAILURE;
    }

    DemultiplexerReturnCode returnCode = DemultiplexerReturnCode::SUCCESS;

    try {
        SyncResponse syncResponse;
        responseConverter_.fromByteArray(response.data(), response.size(), syncResponse);

        KAA_LOG_INFO(boost::format("Got SyncResponse: requestId: %1%, result: %2%")
            % syncResponse.requestId % LoggingUtils::toString(syncResponse.status));

        KAA_LOG_DEBUG(boost::format("Got BootstrapSyncResponse: %1%")
            % LoggingUtils::toString(syncResponse.bootstrapSyncResponse));

        if (!syncResponse.bootstrapSyncResponse.is_null()) {
            if (bootstrapTransport_) {
                bootstrapTransport_->onBootstrapResponse(syncResponse.bootstrapSyncResponse.get_BootstrapSyncResponse());
            } else {
                KAA_LOG_ERROR("Got bootstrap sync response, but bootstrap transport was not set!");
            }
        }

        KAA_LOG_DEBUG(boost::format("Got ProfileSyncResponse: %1%")
            % LoggingUtils::toString(syncResponse.profileSyncResponse));

        if (!syncResponse.profileSyncResponse.is_null()) {
            if (profileTransport_) {
                profileTransport_->onProfileResponse(syncResponse.profileSyncResponse.get_ProfileSyncResponse());
            } else {
                KAA_LOG_ERROR("Got profile sync response, but profile transport was not set!");
            }
        }

        KAA_LOG_DEBUG(boost::format("Got ConfigurationSyncResponse: %1%")
                % LoggingUtils::toString(syncResponse.configurationSyncResponse));

#ifdef KAA_USE_CONFIGURATION
        if (!syncResponse.configurationSyncResponse.is_null()) {
            if (configurationTransport_) {
                configurationTransport_->onConfigurationResponse(syncResponse.configurationSyncResponse.get_ConfigurationSyncResponse());
            } else {
                KAA_LOG_ERROR("Got configuration sync response, but configuration transport was not set!");
            }
        }
#endif

        KAA_LOG_DEBUG(boost::format("Got EventSyncResponse: %1%")
                % LoggingUtils::toString(syncResponse.eventSyncResponse));

#ifdef KAA_USE_EVENTS
        if (eventTransport_) {
            eventTransport_->onSyncResponseId(syncResponse.requestId);
            if (!syncResponse.eventSyncResponse.is_null()) {
                    eventTransport_->onEventResponse(syncResponse.eventSyncResponse.get_EventSyncResponse());
            }
        } else {
            KAA_LOG_ERROR("Event transport was not set!");
        }
#endif

        KAA_LOG_DEBUG(boost::format("Got NotificationSyncResponse: %1%")
                % LoggingUtils::toString(syncResponse.notificationSyncResponse));

#ifdef KAA_USE_NOTIFICATIONS
        if (!syncResponse.notificationSyncResponse.is_null()) {
            if (notificationTransport_) {
                notificationTransport_->onNotificationResponse(syncResponse.notificationSyncResponse.get_NotificationSyncResponse());
            } else {
                KAA_LOG_ERROR("Got notification sync response, but notification transport was not set!");
            }
        }
#endif

        KAA_LOG_DEBUG(boost::format("Got UserSyncResponse: %1%")
                % LoggingUtils::toString(syncResponse.userSyncResponse));

#ifdef KAA_USE_EVENTS
        if (!syncResponse.userSyncResponse.is_null()) {
            if (userTransport_) {
                userTransport_->onUserResponse(syncResponse.userSyncResponse.get_UserSyncResponse());
            } else {
                KAA_LOG_ERROR("Got user sync response, but user transport was not set!");
            }
        }
#endif

        KAA_LOG_DEBUG(boost::format("Got LogSyncResponse: %1%")
                % LoggingUtils::toString(syncResponse.logSyncResponse));

#ifdef KAA_USE_LOGGING
        if (!syncResponse.logSyncResponse.is_null()) {
            if (loggingTransport_) {
                loggingTransport_->onLogSyncResponse(syncResponse.logSyncResponse.get_LogSyncResponse());
            } else {
                KAA_LOG_ERROR("Got log upload sync response, but logging transport was not set!");
            }
        }
#endif

        KAA_LOG_DEBUG(boost::format("Got RedirectSyncResponse: %1%")
                % LoggingUtils::toString(syncResponse.redirectSyncResponse));

        if (!syncResponse.redirectSyncResponse.is_null()) {
            if (redirectionTransport_) {
                redirectionTransport_->onRedirectionResponse(syncResponse.redirectSyncResponse.get_RedirectSyncResponse());
                returnCode = DemultiplexerReturnCode::REDIRECT;
            } else {
                KAA_LOG_ERROR("Got redirection sync response, but redirection transport was not set!");
            }
        }

        bool needProfileResync = (syncResponse.status == SyncResponseResultType::PROFILE_RESYNC);
        context_.getStatus().setProfileResyncNeeded(needProfileResync);

        if (needProfileResync) {
            if (profileTransport_) {
                KAA_LOG_INFO("Profile resync received");
                profileTransport_->sync();
            } else {
                KAA_LOG_ERROR("Got profile resync request, but profile transport was not set!");
            }
        }

        context_.getStatus().save();

        KAA_LOG_DEBUG("Processed SyncResponse");
    } catch (const std::exception& e) {
        KAA_LOG_ERROR(boost::format("Unable to process response: %s") % e.what());
        returnCode = DemultiplexerReturnCode::FAILURE;
    }
    return returnCode;
}
예제 #25
0
파일: kaa_client.c 프로젝트: kaaproject/kaa
kaa_error_t kaa_client_process_channel_connected(kaa_client_t *kaa_client)
{
    KAA_RETURN_IF_NIL(kaa_client, KAA_ERR_BADPARAM);

    fd_set read_fds, write_fds, except_fds;
    struct timeval select_tv = { get_poll_timeout(kaa_client), 0 };
    int channel_fd = 0;

    FD_ZERO(&read_fds);
    FD_ZERO(&write_fds);
    FD_ZERO(&except_fds);

    kaa_error_t error_code = kaa_tcp_channel_get_descriptor(&kaa_client->channel, &channel_fd);
    if(error_code) KAA_LOG_ERROR(kaa_client->context->logger, error_code, "No descriptor provided!");

    if (kaa_tcp_channel_is_ready(&kaa_client->channel, FD_READ))
        FD_SET(channel_fd, &read_fds);
    if (kaa_tcp_channel_is_ready(&kaa_client->channel, FD_WRITE))
        FD_SET(channel_fd, &write_fds);

    int poll_result = select(channel_fd + 1, &read_fds, &write_fds, NULL, &select_tv);
    if (poll_result == 0) {
       error_code =  kaa_tcp_channel_check_keepalive(&kaa_client->channel);
    } else if (poll_result > 0) {
        if (channel_fd >= 0) {
            if (FD_ISSET(channel_fd, &read_fds)) {
                KAA_LOG_DEBUG(kaa_client->context->logger, KAA_ERR_NONE,
                        "Processing IN event for the client socket %d", channel_fd);
                error_code = kaa_tcp_channel_process_event(&kaa_client->channel, FD_READ);
                if (error_code) {
                    KAA_LOG_ERROR(kaa_client->context->logger, error_code,
                            "Failed to process IN event for the client socket %d", channel_fd);
                }
            }
            if (FD_ISSET(channel_fd, &write_fds)) {
                KAA_LOG_DEBUG(kaa_client->context->logger, KAA_ERR_NONE,
                        "Processing OUT event for the client socket %d", channel_fd);

                error_code = kaa_tcp_channel_process_event(&kaa_client->channel, FD_WRITE);
                if (error_code) {
                    KAA_LOG_ERROR(kaa_client->context->logger, error_code,
                            "Failed to process OUT event for the client socket %d", channel_fd);
                }
            }
        }
    } else {
        KAA_LOG_ERROR(kaa_client->context->logger, KAA_ERR_BAD_STATE, "Failed to poll descriptors");
        error_code = KAA_ERR_BAD_STATE;
    }

    if (kaa_client->channel_socket_closed) {
        KAA_LOG_INFO(kaa_client->context->logger, KAA_ERR_NONE,
                "Channel [0x%08X] connection terminated", kaa_client->channel_id);

        kaa_client->channel_state = KAA_CLIENT_CHANNEL_STATE_NOT_CONNECTED;
        if (error_code != KAA_ERR_EVENT_NOT_ATTACHED) {
            kaa_client_deinit_channel(kaa_client);
        }
    }

    return error_code;
}
예제 #26
0
int kaa_demo_event_loop()
{
    kaa_error_t error_code = kaa_start(kaa_context_);
    if (error_code) {
        KAA_LOG_FATAL(kaa_context_->logger, error_code,"Failed to start Kaa workflow");
        return -1;
    }

    uint16_t select_timeout;
    error_code = kaa_tcp_channel_get_max_timeout(&operations_channel, &select_timeout);
    if (error_code) {
        KAA_LOG_FATAL(kaa_context_->logger, error_code,"Failed to get Operations channel keepalive timeout");
        return -1;
    }

    if (select_timeout > KAA_DEMO_LOG_GENERATION_FREQUENCY) {
        select_timeout = KAA_DEMO_LOG_GENERATION_FREQUENCY;
    }

    fd_set read_fds, write_fds, except_fds;
    int ops_fd = 0, bootstrap_fd = 0;
    struct timeval select_tv = { 0, 0 };
    int max_fd = 0;

    while (log_record_counter < KAA_DEMO_LOGS_TO_SEND) {
        FD_ZERO(&read_fds);
        FD_ZERO(&write_fds);
        FD_ZERO(&except_fds);

        max_fd = 0;

        kaa_tcp_channel_get_descriptor(&operations_channel, &ops_fd);
        if (max_fd < ops_fd)
            max_fd = ops_fd;
        kaa_tcp_channel_get_descriptor(&bootstrap_channel, &bootstrap_fd);
        if (max_fd < bootstrap_fd)
            max_fd = bootstrap_fd;

        if (kaa_tcp_channel_is_ready(&operations_channel, FD_READ))
            FD_SET(ops_fd, &read_fds);
        if (kaa_tcp_channel_is_ready(&operations_channel, FD_WRITE))
            FD_SET(ops_fd, &write_fds);

        if (kaa_tcp_channel_is_ready(&bootstrap_channel, FD_READ))
            FD_SET(bootstrap_fd, &read_fds);
        if (kaa_tcp_channel_is_ready(&bootstrap_channel, FD_WRITE))
            FD_SET(bootstrap_fd, &write_fds);

        select_tv.tv_sec = select_timeout;
        select_tv.tv_usec = 0;

        int poll_result = select(max_fd + 1, &read_fds, &write_fds, NULL, &select_tv);
        if (poll_result == 0) {
            kaa_demo_add_log_record();
            kaa_tcp_channel_check_keepalive(&operations_channel);
            kaa_tcp_channel_check_keepalive(&bootstrap_channel);
        } else if (poll_result > 0) {
            if (bootstrap_fd >= 0) {
                if (FD_ISSET(bootstrap_fd, &read_fds)) {
                    KAA_LOG_DEBUG(kaa_context_->logger, KAA_ERR_NONE,"Processing IN event for the Bootstrap client socket %d", bootstrap_fd);
                    error_code = kaa_tcp_channel_process_event(&bootstrap_channel, FD_READ);
                    if (error_code)
                        KAA_LOG_ERROR(kaa_context_->logger, KAA_ERR_NONE,"Failed to process IN event for the Bootstrap client socket %d", bootstrap_fd);
                }
                if (FD_ISSET(bootstrap_fd, &write_fds)) {
                    KAA_LOG_DEBUG(kaa_context_->logger, KAA_ERR_NONE,"Processing OUT event for the Bootstrap client socket %d", bootstrap_fd);
                    error_code = kaa_tcp_channel_process_event(&bootstrap_channel, FD_WRITE);
                    if (error_code)
                        KAA_LOG_ERROR(kaa_context_->logger, error_code,"Failed to process OUT event for the Bootstrap client socket %d", bootstrap_fd);
                }
            }
            if (ops_fd >= 0) {
                if (FD_ISSET(ops_fd, &read_fds)) {
                    KAA_LOG_DEBUG(kaa_context_->logger, KAA_ERR_NONE,"Processing IN event for the Operations client socket %d", ops_fd);
                    error_code = kaa_tcp_channel_process_event(&operations_channel, FD_READ);
                    if (error_code)
                        KAA_LOG_ERROR(kaa_context_->logger, error_code,"Failed to process IN event for the Operations client socket %d", ops_fd);
                }
                if (FD_ISSET(ops_fd, &write_fds)) {
                    KAA_LOG_DEBUG(kaa_context_->logger, KAA_ERR_NONE,"Processing OUT event for the Operations client socket %d", ops_fd);
                    error_code = kaa_tcp_channel_process_event(&operations_channel, FD_WRITE);
                    if (error_code)
                        KAA_LOG_ERROR(kaa_context_->logger, error_code,"Failed to process OUT event for the Operations client socket %d", ops_fd);
                }
            }
        } else {
            KAA_LOG_ERROR(kaa_context_->logger, KAA_ERR_BAD_STATE,"Failed to poll descriptors: %s", strerror(errno));
            return -1;
        }
    }
    return 0;
}
예제 #27
0
void BootstrapManager::onServerListUpdated(const std::vector<ProtocolMetaData>& operationsServers)
{
    if (operationsServers.empty()) {
        KAA_LOG_WARN("Received empty operations server list");
        FailoverStrategyDecision decision = failoverStrategy_->onFailover(Failover::NO_OPERATION_SERVERS);
        switch (decision.getAction()) {
			case FailoverStrategyAction::NOOP:
				KAA_LOG_WARN("No operation is performed according to failover strategy decision.");
				break;
			case FailoverStrategyAction::RETRY:
			{
				std::size_t period = decision.getRetryPeriod();
				KAA_LOG_WARN(boost::format("Attempt to receive operations server list will be made in %1% secs "
						"according to failover strategy decision.") % period);
				retryTimer_.stop();
				retryTimer_.start(period, [&] { receiveOperationsServerList(); });
				break;
			}
			case FailoverStrategyAction::STOP_APP:
				KAA_LOG_WARN("Stopping application according to failover strategy decision!");
				exit(EXIT_FAILURE);
				break;
		}
        return;
    }

    KAA_R_MUTEX_UNIQUE_DECLARE(lock, guard_);

    KAA_LOG_INFO(boost::format("Received %1% new operations servers") % operationsServers.size());

    lastOperationsServers_.clear();
    operationServers_.clear();

    for (const auto& serverMetaData : operationsServers) {
        ITransportConnectionInfoPtr connectionInfo(
                new GenericTransportInfo(ServerType::OPERATIONS, serverMetaData));

        auto& servers = operationServers_[serverMetaData.protocolVersionInfo];
        servers.push_back(connectionInfo);
    }

    for (auto& transportSpecificServers : operationServers_) {
        std::shuffle (transportSpecificServers.second.begin()
                    , transportSpecificServers.second.end()
                    , std::default_random_engine(std::chrono::high_resolution_clock::now().time_since_epoch().count()));

        lastOperationsServers_[transportSpecificServers.first] =
                                    transportSpecificServers.second.begin();
    }

    if (serverToApply) {
        auto servers = getOPSByAccessPointId(*serverToApply);
        if (!servers.empty()) {
            KAA_LOG_DEBUG(boost::format("Found %1% servers by access point id %2%")
                                            % servers.size() % *serverToApply);
            serverToApply.reset();
            notifyChannelManangerAboutServer(servers);
        }
    } else {
        for (const auto& transportSpecificServers : operationServers_) {
            channelManager_->onTransportConnectionInfoUpdated(transportSpecificServers.second.front());
        }
    }
}
예제 #28
0
void thread_run_fn(uintptr_t arg)
{
    if(!arg) {
        sndc_printf("Kaa client thread function Error, no args\n");
        return;
    }

    kaa_client_t *self = (kaa_client_t *)arg;
    KAA_LOG_TRACE(self->kaa_context->logger, KAA_ERR_NONE, "Kaa client working thread started....");
    sndc_sem_post(&self->logging_semophore);

    sndc_sock_fdset r_set;
    sndc_sock_fdset w_set;
    sndc_sock_fdset x_set;
    int r = 0;
    int max_fd = 0;
    uint32_t msec = 0;
    int ops_fd = -1, bootstrap_fd = -1;
    bool_t fdset = false;
    uint16_t timeout = self->max_update_time;
    kaa_error_t error_code;
    KAA_LOG_TRACE(self->kaa_context->logger, KAA_ERR_NONE, "Kaa client working thread(%s) wait starting...", self->thread_name);
    sndc_sem_wait(&self->start_semophore);
    KAA_LOG_INFO(self->kaa_context->logger, KAA_ERR_NONE, "Kaa client working thread(%s) started", self->thread_name);

    while(self->operate) {
        max_fd = 0;
        SNDC_FD_ZERO(&r_set);
        SNDC_FD_ZERO(&w_set);
        SNDC_FD_ZERO(&x_set);

        // This semaphore is used to synchronize main thread and kaa_client thread,
        // mostly for logging proposes.
        sndc_sem_tryWait(&self->logging_semophore);

        if (self->operations_channel.context)
            kaa_tcp_channel_get_descriptor(&self->operations_channel, &ops_fd);
        if(self->bootstrap_channel.context)
            kaa_tcp_channel_get_descriptor(&self->bootstrap_channel, &bootstrap_fd);
        KAA_LOG_DEBUG(self->kaa_context->logger, KAA_ERR_NONE, "IO LOOP: descriptors: bootstrap(%d), operations(%d)", bootstrap_fd, ops_fd);

        print_mem_stat(self);

        if (bootstrap_fd >= 0) {
            fdset = false;
            if (kaa_tcp_channel_is_ready(&self->bootstrap_channel, FD_READ)) {
                SNDC_FD_SET(bootstrap_fd, &r_set);
                KAA_LOG_DEBUG(self->kaa_context->logger,
                        KAA_ERR_NONE,
                        "IO LOOP: Bootstrap READ set wait");
                fdset = true;
            }
            if (kaa_tcp_channel_is_ready(&self->bootstrap_channel, FD_WRITE)) {
                SNDC_FD_SET(bootstrap_fd, &w_set);
                KAA_LOG_DEBUG(self->kaa_context->logger,
                        KAA_ERR_NONE,
                        "IO LOOP: Bootstrap WRITE set wait");
                fdset = true;
            }
            if (fdset) {
                max_fd = MAX(max_fd, bootstrap_fd);
                SNDC_FD_SET(bootstrap_fd, &x_set);
            }
        }
        if (ops_fd >= 0) {
            fdset = false;
            if (kaa_tcp_channel_is_ready(&self->operations_channel, FD_READ)) {
                SNDC_FD_SET(ops_fd, &r_set);
                KAA_LOG_DEBUG(self->kaa_context->logger,
                        KAA_ERR_NONE,
                        "IO LOOP: Operations READ set wait");
                fdset = true;
            }
            if (kaa_tcp_channel_is_ready(&self->operations_channel, FD_WRITE)) {
                SNDC_FD_SET(ops_fd, &w_set);
                KAA_LOG_DEBUG(self->kaa_context->logger,
                        KAA_ERR_NONE,
                        "IO LOOP: Operations WRITE set wait");
                fdset = true;
            }
            if (fdset) {
                max_fd = MAX(max_fd, ops_fd);
                SNDC_FD_SET(ops_fd, &x_set);
            }
        }

        kaa_tcp_channel_get_max_timeout(&self->operations_channel, &timeout);
        self->timeval.tv_sec = timeout;
        if (timeout > self->max_update_time)
            self->timeval.tv_sec = self->max_update_time;

        self->timeval.tv_usec = 0;
        sndc_sem_post(&self->logging_semophore);
        r = sndc_sock_select(max_fd+1,&r_set,&w_set,&x_set,&self->timeval);
        sndc_sem_tryWait(&self->logging_semophore);
        if (r == 0) {
            msec = sndc_sys_getTimestamp_msec();
            KAA_LOG_DEBUG(self->kaa_context->logger,
                    KAA_ERR_NONE,
                    "IO LOOP: timeout (%d) expired",
                    self->timeval.tv_sec);

            if (self->bootstrap_state == BOOTSRAP_FINISHED && bootstrap_fd == -1) {
                sndc_printf("Bootstrap channel deinit, Operations channel init %d\n", bootstrap_fd);
                KAA_LOG_INFO(self->kaa_context->logger,
                                    KAA_ERR_NONE,
                                    "IO LOOP: Bootstrap channel finish processing switching to Operations channel");
                kaa_client_deinit_bootstrap_channel(self);
                kaa_client_init_operations_channel(self);
            }

            if (self->bootstrap_channel.context) {
                error_code = kaa_tcp_channel_check_keepalive(&self->bootstrap_channel);
                if (error_code) {
                    KAA_LOG_ERROR(self->kaa_context->logger,
                            KAA_ERR_NONE,
                            "IO LOOP: Failed Keepalive Bootstrap(%d) check",
                            bootstrap_fd);
                }
            }
            if (self->operations_channel.context) {
                error_code = kaa_tcp_channel_check_keepalive(&self->operations_channel);
                if (error_code) {
                    KAA_LOG_ERROR(self->kaa_context->logger,
                            KAA_ERR_NONE,
                            "IO LOOP: Failed Keepalive Operations(%d) check",
                            ops_fd);
                }
            }
        } else if (r > 0) {
            sndc_printf("FD SET return %d events\n", r);
            KAA_LOG_DEBUG(self->kaa_context->logger,
                    KAA_ERR_NONE,
                    "IO LOOP: select() return %d events", r);
            if (bootstrap_fd >= 0) {
                fdset = false;
                if (SNDC_FD_ISSET(bootstrap_fd, &r_set)) {
                    fdset = true;
                    KAA_LOG_DEBUG(self->kaa_context->logger,
                                        KAA_ERR_NONE,
                                        "IO LOOP: Read Event Bootstrap(%d)", bootstrap_fd);
                    error_code = kaa_tcp_channel_process_event(&self->bootstrap_channel, FD_READ);
                    if (error_code) {
                        KAA_LOG_ERROR(self->kaa_context->logger,
                                        error_code,
                                        "IO LOOP: Failed Read Event Bootstrap(%d)", bootstrap_fd);
                    }
                }
                if (fdset)
                    r--;
                if (r > 0) {
                    fdset = false;
                    if (SNDC_FD_ISSET(bootstrap_fd, &w_set)) {
                        fdset = true;
                        KAA_LOG_DEBUG(self->kaa_context->logger,
                                        KAA_ERR_NONE,
                                        "IO LOOP: Write Event Bootstrap(%d)", bootstrap_fd);
                        error_code = kaa_tcp_channel_process_event(&self->bootstrap_channel, FD_WRITE);
                        if (error_code) {
                            KAA_LOG_ERROR(self->kaa_context->logger,
                                        error_code,
                                        "IO LOOP: Failed Write Event Bootstrap(%d)", bootstrap_fd);
                        }
                    }
                    if (fdset)
                        r--;
                }
                if (r > 0) {
                    fdset = false;
                    if (SNDC_FD_ISSET(bootstrap_fd, &x_set)) {
                        fdset = true;
                        sndc_printf("Exception Event Bootstrap %d\n", bootstrap_fd);
                        KAA_LOG_DEBUG(self->kaa_context->logger,
                                        KAA_ERR_NONE,
                                        "IO LOOP: Exception Event Bootstrap(%d)", bootstrap_fd);
                        error_code = kaa_tcp_channel_process_event(&self->bootstrap_channel, FD_EXCEPTION);
                        if (error_code) {
                            KAA_LOG_ERROR(self->kaa_context->logger,
                                        error_code,
                                        "IO LOOP: Failed Exception Event Bootstrap(%d)", bootstrap_fd);
                        }
                    }
                    if (fdset)
                        r--;
                }
            }
            if (r > 0 && ops_fd >= 0) {
                fdset = false;
                if (SNDC_FD_ISSET(ops_fd, &r_set)) {
                    fdset = true;
                    KAA_LOG_DEBUG(self->kaa_context->logger,
                                    KAA_ERR_NONE,
                                    "IO LOOP: Read Event Operations(%d)", ops_fd);
                    error_code = kaa_tcp_channel_process_event(&self->operations_channel, FD_READ);
                    if (error_code) {
                        KAA_LOG_ERROR(self->kaa_context->logger,
                                    error_code,
                                    "IO LOOP: Failed Read Event Operations(%d)", ops_fd);
                    }
                }
                if (fdset)
                    r--;
                if (r > 0) {
                    fdset = false;
                    if (SNDC_FD_ISSET(ops_fd, &w_set)) {
                        fdset = true;
                        KAA_LOG_DEBUG(self->kaa_context->logger,
                                        KAA_ERR_NONE,
                                        "IO LOOP: Write Event Operations(%d)", ops_fd);
                        error_code = kaa_tcp_channel_process_event(&self->operations_channel, FD_WRITE);
                        if (error_code) {
                            KAA_LOG_ERROR(self->kaa_context->logger,
                                        error_code,
                                        "IO LOOP: Failed Write Event Operations(%d)", ops_fd);
                        }
                    }
                }
                if (fdset)
                    r--;
                if (r > 0) {
                    fdset = false;
                    if (SNDC_FD_ISSET(ops_fd, &x_set)) {
                        fdset = true;
                        sndc_printf("Exception Event Operations %d\n", ops_fd);
                        KAA_LOG_DEBUG(self->kaa_context->logger,
                                        KAA_ERR_NONE,
                                        "IO LOOP: Exception Event Operations(%d)", ops_fd);
                        error_code = kaa_tcp_channel_process_event(&self->operations_channel, FD_EXCEPTION);
                        if (error_code) {
                            KAA_LOG_ERROR(self->kaa_context->logger,
                                        error_code,
                                        "IO LOOP: Failed Exception Event Operations(%d)", ops_fd);
                        }
                    }
                }
            }
        } else {
            KAA_LOG_ERROR(self->kaa_context->logger,
                        KAA_ERR_BAD_STATE,
                        "IO LOOP: Error %d returned from select()", r);
        }
    }

    KAA_LOG_INFO(self->kaa_context->logger,
                    KAA_ERR_NONE,
                    "IO LOOP: Finished.");
}
예제 #29
0
void NotificationTransport::onNotificationResponse(const NotificationSyncResponse& response)
{
    subscriptions_.clear();

    if (response.responseStatus == SyncResponseStatus::NO_DELTA) {
        acceptedUnicastNotificationIds_.clear();
    }

    clientStatus_->setNotificationSequenceNumber(response.appStateSeqNumber);

    DetailedTopicStates detailedStatesContainer = clientStatus_->getTopicStates();

    if (!response.availableTopics.is_null()) {
        const auto& topics = response.availableTopics.get_array();

        detailedStatesContainer.clear();

        for (const auto& topic : topics) {
            DetailedTopicState dts;

            dts.topicId = topic.id;
            dts.topicName = topic.name;
            dts.subscriptionType = topic.subscriptionType;
            dts.sequenceNumber = 0;

            auto insertResult = notificationSubscriptions_.insert(std::make_pair(topic.id, 0));
            if (!insertResult.second) {
                dts.sequenceNumber = notificationSubscriptions_[topic.id];
            }

            detailedStatesContainer[topic.id] = dts;
        }

        if (notificationProcessor_) {
            notificationProcessor_->topicsListUpdated(topics);
        }
    }

    if (!response.notifications.is_null()) {

        KAA_LOG_INFO(boost::format("Received notifications array: %1%") % LoggingUtils::NotificationToString(response.notifications));

        const auto& notifications = response.notifications.get_array();

        Notifications unicast = getUnicastNotifications(notifications);
        Notifications multicast = getMulticastNotifications(notifications);

        Notifications newNotifications;

        for (const auto& n : unicast) {
            const std::string& uid = n.uid.get_string();
            KAA_LOG_INFO(boost::format("Adding '%1%' to unicast accepted notifications") % uid);
            auto addResultPair = acceptedUnicastNotificationIds_.insert(uid);
            if (addResultPair.second) {
                newNotifications.push_back(n);
            } else {
                KAA_LOG_INFO(boost::format("Notification with uid [%1%] was already received") % uid);
            }
        }

        for (const auto& n : multicast) {
            KAA_LOG_DEBUG(boost::format("Notification: %1%, Stored sequence number: %2%")
                    % LoggingUtils::SingleNotificationToString(n)
                    % notificationSubscriptions_[n.topicId]);
            auto& sequenceNumber = notificationSubscriptions_[n.topicId];
            std::int32_t notificationSequenceNumber =
                        (n.seqNumber.is_null()) ? 0 : n.seqNumber.get_int();
            if (notificationSequenceNumber > sequenceNumber) {
                newNotifications.push_back(n);
                detailedStatesContainer[n.topicId].sequenceNumber = sequenceNumber = notificationSequenceNumber;
            }
        }

        if (notificationProcessor_) {
            notificationProcessor_->notificationReceived(newNotifications);
        }
    }

    clientStatus_->setTopicStates(detailedStatesContainer);
    if (response.responseStatus != SyncResponseStatus::NO_DELTA) {
        syncAck();
    }
}
예제 #30
0
void SyncDataProcessor::processResponse(const std::vector<std::uint8_t> &response)
{
    SyncResponse syncResponse = responseConverter_.fromByteArray(response.data(), response.size());
    KAA_LOG_INFO(boost::format("Got SyncResponse: requestId: %1%, result: %2%")
                 % syncResponse.requestId % LoggingUtils::SyncResponseResultTypeToString(syncResponse.status));

    KAA_LOG_DEBUG(boost::format("Got BootstrapSyncResponse: %1%")
                  % LoggingUtils::BootstrapSyncResponseToString(syncResponse.bootstrapSyncResponse));

    if (!syncResponse.bootstrapSyncResponse.is_null()) {
        if (bootstrapTransport_) {
            bootstrapTransport_->onBootstrapResponse(syncResponse.bootstrapSyncResponse.get_BootstrapSyncResponse());
        } else {
            KAA_LOG_ERROR("Got bootstrap sync response, but profile transport was not set!");
        }
    }

    KAA_LOG_DEBUG(boost::format("Got ProfileSyncResponse: %1%")
                  % LoggingUtils::ProfileSyncResponseToString(syncResponse.profileSyncResponse));

    if (!syncResponse.profileSyncResponse.is_null()) {
        if (profileTransport_) {
            profileTransport_->onProfileResponse(syncResponse.profileSyncResponse.get_ProfileSyncResponse());
        } else {
            KAA_LOG_ERROR("Got profile sync response, but profile transport was not set!");
        }
    } else if (syncResponse.status == SyncResponseResultType::PROFILE_RESYNC) {
        if (profileTransport_) {
            profileTransport_->onProfileResync();
        } else {
            KAA_LOG_ERROR("Got profile resync request, but profile transport was not set!");
        }
    }

    KAA_LOG_DEBUG(boost::format("Got ConfigurationSyncResponse: %1%")
                  % LoggingUtils::ConfigurationSyncResponseToString(syncResponse.configurationSyncResponse));

#ifdef KAA_USE_CONFIGURATION
    if (!syncResponse.configurationSyncResponse.is_null()) {
        if (configurationTransport_) {
            configurationTransport_->onConfigurationResponse(syncResponse.configurationSyncResponse.get_ConfigurationSyncResponse());
        } else {
            KAA_LOG_ERROR("Got configuration sync response, but configuration transport was not set!");
        }
    }
#endif

    KAA_LOG_DEBUG(boost::format("Got EventSyncResponse: %1%")
                  % LoggingUtils::EventSyncResponseToString(syncResponse.eventSyncResponse));

#ifdef KAA_USE_EVENTS
    if (eventTransport_) {
        eventTransport_->onSyncResponseId(syncResponse.requestId);
        if (!syncResponse.eventSyncResponse.is_null()) {
            eventTransport_->onEventResponse(syncResponse.eventSyncResponse.get_EventSyncResponse());
        }
    } else {
        KAA_LOG_ERROR("Event transport was not set!");
    }
#endif

    KAA_LOG_DEBUG(boost::format("Got NotificationSyncResponse: %1%")
                  % LoggingUtils::NotificationSyncResponseToString(syncResponse.notificationSyncResponse));

#ifdef KAA_USE_NOTIFICATIONS
    if (!syncResponse.notificationSyncResponse.is_null()) {
        if (notificationTransport_) {
            notificationTransport_->onNotificationResponse(syncResponse.notificationSyncResponse.get_NotificationSyncResponse());
        } else {
            KAA_LOG_ERROR("Got notification sync response, but notification transport was not set!");
        }
    }
#endif

    KAA_LOG_DEBUG(boost::format("Got UserSyncResponse: %1%")
                  % LoggingUtils::UserSyncResponseToString(syncResponse.userSyncResponse));

#ifdef KAA_USE_EVENTS
    if (!syncResponse.userSyncResponse.is_null()) {
        if (userTransport_) {
            userTransport_->onUserResponse(syncResponse.userSyncResponse.get_UserSyncResponse());
        } else {
            KAA_LOG_ERROR("Got user sync response, but user transport was not set!");
        }
    }
#endif

    KAA_LOG_DEBUG(boost::format("Got LogSyncResponse: %1%")
                  % LoggingUtils::LogSyncResponseToString(syncResponse.logSyncResponse));

#ifdef KAA_USE_LOGGING
    if (!syncResponse.logSyncResponse.is_null()) {
        if (loggingTransport_) {
            loggingTransport_->onLogSyncResponse(syncResponse.logSyncResponse.get_LogSyncResponse());
        } else {
            KAA_LOG_ERROR("Got log upload sync response, but logging transport was not set!");
        }
    }
#endif

    KAA_LOG_DEBUG(boost::format("Got RedirectSyncResponse: %1%")
                  % LoggingUtils::RedirectSyncResponseToString(syncResponse.redirectSyncResponse));

    if (!syncResponse.redirectSyncResponse.is_null()) {
        if (redirectionTransport_) {
            redirectionTransport_->onRedirectionResponse(syncResponse.redirectSyncResponse.get_RedirectSyncResponse());
        } else {
            KAA_LOG_ERROR("Got redirection sync response, but redirection transport was not set!");
        }
    }

    KAA_LOG_DEBUG("Processed SyncResponse");
    clientStatus_->save();
}