void test_create_request(void) { KAA_TRACE_IN(logger); size_t expected_size = 0; ASSERT_EQUAL(kaa_configuration_manager_get_size(config_manager, &expected_size), KAA_ERR_NONE); ASSERT_EQUAL(expected_size, sizeof(uint32_t) + KAA_EXTENSION_HEADER_SIZE + SHA_1_DIGEST_LENGTH); char request_buffer[expected_size]; kaa_platform_message_writer_t *writer = NULL; ASSERT_EQUAL(kaa_platform_message_writer_create(&writer, request_buffer, expected_size), KAA_ERR_NONE); ASSERT_EQUAL(kaa_configuration_manager_request_serialize(config_manager, writer), KAA_ERR_NONE); char *cursor = writer->begin; ASSERT_EQUAL(*cursor, KAA_CONFIGURATION_EXTENSION_TYPE); cursor += sizeof(uint32_t); ASSERT_EQUAL(KAA_NTOHL(*((uint32_t *) cursor)), sizeof(uint32_t) + SHA_1_DIGEST_LENGTH); // checking payload size cursor += sizeof(uint32_t); ASSERT_EQUAL(KAA_NTOHL(*((uint32_t *) cursor)), CONFIG_START_SEQ_N); // checking sequence number cursor += sizeof(uint32_t); kaa_digest check_hash; ext_calculate_sha_hash(KAA_CONFIGURATION_DATA, KAA_CONFIGURATION_DATA_LENGTH, check_hash); // checking configuration hash ASSERT_EQUAL(memcmp(cursor, check_hash, SHA_1_DIGEST_LENGTH), 0); cursor += SHA_1_DIGEST_LENGTH; ASSERT_EQUAL(cursor, writer->end); kaa_platform_message_writer_destroy(writer); }
kaa_error_t kaa_configuration_manager_handle_server_sync(kaa_configuration_manager_t *self , kaa_platform_message_reader_t *reader , uint32_t extension_options , size_t extension_length) { KAA_RETURN_IF_NIL2(self, reader, KAA_ERR_BADPARAM); KAA_LOG_INFO(self->logger, KAA_ERR_NONE, "Received configuration server sync: options %u, payload size %u", extension_options, extension_length); if (extension_length >= sizeof(uint32_t)) { self->status->config_seq_n = KAA_NTOHL(*((uint32_t *) reader->current)); KAA_LOG_TRACE(self->logger, KAA_ERR_NONE, "Configuration state sequence number is '%d'", self->status->config_seq_n); reader->current += sizeof(uint32_t); if (extension_options & KAA_CONFIGURATION_BODY_PRESENT) { uint32_t body_size = KAA_NTOHL(*((uint32_t *) reader->current)); reader->current += sizeof(uint32_t); KAA_LOG_INFO(self->logger, KAA_ERR_NONE, "Received configuration body, size '%u' ", body_size); const char* body = reader->current; kaa_error_t error = kaa_platform_message_skip(reader, kaa_aligned_size_get(body_size)); if (error) { KAA_LOG_ERROR(self->logger, error, "Failed to read configuration body, size %u", body_size); return error; } #if KAA_CONFIGURATION_DELTA_SUPPORT #else if (self->root_record) self->root_record->destroy(self->root_record); self->root_record = kaa_configuration_manager_deserialize(body, body_size); if (!self->root_record) { KAA_LOG_ERROR(self->logger, KAA_ERR_READ_FAILED, "Failed to deserialize configuration body, size %u", body_size); return KAA_ERR_READ_FAILED; } kaa_error_t err = ext_calculate_sha_hash(body, body_size, self->configuration_hash); if (err) { KAA_LOG_WARN(self->logger, err, "Failed to calculate configuration body hash"); return err; } ext_configuration_store(body, body_size); #endif if (self->root_receiver.on_configuration_updated) self->root_receiver.on_configuration_updated(self->root_receiver.context, self->root_record); kaa_transport_channel_interface_t *channel = kaa_channel_manager_get_transport_channel(self->channel_manager, configuration_sync_services[0]); if (channel) channel->sync_handler(channel->context, configuration_sync_services, 1); } } return KAA_ERR_NONE; }
void test_create_request(void **state) { (void)state; size_t expected_size = 0; ASSERT_EQUAL(kaa_configuration_manager_get_size(config_manager, &expected_size), KAA_ERR_NONE); ASSERT_EQUAL(expected_size, KAA_EXTENSION_HEADER_SIZE + SHA_1_DIGEST_LENGTH); uint8_t request_buffer[expected_size]; kaa_platform_message_writer_t *writer = NULL; ASSERT_EQUAL(kaa_platform_message_writer_create(&writer, request_buffer, expected_size), KAA_ERR_NONE); ASSERT_EQUAL(kaa_configuration_manager_request_serialize(config_manager, writer), KAA_ERR_NONE); uint8_t *cursor = writer->begin; ASSERT_EQUAL(KAA_HTONS(*((uint16_t *) cursor)), KAA_EXTENSION_CONFIGURATION); cursor += sizeof(uint32_t); ASSERT_EQUAL(KAA_NTOHL(*((uint32_t *) cursor)), SHA_1_DIGEST_LENGTH); // checking payload size cursor += sizeof(uint32_t); kaa_digest check_hash; ext_calculate_sha_hash(KAA_CONFIGURATION_DATA, KAA_CONFIGURATION_DATA_LENGTH, check_hash); // checking configuration hash ASSERT_EQUAL(memcmp(cursor, check_hash, SHA_1_DIGEST_LENGTH), 0); cursor += SHA_1_DIGEST_LENGTH; ASSERT_EQUAL(cursor, writer->end); kaa_platform_message_writer_destroy(writer); }
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_TRACE(self->logger, KAA_ERR_NONE, "Processing server sync..."); 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; uint8_t extension_type = 0; uint32_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); 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(uint32_t)); request_id = KAA_NTOHL(request_id); 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; }
void test_meta_extension_serialize(void) { KAA_TRACE_IN(logger); size_t meta_extension_size; kaa_error_t error_code = kaa_meta_data_request_get_size(&meta_extension_size); char buffer[meta_extension_size]; kaa_platform_message_writer_t *writer; error_code = kaa_platform_message_writer_create(&writer, buffer, meta_extension_size); ASSERT_EQUAL(error_code, KAA_ERR_NONE); uint32_t expected_timeout = KAA_SYNC_TIMEOUT; kaa_digest expected_public_key_hash = {0x74, 0xc7, 0x51, 0x43, 0x00, 0xf7, 0xb8, 0x21, 0x2c, 0xc3, 0x6b, 0xa5, 0x9c, 0xb4, 0x03, 0xef, 0xc2, 0x5c, 0x65, 0x6c}; kaa_digest expected_profile_hash = {0xfa, 0x71, 0xb5, 0x02, 0xe7, 0xdf, 0x96, 0x86, 0x6c, 0xdc, 0xe1, 0x4a, 0x17, 0x35, 0x7f, 0xd9, 0xa8, 0xfb, 0x71, 0x09}; error_code = ext_copy_sha_hash(status->endpoint_public_key_hash, expected_public_key_hash); ASSERT_EQUAL(error_code, KAA_ERR_NONE); error_code = ext_copy_sha_hash(status->profile_hash, expected_profile_hash); ASSERT_EQUAL(error_code, KAA_ERR_NONE); kaa_context_t *context = NULL; kaa_init(&context); kaa_platform_protocol_t *protocol = NULL; kaa_platform_protocol_create(&protocol, context, status); error_code = kaa_meta_data_request_serialize(protocol, writer, 1); ASSERT_EQUAL(error_code, KAA_ERR_NONE); kaa_deinit(context); kaa_platform_message_reader_t *reader; error_code = kaa_platform_message_reader_create(&reader, buffer, meta_extension_size); ASSERT_EQUAL(error_code, KAA_ERR_NONE); uint8_t extension_type; uint32_t extension_options; uint32_t extension_payload; error_code = kaa_platform_message_read_extension_header( reader, &extension_type, &extension_options, &extension_payload); ASSERT_EQUAL(error_code, KAA_ERR_NONE); ASSERT_EQUAL(extension_type, KAA_META_DATA_EXTENSION_TYPE); ASSERT_EQUAL(extension_options, (TIMEOUT_VALUE | PUBLIC_KEY_HASH_VALUE | PROFILE_HASH_VALUE | APP_TOKEN_VALUE)); ASSERT_EQUAL(extension_payload, meta_extension_size - KAA_EXTENSION_HEADER_SIZE); uint32_t request_id; uint32_t timeout; kaa_digest public_key_hash; kaa_digest profile_hash; char sdk_token[KAA_SDK_TOKEN_LENGTH]; error_code = kaa_platform_message_read(reader, &request_id, sizeof(uint32_t)); ASSERT_EQUAL(error_code, KAA_ERR_NONE); ASSERT_EQUAL(KAA_NTOHL(request_id), 1); error_code = kaa_platform_message_read(reader, &timeout, sizeof(uint32_t)); ASSERT_EQUAL(error_code, KAA_ERR_NONE); timeout = KAA_NTOHL(timeout); ASSERT_EQUAL(expected_timeout, timeout); error_code = kaa_platform_message_read_aligned(reader, public_key_hash, SHA_1_DIGEST_LENGTH); ASSERT_EQUAL(error_code, KAA_ERR_NONE); error_code = (memcmp(public_key_hash, expected_public_key_hash, SHA_1_DIGEST_LENGTH) == 0 ? KAA_ERR_NONE : KAA_ERR_READ_FAILED); ASSERT_EQUAL(error_code, KAA_ERR_NONE); error_code = kaa_platform_message_read_aligned(reader, profile_hash, SHA_1_DIGEST_LENGTH); ASSERT_EQUAL(error_code, KAA_ERR_NONE); error_code = (memcmp(profile_hash, expected_profile_hash, SHA_1_DIGEST_LENGTH) == 0 ? KAA_ERR_NONE : KAA_ERR_READ_FAILED); ASSERT_EQUAL(error_code, KAA_ERR_NONE); error_code = kaa_platform_message_read_aligned(reader, sdk_token, KAA_SDK_TOKEN_LENGTH); ASSERT_EQUAL(error_code, KAA_ERR_NONE); error_code = (memcmp(sdk_token, KAA_SDK_TOKEN, KAA_SDK_TOKEN_LENGTH) == 0 ? KAA_ERR_NONE : KAA_ERR_READ_FAILED); ASSERT_EQUAL(error_code, KAA_ERR_NONE); kaa_platform_message_reader_destroy(reader); kaa_platform_message_writer_destroy(writer); }
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; }