static void test_profile_force_sync(void) { kaa_error_t rc = kaa_profile_force_sync(profile_manager); ASSERT_EQUAL(KAA_ERR_NONE, rc); ASSERT_TRUE(mock_sync_handler_called); }
kaa_error_t kaa_profile_handle_server_sync(kaa_profile_manager_t *self , kaa_platform_message_reader_t *reader , uint16_t extension_options , size_t extension_length) { // Only used for logging (void)extension_options; (void)extension_length; KAA_RETURN_IF_NIL2(self, reader, KAA_ERR_BADPARAM); KAA_LOG_INFO(self->logger, KAA_ERR_NONE, "Received profile server sync: options %u, payload size %zu", extension_options, extension_length); kaa_error_t error_code = KAA_ERR_NONE; self->need_resync = false; if (extension_options & KAA_PROFILE_RESYNC_OPTION) { self->need_resync = true; KAA_LOG_INFO(self->logger, KAA_ERR_NONE, "Going to resync profile..."); /* Ignoring an error code: the channels can be not initialized */ (void)kaa_profile_force_sync(self); } if (!self->status->is_registered) { KAA_LOG_INFO(self->logger, KAA_ERR_NONE, "Endpoint has been registered"); self->status->is_registered = true; } return error_code; }
kaa_error_t kaa_profile_manager_update_profile(kaa_profile_manager_t *self, kaa_profile_t *profile_body) { #if KAA_PROFILE_SCHEMA_VERSION > 0 KAA_RETURN_IF_NIL2(self, profile_body, KAA_ERR_BADPARAM); size_t serialized_profile_size = profile_body->get_size(profile_body); if (!serialized_profile_size) { KAA_LOG_ERROR(self->logger, KAA_ERR_BADDATA, "Failed to update profile: serialize profile size is null. Maybe profile schema is empty"); return KAA_ERR_BADDATA; } char *serialized_profile = (char *) KAA_MALLOC(serialized_profile_size * sizeof(char)); KAA_RETURN_IF_NIL(serialized_profile, KAA_ERR_NOMEM); avro_writer_t writer = avro_writer_memory(serialized_profile, serialized_profile_size); if (!writer) { KAA_FREE(serialized_profile); return KAA_ERR_NOMEM; } profile_body->serialize(writer, profile_body); avro_writer_free(writer); kaa_digest new_hash; ext_calculate_sha_hash(serialized_profile, serialized_profile_size, new_hash); if (!memcmp(new_hash, self->status->profile_hash, SHA_1_DIGEST_LENGTH)) { self->need_resync = false; KAA_FREE(serialized_profile); return KAA_ERR_NONE; } KAA_LOG_INFO(self->logger, KAA_ERR_NONE, "Endpoint profile is updated"); if (ext_copy_sha_hash(self->status->profile_hash, new_hash)) { KAA_FREE(serialized_profile); return KAA_ERR_BAD_STATE; } if (self->profile_body.size > 0) { KAA_FREE(self->profile_body.buffer); self->profile_body.buffer = NULL; } self->profile_body.buffer = (uint8_t*)serialized_profile; self->profile_body.size = serialized_profile_size; self->need_resync = true; /* Ignoring an error code: the channels can be not initialized */ (void)kaa_profile_force_sync(self); #endif return KAA_ERR_NONE; }
kaa_error_t kaa_profile_manager_set_endpoint_access_token(kaa_profile_manager_t *self, const char *token) { KAA_RETURN_IF_NIL2(self, token, KAA_ERR_BADPARAM); kaa_error_t error = kaa_status_set_endpoint_access_token(self->status, token); if (error == KAA_ERR_NONE) { self->need_resync = true; /* Ignoring an error code: the channels can be not initialized */ (void)kaa_profile_force_sync(self); } return error; }
kaa_error_t kaa_platform_protocol_process_server_sync(kaa_platform_protocol_t *self, const uint8_t *buffer, size_t buffer_size) { if (!self || !buffer || buffer_size == 0) { return KAA_ERR_BADPARAM; } KAA_LOG_INFO(self->logger, KAA_ERR_NONE, "Server sync received: payload size '%zu'", buffer_size); kaa_platform_message_reader_t reader = KAA_MESSAGE_READER(buffer, buffer_size); uint32_t protocol_id = 0; uint16_t protocol_version = 0; uint16_t extension_count = 0; kaa_error_t error_code = kaa_platform_message_header_read(&reader, &protocol_id, &protocol_version, &extension_count); if (error_code) { goto fail; } if (protocol_id != KAA_PLATFORM_PROTOCOL_ID) { KAA_LOG_ERROR(self->logger, KAA_ERR_BAD_PROTOCOL_ID, "Unsupported protocol ID %x", protocol_id); error_code = KAA_ERR_BAD_PROTOCOL_ID; goto fail; } if (protocol_version != KAA_PLATFORM_PROTOCOL_VERSION) { KAA_LOG_ERROR(self->logger, KAA_ERR_BAD_PROTOCOL_VERSION, "Unsupported protocol version %u", protocol_version); error_code = KAA_ERR_BAD_PROTOCOL_VERSION; goto fail; } uint32_t request_id = 0; while (kaa_platform_message_is_buffer_large_enough(&reader, KAA_PROTOCOL_MESSAGE_HEADER_SIZE)) { uint16_t extension_type; uint16_t extension_options; uint32_t extension_length; error_code = kaa_platform_message_read_extension_header(&reader, &extension_type, &extension_options, &extension_length); if (error_code) { KAA_LOG_ERROR(self->logger, error_code, "Failed to read extension header"); goto fail; } /* Do not resync unless it is requested by the metadata extension */ // TODO: must profile_needs_resync be set inside of the loop? self->status->profile_needs_resync = false; if (extension_type == KAA_EXTENSION_META_DATA) { error_code = kaa_platform_message_read(&reader, &request_id, sizeof(request_id)); if (error_code) { KAA_LOG_ERROR(self->logger, error_code, "Failed to read meta data (request_id)"); goto fail; } request_id = KAA_NTOHL(request_id); KAA_LOG_TRACE(self->logger, KAA_ERR_NONE, "Server sync request id %u", request_id); /* Check if managers needs resync */ uint32_t resync_request; error_code = kaa_platform_message_read(&reader, &resync_request, sizeof(resync_request)); if (error_code) { KAA_LOG_ERROR(self->logger, error_code, "Failed to read meta data (resync_request)"); goto fail; } resync_request = KAA_NTOHL(resync_request); KAA_LOG_TRACE(self->logger, KAA_ERR_NONE, "Server resync request %u", resync_request); if (resync_request & KAA_PROFILE_RESYNC_FLAG) { KAA_LOG_INFO(self->logger, KAA_ERR_NONE, "Profile resync is requested"); self->status->profile_needs_resync = true; #ifndef KAA_DISABLE_FEATURE_PROFILE void *profile_ctx = kaa_extension_get_context(KAA_EXTENSION_PROFILE); if (!profile_ctx) { error_code = KAA_ERR_NOT_FOUND; KAA_LOG_ERROR(self->logger, error_code, "Profile extension is not found. Force resync can't be done"); goto fail; } error_code = kaa_profile_force_sync(profile_ctx); if (error_code) { KAA_LOG_ERROR(self->logger, error_code, "Failed to force-sync profile"); goto fail; } #endif } } else { error_code = kaa_extension_server_sync(extension_type, request_id, extension_options, reader.current, extension_length); reader.current += extension_length; if (error_code == KAA_ERR_NOT_FOUND) { KAA_LOG_WARN(self->logger, KAA_ERR_UNSUPPORTED, "Unsupported extension received (type = %u)", extension_type); error_code = KAA_ERR_NONE; } else if (error_code) { KAA_LOG_ERROR(self->logger, error_code, "Server sync is corrupted. Failed to read extension with type %u", extension_type); goto fail; } } } error_code = kaa_status_save(self->status); if (error_code) { KAA_LOG_ERROR(self->logger, error_code, "Failed to save status"); goto fail; } KAA_LOG_TRACE(self->logger, KAA_ERR_NONE, "Server sync successfully processed"); fail: return error_code; }
kaa_error_t kaa_platform_protocol_process_server_sync(kaa_platform_protocol_t *self , const char *buffer , size_t buffer_size) { KAA_RETURN_IF_NIL3(self, buffer, buffer_size, KAA_ERR_BADPARAM); KAA_LOG_INFO(self->logger, KAA_ERR_NONE, "Server sync received: payload size '%zu'", buffer_size); kaa_platform_message_reader_t *reader = NULL; kaa_error_t error_code = kaa_platform_message_reader_create(&reader, buffer, buffer_size); KAA_RETURN_IF_ERR(error_code); uint32_t protocol_id = 0; uint16_t protocol_version = 0; uint16_t extension_count = 0; error_code = kaa_platform_message_header_read(reader, &protocol_id, &protocol_version, &extension_count); KAA_RETURN_IF_ERR(error_code); if (protocol_id != KAA_PLATFORM_PROTOCOL_ID) { KAA_LOG_ERROR(self->logger, KAA_ERR_BAD_PROTOCOL_ID, "Unsupported protocol ID %x", protocol_id); return KAA_ERR_BAD_PROTOCOL_ID; } if (protocol_version != KAA_PLATFORM_PROTOCOL_VERSION) { KAA_LOG_ERROR(self->logger, KAA_ERR_BAD_PROTOCOL_VERSION, "Unsupported protocol version %u", protocol_version); return KAA_ERR_BAD_PROTOCOL_VERSION; } uint32_t request_id = 0; uint16_t extension_type = 0; uint16_t extension_options = 0; uint32_t extension_length = 0; while (!error_code && kaa_platform_message_is_buffer_large_enough(reader, KAA_PROTOCOL_MESSAGE_HEADER_SIZE)) { error_code = kaa_platform_message_read_extension_header(reader , &extension_type , &extension_options , &extension_length); KAA_RETURN_IF_ERR(error_code); /* Do not resync unless it is requested by the metadata extension */ self->status->profile_needs_resync = false; switch (extension_type) { case KAA_BOOTSTRAP_EXTENSION_TYPE: { error_code = kaa_bootstrap_manager_handle_server_sync(self->kaa_context->bootstrap_manager , reader , extension_options , extension_length); break; } case KAA_META_DATA_EXTENSION_TYPE: { error_code = kaa_platform_message_read(reader, &request_id, sizeof(request_id)); if (error_code) { break; } request_id = KAA_NTOHL(request_id); KAA_LOG_TRACE(self->logger, KAA_ERR_NONE, "Server sync request id %u", request_id); /* Check if managers needs resync */ uint32_t resync_request; error_code = kaa_platform_message_read(reader, &resync_request, sizeof(resync_request)); if (error_code) { break; } resync_request = KAA_NTOHL(resync_request); KAA_LOG_TRACE(self->logger, KAA_ERR_NONE, "Server resync request %u", resync_request); if (resync_request & KAA_PROFILE_RESYNC_FLAG) { KAA_LOG_INFO(self->logger, KAA_ERR_NONE, "Profile resync is requested"); self->status->profile_needs_resync = true; error_code = kaa_profile_force_sync(self->kaa_context->profile_manager); } break; } case KAA_PROFILE_EXTENSION_TYPE: { error_code = kaa_profile_handle_server_sync(self->kaa_context->profile_manager , reader , extension_options , extension_length); break; } case KAA_USER_EXTENSION_TYPE: { error_code = kaa_user_handle_server_sync(self->kaa_context->user_manager , reader , extension_options , extension_length); break; } #ifndef KAA_DISABLE_FEATURE_LOGGING case KAA_LOGGING_EXTENSION_TYPE: { error_code = kaa_logging_handle_server_sync(self->kaa_context->log_collector , reader , extension_options , extension_length); break; } #endif #ifndef KAA_DISABLE_FEATURE_EVENTS case KAA_EVENT_EXTENSION_TYPE: { error_code = kaa_event_handle_server_sync(self->kaa_context->event_manager , reader , extension_options , extension_length , request_id); break; } #endif #ifndef KAA_DISABLE_FEATURE_CONFIGURATION case KAA_CONFIGURATION_EXTENSION_TYPE: { error_code = kaa_configuration_manager_handle_server_sync(self->kaa_context->configuration_manager , reader , extension_options , extension_length); break; } #endif #ifndef KAA_DISABLE_FEATURE_NOTIFICATION case KAA_NOTIFICATION_EXTENSION_TYPE: { error_code = kaa_notification_manager_handle_server_sync(self->kaa_context->notification_manager , reader , extension_length); break; } #endif default: KAA_LOG_WARN(self->logger, KAA_ERR_UNSUPPORTED, "Unsupported extension received (type = %u)", extension_type); break; } } kaa_platform_message_reader_destroy(reader); if (!error_code) { error_code = kaa_status_save(self->status); KAA_LOG_TRACE(self->logger, KAA_ERR_NONE, "Server sync successfully processed"); } else { KAA_LOG_ERROR(self->logger, error_code, "Server sync is corrupted. Failed to read extension with type %u", extension_type); } return error_code; }