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; } }
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; } }
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(); } }
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; }
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(); } }
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); }
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); } } }
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()); } } } }
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)); }
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); }
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); }
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)); }
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); }
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()); } }
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(); } }
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); } } }
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(); } }
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; }
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; } }
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(); }
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; } }
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())); } } }
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; }
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; }
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; }
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; }
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()); } } }
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."); }
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(); } }
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(); }