From 947608fbab0ad322d77976d0cad762d1106d5144 Mon Sep 17 00:00:00 2001 From: Wenhui Xie <54433186+wenhui-xie@users.noreply.github.com> Date: Wed, 13 Dec 2023 09:34:06 +0800 Subject: [PATCH] Add Azure IoT test. (#217) --- .github/workflows/regression_test.yml | 47 +- scripts/build_azure_iot.sh | 3 + scripts/install.sh | 2 + scripts/test_azure_iot.sh | 3 + test/cmake/azure_iot/CMakeLists.txt | 111 + .../azure_iot/configs/azure_rtos_src.cmake | 47 + .../azure_iot/configs/azure_rtos_tests.cmake | 351 +++ test/cmake/azure_iot/configs/linux.cmake | 31 + test/cmake/azure_iot/configs/win32.cmake | 15 + test/cmake/azure_iot/coverage.sh | 8 + test/cmake/azure_iot/run.sh | 115 + test/regression/azure_iot/api_unit_test.c | 589 +++++ .../azure_iot/c2d_property_unit_test.c | 357 +++ test/regression/azure_iot/c2d_unit_test.c | 584 +++++ .../azure_iot/connection_non_block_ram_test.c | 499 +++++ .../connection_sas_expiry_ram_test.c | 512 +++++ .../azure_iot/connection_unit_test.c | 244 ++ test/regression/azure_iot/d2c_unit_test.c | 368 +++ .../azure_iot/device_cert_unit_test.c | 210 ++ .../azure_iot/device_twin_unit_test.c | 1127 ++++++++++ .../azure_iot/direct_method_unit_test.c | 694 ++++++ .../azure_iot/initialization_unit_test.c | 362 +++ .../iot_provisioning_client_unit_test.c | 1965 +++++++++++++++++ test/regression/azure_iot/main.c | 382 ++++ .../nx_azure_iot_adu_agent_unit_test.c | 1806 +++++++++++++++ .../nx_azure_iot_json_reader_unit_test.c | 467 ++++ .../nx_azure_iot_json_writer_unit_test.c | 455 ++++ ...x_azure_iot_pnp_client_command_unit_test.c | 856 +++++++ ...zure_iot_pnp_client_properties_unit_test.c | 1777 +++++++++++++++ ...azure_iot_pnp_client_telemetry_unit_test.c | 993 +++++++++ .../azure_iot/nx_azure_iot_unit_test.c | 298 +++ .../azure_iot/trusted_cert_unit_test.c | 170 ++ .../azure_iot/user_agent_string_unit_test.c | 308 +++ 33 files changed, 15752 insertions(+), 4 deletions(-) create mode 100755 scripts/build_azure_iot.sh create mode 100755 scripts/test_azure_iot.sh create mode 100644 test/cmake/azure_iot/CMakeLists.txt create mode 100644 test/cmake/azure_iot/configs/azure_rtos_src.cmake create mode 100644 test/cmake/azure_iot/configs/azure_rtos_tests.cmake create mode 100644 test/cmake/azure_iot/configs/linux.cmake create mode 100644 test/cmake/azure_iot/configs/win32.cmake create mode 100755 test/cmake/azure_iot/coverage.sh create mode 100755 test/cmake/azure_iot/run.sh create mode 100644 test/regression/azure_iot/api_unit_test.c create mode 100644 test/regression/azure_iot/c2d_property_unit_test.c create mode 100644 test/regression/azure_iot/c2d_unit_test.c create mode 100644 test/regression/azure_iot/connection_non_block_ram_test.c create mode 100644 test/regression/azure_iot/connection_sas_expiry_ram_test.c create mode 100644 test/regression/azure_iot/connection_unit_test.c create mode 100644 test/regression/azure_iot/d2c_unit_test.c create mode 100644 test/regression/azure_iot/device_cert_unit_test.c create mode 100644 test/regression/azure_iot/device_twin_unit_test.c create mode 100644 test/regression/azure_iot/direct_method_unit_test.c create mode 100644 test/regression/azure_iot/initialization_unit_test.c create mode 100644 test/regression/azure_iot/iot_provisioning_client_unit_test.c create mode 100644 test/regression/azure_iot/main.c create mode 100644 test/regression/azure_iot/nx_azure_iot_adu_agent_unit_test.c create mode 100644 test/regression/azure_iot/nx_azure_iot_json_reader_unit_test.c create mode 100644 test/regression/azure_iot/nx_azure_iot_json_writer_unit_test.c create mode 100644 test/regression/azure_iot/nx_azure_iot_pnp_client_command_unit_test.c create mode 100644 test/regression/azure_iot/nx_azure_iot_pnp_client_properties_unit_test.c create mode 100644 test/regression/azure_iot/nx_azure_iot_pnp_client_telemetry_unit_test.c create mode 100644 test/regression/azure_iot/nx_azure_iot_unit_test.c create mode 100644 test/regression/azure_iot/trusted_cert_unit_test.c create mode 100644 test/regression/azure_iot/user_agent_string_unit_test.c diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml index affb6f61..1ad2e8be 100644 --- a/.github/workflows/regression_test.yml +++ b/.github/workflows/regression_test.yml @@ -73,7 +73,7 @@ jobs: cmake_path: ./test/cmake/netxduo64 result_affix: NetXDuo64 skip_deploy: true - NetXDuo_fast: + NetXDuo_Fast: permissions: contents: read issues: read @@ -86,9 +86,48 @@ jobs: build_script: ./scripts/build_nxd_fast.sh test_script: ./scripts/test_nxd_fast.sh cmake_path: ./test/cmake/netxduo_fast - result_affix: NetXDuo_fast + result_affix: NetXDuo_Fast skip_deploy: true skip_coverage: true + Azure_IoT: + permissions: + contents: read + issues: read + checks: write + pull-requests: write + pages: write + id-token: write + uses: azure-rtos/threadx/.github/workflows/regression_template.yml@master + with: + build_script: ./scripts/build_azure_iot.sh + test_script: ./scripts/test_azure_iot.sh + cmake_path: ./test/cmake/azure_iot + result_affix: Azure_IoT + skip_deploy: true + Azure_IoT_Windows: + permissions: + contents: read + issues: read + checks: write + pull-requests: write + runs-on: windows-2019 + steps: + - name: Check out the repository + uses: actions/checkout@v4 + with: + submodules: true + - name: Checkout submodules + run: | + if (!(Test-Path ./test/cmake/threadx)) {git clone https://github.com/azure-rtos/threadx.git ./test/cmake/threadx --depth 1} + - name: CMake + run: | + mkdir build + cd build + cmake ../test/cmake/azure_iot -A Win32 + - name: Build + run: | + cd build + cmake --build . Deploy: permissions: contents: read @@ -97,8 +136,8 @@ jobs: pull-requests: write pages: write id-token: write - needs: [NetXDuo, Web, MQTT, NetXDuo64, NetXDuo_fast] + needs: [NetXDuo, Web, MQTT, NetXDuo64, NetXDuo_Fast, Azure_IoT] uses: azure-rtos/threadx/.github/workflows/regression_template.yml@master with: skip_test: true - deploy_list: "NetXDuo Web MQTT NetXDuo64 NetXDuo_fast" \ No newline at end of file + deploy_list: "NetXDuo Web MQTT NetXDuo64 NetXDuo_Fast Azure_IoT" \ No newline at end of file diff --git a/scripts/build_azure_iot.sh b/scripts/build_azure_iot.sh new file mode 100755 index 00000000..3b7bec71 --- /dev/null +++ b/scripts/build_azure_iot.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +$(dirname `realpath $0`)/../test/cmake/azure_iot/run.sh build all \ No newline at end of file diff --git a/scripts/install.sh b/scripts/install.sh index 25da84ce..dd55b3e4 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -20,6 +20,8 @@ sudo apt-get install -y \ dos2unix \ gawk \ libssl-dev:i386 \ + libcmocka-dev:i386 \ + gcc-arm-none-eabi \ software-properties-common wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add - diff --git a/scripts/test_azure_iot.sh b/scripts/test_azure_iot.sh new file mode 100755 index 00000000..33acf55a --- /dev/null +++ b/scripts/test_azure_iot.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +CTEST_PARALLEL_LEVEL=4 $(dirname `realpath $0`)/../test/cmake/azure_iot/run.sh test all diff --git a/test/cmake/azure_iot/CMakeLists.txt b/test/cmake/azure_iot/CMakeLists.txt new file mode 100644 index 00000000..faa5de87 --- /dev/null +++ b/test/cmake/azure_iot/CMakeLists.txt @@ -0,0 +1,111 @@ +cmake_minimum_required(VERSION 3.13 FATAL_ERROR) + +if(NOT DEFINED THREADX_ARCH) + if(WIN32) + set(CMAKE_TOOLCHAIN_FILE + "configs/win32.cmake" + CACHE STRING "") + elseif(UNIX) + set(CMAKE_TOOLCHAIN_FILE + "configs/linux.cmake" + CACHE STRING "") + else() + message(FATAL_ERROR "Error: Architecture not supported") + endif() +endif() + +# Project +project(AzureIoTMiddleware LANGUAGES C ASM) + +# Set build configurations +if(NOT WIN32) +set(BUILD_CONFIGURATIONS + default_build_coverage disable_precondition_build disable_security_module_build) +set(CMAKE_CONFIGURATION_TYPES + ${BUILD_CONFIGURATIONS} + CACHE STRING "list of supported configuration types" FORCE) +set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + ${CMAKE_CONFIGURATION_TYPES}) +list(GET CMAKE_CONFIGURATION_TYPES 0 BUILD_TYPE) +if((NOT CMAKE_BUILD_TYPE) OR (NOT ("${CMAKE_BUILD_TYPE}" IN_LIST + CMAKE_CONFIGURATION_TYPES))) + set(CMAKE_BUILD_TYPE + "${BUILD_TYPE}" + CACHE STRING "Build Type of the project" FORCE) +endif() +endif() + +message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") +message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.") + +set(default_build_coverage) +set(disable_precondition_build -DAZ_NO_PRECONDITION_CHECKING -DAZ_NO_LOGGING -DNX_DISABLE_IPV6) +set(disable_security_module_build -DNX_AZURE_DISABLE_IOT_SECURITY_MODULE) + +# Set property for folder +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +set(DISABLE_TEST + OFF + CACHE BOOL "Disable test projects (default is OFF)") +set(NX_AZURE_DISABLE_IOT_SECURITY_MODULE + OFF + CACHE BOOL "Disable Azure IoT Security Module (default is OFF)") + +if(NOT WIN32) +if("-DNX_AZURE_DISABLE_IOT_SECURITY_MODULE" IN_LIST ${CMAKE_BUILD_TYPE}) + set(NX_AZURE_DISABLE_IOT_SECURITY_MODULE ON) +endif() +endif() + +# CFLAGS +if(WIN32) + set(ADDITIONAL_C_FLAGS $ENV{CFLAGS} "/MP -DWIN32 -D_CRT_SECURE_NO_WARNINGS") +else() + if(THREADX_ARCH STREQUAL "linux") + set(ADDITIONAL_C_FLAGS + "$ENV{CFLAGS} -O0 -g3 -ggdb -m32 -gdwarf-2 -fdiagnostics-color -fprofile-arcs -ftest-coverage -Wno-error=misleading-indentation") + endif() + set(ADDITIONAL_C_FLAGS_AZURE_SERVICES + "-std=c99 -Werror -Wall -Wextra -pedantic -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -Wunused -Wuninitialized -Wmissing-declarations -Wconversion -Wpointer-arith -Wshadow -Wlogical-op -Wfloat-equal -fprofile-arcs -ftest-coverage -Wjump-misses-init -Wno-error=misleading-indentation" + ) +endif() + +# Add definitions +add_definitions( + ${ADDITIONAL_C_FLAGS} + ${DRIVER_FLAG} + -DNX_PCAP_SOURCE_NAME=\"${PCAP_NAME}\" + -DNX_ENABLE_EXTENDED_NOTIFY_SUPPORT + -DNX_SECURE_ENABLE + -DNX_DNS_CLIENT_USER_CREATE_PACKET_POOL + -DNX_DNS_CLIENT_CLEAR_QUEUE + -DNXD_MQTT_CLOUD_ENABLE + -DNX_SNTP_CLIENT_MAX_ROOT_DISPERSION=0 + -DNX_SNTP_CLIENT_MIN_SERVER_STRATUM=3 + -DNX_ENABLE_IP_PACKET_FILTER + -DNX_SECURE_TLS_DISABLE_TLS_1_1 + -DNXD_MQTT_PING_TIMEOUT_DELAY=500 + -DNXD_MQTT_SOCKET_TIMEOUT=0 + -DNXD_MQTT_OVER_WEBSOCKET + -DNX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT=1 + ${${CMAKE_BUILD_TYPE}}) + +# Include azure rtos cmake +include(configs/azure_rtos_src.cmake) + +if(NX_AZURE_DISABLE_IOT_SECURITY_MODULE) + add_definitions( + -DNX_AZURE_DISABLE_IOT_SECURITY_MODULE + ) +endif() + +# Link libraries +if(THREADX_ARCH STREQUAL "linux") + add_link_options(-m32 -fprofile-arcs -ftest-coverage) +endif() + +if((NOT DISABLE_TEST) AND UNIX) + # Include tests cmake + include(configs/azure_rtos_tests.cmake) +endif() diff --git a/test/cmake/azure_iot/configs/azure_rtos_src.cmake b/test/cmake/azure_iot/configs/azure_rtos_src.cmake new file mode 100644 index 00000000..012a98a6 --- /dev/null +++ b/test/cmake/azure_iot/configs/azure_rtos_src.cmake @@ -0,0 +1,47 @@ +# Set folder +set(TX_FOLDER "${PROJECT_SOURCE_DIR}/../threadx") +set(NXD_FOLDER "${PROJECT_SOURCE_DIR}/../../..") + +# Add tx +add_subdirectory(${TX_FOLDER} threadx) + +# Add nxd +set(NXD_ENABLE_FILE_SERVERS OFF CACHE BOOL "Disable fileX dependency by netxduo") +set(NXD_ENABLE_AZURE_IOT ON CACHE BOOL "Enable Azure IoT from netxduo") +add_subdirectory(${NXD_FOLDER} netxduo) + +set_target_properties(threadx PROPERTIES FOLDER "azure_rtos") +set_target_properties(netxduo PROPERTIES FOLDER "azure_rtos") + +set_target_properties(az_core PROPERTIES FOLDER "azure_iot_embedded_sdk") +set_target_properties(az_iot_common PROPERTIES FOLDER "azure_iot_embedded_sdk") +set_target_properties(az_iot_hub PROPERTIES FOLDER "azure_iot_embedded_sdk") +set_target_properties(az_iot_provisioning PROPERTIES FOLDER "azure_iot_embedded_sdk") +set_target_properties(az_nohttp PROPERTIES FOLDER "azure_iot_embedded_sdk") +set_target_properties(az_noplatform PROPERTIES FOLDER "azure_iot_embedded_sdk") + +# Enable strict build flags for netxduo +if(THREADX_TOOLCHAIN STREQUAL "gnu") + target_compile_options( + netxduo + PRIVATE -std=c99 + -Werror + -Wall + -Wextra + -pedantic + -fmessage-length=0 + -fsigned-char + -ffunction-sections + -fdata-sections + -Wunused + -Wuninitialized + -Wmissing-declarations + -Wconversion + -Wpointer-arith + -Wshadow + -Wlogical-op + -Wfloat-equal + -fprofile-arcs + -Wjump-misses-init + -Wno-error=misleading-indentation) +endif() \ No newline at end of file diff --git a/test/cmake/azure_iot/configs/azure_rtos_tests.cmake b/test/cmake/azure_iot/configs/azure_rtos_tests.cmake new file mode 100644 index 00000000..b693dec2 --- /dev/null +++ b/test/cmake/azure_iot/configs/azure_rtos_tests.cmake @@ -0,0 +1,351 @@ +# Enable testing +enable_testing() + +set(SDK_FOLDER "${PROJECT_SOURCE_DIR}/../../../addons/azure_iot") +set(SDK_CERT_SAMPLE_FOLDER "${SDK_FOLDER}/samples/cert") +set(AZURE_EMBEDDED_SDK_TESTS_FOLDER "${PROJECT_SOURCE_DIR}/../../regression/azure_iot") + +include_directories("${SDK_CERT_SAMPLE_FOLDER}/") +aux_source_directory(${SDK_CERT_SAMPLE_FOLDER}/ CERT_SAMPLE_SRC) + +set(unit_tests + initialization_unit_test + connection_unit_test + connection_non_block_ram_test + connection_sas_expiry_ram_test + d2c_unit_test + c2d_property_unit_test + c2d_unit_test + iot_provisioning_client_unit_test + nx_azure_iot_unit_test + direct_method_unit_test + device_twin_unit_test + device_cert_unit_test + trusted_cert_unit_test + user_agent_string_unit_test + api_unit_test + nx_azure_iot_json_writer_unit_test + nx_azure_iot_json_reader_unit_test + nx_azure_iot_pnp_client_telemetry_unit_test + nx_azure_iot_pnp_client_command_unit_test + nx_azure_iot_pnp_client_properties_unit_test + nx_azure_iot_adu_agent_unit_test) + +# Unit test cases +if(UNIX) + add_executable( + initialization_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/initialization_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(initialization_unit_test initialization_unit_test) + + target_link_libraries( + initialization_unit_test + PUBLIC netxduo -Wl,-wrap,_nxde_mqtt_client_receive_notify_set + -Wl,-wrap,_nxde_mqtt_client_delete) + + add_executable( + connection_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/connection_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(connection_unit_test connection_unit_test) + + target_link_libraries( + connection_unit_test + PUBLIC netxduo + -Wl,-wrap,_nxde_dns_host_by_name_get + -Wl,-wrap,_nxde_mqtt_client_secure_connect + -Wl,-wrap,_nxde_mqtt_client_disconnect + -Wl,-wrap,nx_azure_iot_security_module_enable + -Wl,-wrap,nx_azure_iot_security_module_disable) + + add_executable( + connection_non_block_ram_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/connection_non_block_ram_test.c + ${CERT_SAMPLE_SRC}) + add_test(connection_non_block_ram_test connection_non_block_ram_test) + + target_link_libraries( + connection_non_block_ram_test PUBLIC netxduo + -Wl,-wrap,_nxde_dns_host_by_name_get) + + add_executable( + connection_sas_expiry_ram_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/connection_sas_expiry_ram_test.c + ${CERT_SAMPLE_SRC}) + add_test(connection_sas_expiry_ram_test connection_sas_expiry_ram_test) + + target_link_libraries( + connection_sas_expiry_ram_test PUBLIC netxduo + -Wl,-wrap,_nxde_dns_host_by_name_get) + + add_executable( + d2c_unit_test ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/d2c_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(d2c_unit_test d2c_unit_test) + + target_link_libraries( + d2c_unit_test + PUBLIC netxduo + -Wl,-wrap,_nxde_mqtt_client_secure_connect + -Wl,-wrap,_nxde_dns_host_by_name_get + -Wl,-wrap,_nxd_mqtt_client_publish_packet_send + -Wl,-wrap,nx_azure_iot_security_module_enable + -Wl,-wrap,nx_azure_iot_security_module_disable) + + # This test case should be able to run in Windows. But cmocka.h can not be + # found. Disable Windows build for now. + add_executable( + c2d_property_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/c2d_property_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(c2d_property_unit_test c2d_property_unit_test) + + add_executable( + c2d_unit_test ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/c2d_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(c2d_unit_test c2d_unit_test) + + target_link_libraries( + c2d_unit_test + PUBLIC netxduo + -Wl,-wrap,_nxde_mqtt_client_receive_notify_set + -Wl,-wrap,_nxde_mqtt_client_secure_connect + -Wl,-wrap,_nxde_mqtt_client_subscribe + -Wl,-wrap,_nxde_dns_host_by_name_get + -Wl,-wrap,_nxde_mqtt_client_disconnect + -Wl,-wrap,_nxde_mqtt_client_unsubscribe + -Wl,-wrap,nx_azure_iot_security_module_enable + -Wl,-wrap,nx_azure_iot_security_module_disable) + + add_executable( + iot_provisioning_client_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/iot_provisioning_client_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(iot_provisioning_client_unit_test iot_provisioning_client_unit_test) + + target_link_libraries( + iot_provisioning_client_unit_test + PUBLIC netxduo + -Wl,-wrap,_nxde_mqtt_client_secure_connect + -Wl,-wrap,_nxde_mqtt_client_subscribe + -Wl,-wrap,_nxde_dns_host_by_name_get + -Wl,-wrap,_nxde_mqtt_client_disconnect + -Wl,-wrap,_nxde_mqtt_client_receive_notify_set + -Wl,-wrap,_nxd_mqtt_client_publish_packet_send + -Wl,-wrap,nx_azure_iot_buffer_allocate + -Wl,-wrap,_nx_packet_data_append + -Wl,-wrap,nx_azure_iot_security_module_enable + -Wl,-wrap,nx_azure_iot_security_module_disable) + + add_executable( + nx_azure_iot_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/nx_azure_iot_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(nx_azure_iot_unit_test nx_azure_iot_unit_test) + + add_executable( + direct_method_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/direct_method_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(direct_method_unit_test direct_method_unit_test) + + target_link_libraries( + direct_method_unit_test + PUBLIC netxduo + -Wl,-wrap,_nxde_mqtt_client_secure_connect + -Wl,-wrap,_nxde_mqtt_client_disconnect + -Wl,-wrap,_nxde_dns_host_by_name_get + -Wl,-wrap,_nxde_mqtt_client_subscribe + -Wl,-wrap,_nxde_mqtt_client_unsubscribe + -Wl,-wrap,_nxd_mqtt_client_publish_packet_send + -Wl,-wrap,_nxde_mqtt_client_receive_notify_set + -Wl,-wrap,nx_azure_iot_buffer_allocate + -Wl,-wrap,_nx_packet_data_append + -Wl,-wrap,nx_azure_iot_security_module_enable + -Wl,-wrap,nx_azure_iot_security_module_disable) + + add_executable( + device_twin_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/device_twin_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(device_twin_unit_test device_twin_unit_test) + + target_link_libraries( + device_twin_unit_test + PUBLIC netxduo + -Wl,-wrap,_nxde_mqtt_client_secure_connect + -Wl,-wrap,_nxde_mqtt_client_disconnect + -Wl,-wrap,_nxde_dns_host_by_name_get + -Wl,-wrap,_nxde_mqtt_client_subscribe + -Wl,-wrap,_nxde_mqtt_client_unsubscribe + -Wl,-wrap,_nxd_mqtt_client_publish_packet_send + -Wl,-wrap,_nxde_mqtt_client_receive_notify_set + -Wl,-wrap,nx_azure_iot_buffer_allocate + -Wl,-wrap,_nx_packet_data_append + -Wl,-wrap,nx_azure_iot_security_module_enable + -Wl,-wrap,nx_azure_iot_security_module_disable) + + add_executable( + device_cert_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/device_cert_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(device_cert_unit_test device_cert_unit_test) + + target_link_libraries( + device_cert_unit_test + PUBLIC netxduo + -Wl,-wrap,_nxde_mqtt_client_login_set + -Wl,-wrap,_nxde_dns_host_by_name_get + -Wl,-wrap,_nxde_mqtt_client_secure_connect + -Wl,-wrap,_nxde_mqtt_client_disconnect + -Wl,-wrap,nx_azure_iot_security_module_enable + -Wl,-wrap,nx_azure_iot_security_module_disable) + + add_executable( + trusted_cert_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/trusted_cert_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(trusted_cert_unit_test trusted_cert_unit_test) + + add_executable( + user_agent_string_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/user_agent_string_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(user_agent_string_unit_test user_agent_string_unit_test) + + target_link_libraries( + user_agent_string_unit_test + PUBLIC netxduo + -Wl,-wrap,_nxde_mqtt_client_secure_connect + -Wl,-wrap,_nxde_mqtt_client_disconnect + -Wl,-wrap,_nxde_dns_host_by_name_get + -Wl,-wrap,_nxd_mqtt_client_publish_packet_send + -Wl,-wrap,_nxe_ip_driver_interface_direct_command + -Wl,-wrap,nx_azure_iot_security_module_disable + -Wl,-wrap,nx_azure_iot_security_module_enable) + + add_executable( + nx_azure_iot_json_writer_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/nx_azure_iot_json_writer_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(nx_azure_iot_json_writer_unit_test nx_azure_iot_json_writer_unit_test) + + add_executable( + nx_azure_iot_json_reader_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/nx_azure_iot_json_reader_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(nx_azure_iot_json_reader_unit_test nx_azure_iot_json_reader_unit_test) + + add_executable( + nx_azure_iot_pnp_client_telemetry_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/nx_azure_iot_pnp_client_telemetry_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(nx_azure_iot_pnp_client_telemetry_unit_test nx_azure_iot_pnp_client_telemetry_unit_test) + + target_link_libraries( + nx_azure_iot_pnp_client_telemetry_unit_test + PUBLIC netxduo + -Wl,-wrap,_nxde_mqtt_client_secure_connect + -Wl,-wrap,_nxde_mqtt_client_disconnect + -Wl,-wrap,_nxde_dns_host_by_name_get + -Wl,-wrap,_nx_tcp_socket_send + -Wl,-wrap,nx_azure_iot_buffer_allocate + -Wl,-wrap,_nx_packet_data_append + -Wl,-wrap,nx_azure_iot_security_module_enable + -Wl,-wrap,nx_azure_iot_security_module_disable) + + add_executable( + nx_azure_iot_pnp_client_command_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/nx_azure_iot_pnp_client_command_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(nx_azure_iot_pnp_client_command_unit_test nx_azure_iot_pnp_client_command_unit_test) + + target_link_libraries( + nx_azure_iot_pnp_client_command_unit_test + PUBLIC netxduo + -Wl,-wrap,_nxde_mqtt_client_secure_connect + -Wl,-wrap,_nxde_mqtt_client_disconnect + -Wl,-wrap,_nxde_dns_host_by_name_get + -Wl,-wrap,_nxde_mqtt_client_subscribe + -Wl,-wrap,_nxd_mqtt_client_publish_packet_send + -Wl,-wrap,_nxde_mqtt_client_receive_notify_set + -Wl,-wrap,nx_azure_iot_buffer_allocate + -Wl,-wrap,_nx_packet_data_append + -Wl,-wrap,nx_azure_iot_security_module_enable + -Wl,-wrap,nx_azure_iot_security_module_disable) + + add_executable( + nx_azure_iot_pnp_client_properties_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/nx_azure_iot_pnp_client_properties_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(nx_azure_iot_pnp_client_properties_unit_test nx_azure_iot_pnp_client_properties_unit_test) + + target_link_libraries( + nx_azure_iot_pnp_client_properties_unit_test + PUBLIC netxduo + -Wl,-wrap,_nxde_mqtt_client_secure_connect + -Wl,-wrap,_nxde_mqtt_client_disconnect + -Wl,-wrap,_nxde_dns_host_by_name_get + -Wl,-wrap,_nxde_mqtt_client_subscribe + -Wl,-wrap,_nxd_mqtt_client_publish_packet_send + -Wl,-wrap,_nxde_mqtt_client_receive_notify_set + -Wl,-wrap,nx_azure_iot_buffer_allocate + -Wl,-wrap,_nx_packet_data_append + -Wl,-wrap,nx_azure_iot_security_module_enable + -Wl,-wrap,nx_azure_iot_security_module_disable) + + add_executable( + api_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/api_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(api_unit_test api_unit_test) + + target_link_libraries( + api_unit_test + PUBLIC netxduo + -Wl,-wrap,nx_azure_iot_publish_packet_get + -Wl,-wrap,az_iot_hub_client_properties_builder_begin_component + -Wl,-wrap,az_iot_hub_client_properties_builder_end_component + -Wl,-wrap,az_iot_hub_client_properties_builder_begin_response_status + -Wl,-wrap,az_iot_hub_client_properties_builder_end_response_status) + + add_executable( + nx_azure_iot_adu_agent_unit_test + ${AZURE_EMBEDDED_SDK_TESTS_FOLDER}/nx_azure_iot_adu_agent_unit_test.c + ${CERT_SAMPLE_SRC}) + add_test(nx_azure_iot_adu_agent_unit_test nx_azure_iot_adu_agent_unit_test) + + target_link_libraries( + nx_azure_iot_adu_agent_unit_test + PUBLIC netxduo + -Wl,-wrap,_nxde_mqtt_client_secure_connect + -Wl,-wrap,_nxde_mqtt_client_disconnect + -Wl,-wrap,_nxde_dns_host_by_name_get + -Wl,-wrap,_nxde_mqtt_client_subscribe + -Wl,-wrap,_nxd_mqtt_client_publish_packet_send + -Wl,-wrap,_nxde_mqtt_client_receive_notify_set + -Wl,-wrap,nx_azure_iot_buffer_allocate + -Wl,-wrap,_nx_packet_data_append + -Wl,-wrap,nx_azure_iot_security_module_enable + -Wl,-wrap,nx_azure_iot_security_module_disable + -Wl,-wrap,_nxe_web_http_client_connect + -Wl,-wrap,_nxe_web_http_client_request_send + -Wl,-wrap,_nxe_web_http_client_response_body_get) +endif() + +# Link cmocka +foreach(test ${unit_tests}) + target_link_libraries(${test} PUBLIC cmocka netxduo) +endforeach() + +# Disable idle for unit test. +foreach(test ${unit_tests}) + get_target_property(sources ${test} SOURCES) + set_property( + TARGET ${test} + PROPERTY SOURCES ${sources} + ${TX_FOLDER}/ports/linux/gnu/src/tx_initialize_low_level.c + ${TX_FOLDER}/ports/linux/gnu/src/tx_thread_schedule.c) + target_compile_options(${test} PUBLIC -DTX_LINUX_NO_IDLE_ENABLE) +endforeach() diff --git a/test/cmake/azure_iot/configs/linux.cmake b/test/cmake/azure_iot/configs/linux.cmake new file mode 100644 index 00000000..192425c6 --- /dev/null +++ b/test/cmake/azure_iot/configs/linux.cmake @@ -0,0 +1,31 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR x86_64) + +set(CMAKE_C_COMPILER gcc) +set(CMAKE_CXX_COMPILER g++) +set(AS as) +set(AR ar) +set(OBJCOPY objcopy) +set(OBJDUMP objdump) +set(SIZE size) + +set(THREADX_ARCH "linux") +set(THREADX_TOOLCHAIN "gnu") + +set(LINUX_FLAGS "-g -pthread") + +set(CMAKE_C_FLAGS "${LINUX_FLAGS} " CACHE INTERNAL "c compiler flags") +set(CMAKE_CXX_FLAGS "${LINUX_FLAGS} -fno-rtti -fno-exceptions" CACHE INTERNAL "cxx compiler flags") +set(CMAKE_ASM_FLAGS "${LINUX_FLAGS} -x assembler-with-cpp" CACHE INTERNAL "asm compiler flags") +set(CMAKE_EXE_LINKER_FLAGS "${LINUX_FLAGS} ${LD_FLAGS} -Wl,--gc-sections" CACHE INTERNAL "exe link flags") + +SET(CMAKE_C_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "c debug compiler flags") +SET(CMAKE_CXX_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "cxx debug compiler flags") +SET(CMAKE_ASM_FLAGS_DEBUG "-g -ggdb3" CACHE INTERNAL "asm debug compiler flags") + +SET(CMAKE_C_FLAGS_RELEASE "-O3" CACHE INTERNAL "c release compiler flags") +SET(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE INTERNAL "cxx release compiler flags") +SET(CMAKE_ASM_FLAGS_RELEASE "" CACHE INTERNAL "asm release compiler flags") + +# this makes the test compiles use static library option so that we don't need to pre-set linker flags and scripts +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) diff --git a/test/cmake/azure_iot/configs/win32.cmake b/test/cmake/azure_iot/configs/win32.cmake new file mode 100644 index 00000000..974107ad --- /dev/null +++ b/test/cmake/azure_iot/configs/win32.cmake @@ -0,0 +1,15 @@ +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_PROCESSOR x86_64) + +set(THREADX_ARCH "win32") +set(THREADX_TOOLCHAIN "vs_2019") + +set(WIN32_FLAGS "") + +set(CMAKE_C_FLAGS "${WIN32_FLAGS} " CACHE INTERNAL "c compiler flags") +set(CMAKE_CXX_FLAGS "${WIN32_FLAGS} -fno-rtti -fno-exceptions" CACHE INTERNAL "cxx compiler flags") +set(CMAKE_ASM_FLAGS "${WIN32_FLAGS} -x assembler-with-cpp" CACHE INTERNAL "asm compiler flags") +set(CMAKE_EXE_LINKER_FLAGS "${WIN32_FLAGS} ${LD_FLAGS}" CACHE INTERNAL "exe link flags") + +# this makes the test compiles use static library option so that we don't need to pre-set linker flags and scripts +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) diff --git a/test/cmake/azure_iot/coverage.sh b/test/cmake/azure_iot/coverage.sh new file mode 100755 index 00000000..4603acad --- /dev/null +++ b/test/cmake/azure_iot/coverage.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -e + +cd $(dirname $0) +mkdir -p coverage_report/$1 +gcovr --object-directory=build/$1/netxduo/CMakeFiles/netxduo.dir/addons/azure_iot -r ../../../addons/azure_iot --xml-pretty --output coverage_report/$1.xml +gcovr --object-directory=build/$1/netxduo/CMakeFiles/netxduo.dir/addons/azure_iot -r ../../../addons/azure_iot --html --html-details --output coverage_report/$1/index.html diff --git a/test/cmake/azure_iot/run.sh b/test/cmake/azure_iot/run.sh new file mode 100755 index 00000000..55c601c6 --- /dev/null +++ b/test/cmake/azure_iot/run.sh @@ -0,0 +1,115 @@ +#!/bin/bash +set -e + +function help() { + echo "Usage: $0 [build|test] [all| ...]" + echo "Available build_configuration:" + for build in ${build_configurations[*]}; do + echo " $build" + done + exit 1 +} + +function validate() { + for build in ${build_configurations[*]}; do + if [ "$1" == "$build" ]; then + return + fi + done + help +} + +function generate() { + build=$1 + cmake -Bbuild/$build -GNinja -DCMAKE_BUILD_TYPE=$build . +} + +function build() { + cmake --build build/$1 +} + +function test() { + pushd build/$1 + [ -z "${CTEST_PARALLEL_LEVEL}" ] && parallel="-j$2" + if [ -z "${CTEST_REPEAT_FAIL}" ]; + then + repeat_fail=2 + else + repeat_fail=${CTEST_REPEAT_FAIL} + fi + ctest $parallel --timeout 1000 -O $1.txt -T test --no-compress-output --test-output-size-passed 4194304 --test-output-size-failed 4194304 --output-on-failure --repeat until-pass:${repeat_fail} --output-junit $1.xml + popd + grep -E "^(\s*[0-9]+|Total)" build/$1/$1.txt >build/$1.txt + sed -i "s/\x1B\[[0-9;]*[JKmsu]//g" build/$1.txt + if [[ $1 = *"_coverage" ]]; then + ./coverage.sh $1 + fi +} + +cd $(dirname $0) + +# if threadx repo does not exist, clone it +[ -d ../threadx ] || git clone https://github.com/azure-rtos/threadx.git ../threadx --depth 1 + +result=$(sed -n "/(BUILD_CONFIGURATIONS/,/)/p" CMakeLists.txt|sed ':label;N;s/\n/ /;b label'|grep -Pzo "[a-zA-Z0-9_]*build[a-zA-Z0-9_]*\s*"| tr -d '\0') +IFS=' ' +read -ra build_configurations <<< "$result" + +if [ $# -lt 1 ]; then + help +fi + +command=$1 +shift + +if [ "$#" == "0" ]; then + builds=${build_configurations[0]} +elif [ "$*" == "all" ]; then + builds=${build_configurations[@]} +else + for item in $*; do + validate $item + done + builds=$* +fi + +if [ "$command" == "build" ]; then + for item in $builds; do + generate $item + echo "" + done + + for item in $builds; do + echo "Building $item" + build $item + echo "" + done +elif [ "$command" == "test" ]; then + cores=$(nproc) + if [ -z "${CTEST_PARALLEL_LEVEL}" ]; + then + # Run builds in parallel + build_counts=$(echo $builds | wc -w) + parallel_jobs=$(($cores / $build_counts)) + parallel_jobs=$(($parallel_jobs + 2)) + pids="" + for item in $builds; do + echo "Testing $item" + test $item $parallel_jobs & + pids+=" $!" + done + exit_code=0 + for p in $pids; do + wait $p || exit_code=$? + done + exit $exit_code + else + # Run builds in serial + for item in $builds; do + echo "Testing $item" + test $item $parallel_jobs + done + fi +else + help +fi diff --git a/test/regression/azure_iot/api_unit_test.c b/test/regression/azure_iot/api_unit_test.c new file mode 100644 index 00000000..cea59c46 --- /dev/null +++ b/test/regression/azure_iot/api_unit_test.c @@ -0,0 +1,589 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_hub_client_properties.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +static UINT api_no_model_id_test(); +static VOID api_model_id_test(); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; + +NX_SECURE_X509_CERT device_certificate; +NX_PACKET *packet_ptr; +UCHAR *property_name = "propertyA"; +USHORT property_name_length = sizeof("propertyA") - 1; +UCHAR *property_value; +USHORT property_value_lenght; +UCHAR *name; +USHORT name_length; +UCHAR *context_ptr; +USHORT context_length; +UCHAR *component_name; +USHORT component_name_length; +UCHAR message_buffer[1024]; +UINT message_length = 1024; +UINT request_id; +UINT response_status; +ULONG version; +NX_AZURE_IOT_JSON_WRITER json_writer; +NX_AZURE_IOT_JSON_READER json_reader; +UCHAR json_buffer[2014]; + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert, (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* Perform actual tests. */ + api_no_model_id_test(); + api_model_id_test(); +} + +static VOID connection_status_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT status) +{ + NX_PARAMETER_NOT_USED(hub_client_ptr); + NX_PARAMETER_NOT_USED(status); +} + +static VOID message_receive_callback_properties(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *context) +{ + NX_PARAMETER_NOT_USED(hub_client_ptr); + NX_PARAMETER_NOT_USED(context); +} + +static VOID reported_properties_response_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT request_id, + UINT response_status, ULONG version, VOID *args) +{ + NX_PARAMETER_NOT_USED(hub_client_ptr); + NX_PARAMETER_NOT_USED(request_id); + NX_PARAMETER_NOT_USED(response_status); + NX_PARAMETER_NOT_USED(version); + NX_PARAMETER_NOT_USED(args); +} + +static UINT api_no_model_id_test() +{ + + /* Using IoT Hub APIs if nx_azure_iot_hub_client_model_id_set is not called after initialization. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS("host_name"), + STRING_UNSIGNED_ARGS("device_id"), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Connect APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_device_cert_set(&iot_client, &device_certificate), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_symmetric_key_set(&iot_client, "symmetric_key", sizeof("symmetric_key") - 1), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_component_add(&iot_client, "componentA", sizeof("componentA") - 1), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_connection_status_callback_set(&iot_client, connection_status_callback), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_receive_callback_set(&iot_client, NX_AZURE_IOT_HUB_PROPERTIES, + message_receive_callback_properties, NX_NULL), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_TRUE, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_disconnect(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* C2D APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_enable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_disable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_property_get(&iot_client, packet_ptr, + property_name, property_name_length, + (const UCHAR **)&property_value, &property_value_lenght), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* Telemetry APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_component_set(packet_ptr, + "componentA", sizeof("componentA") - 1, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_property_add(packet_ptr, + "propertyA", sizeof("propertyA") - 1, + "valueA", sizeof("valueA") - 1, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_send(&iot_client, packet_ptr, + "data", sizeof("data") - 1, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* Direct Method APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_enable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_disable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_message_receive(&iot_client, + (const UCHAR **)&name, (USHORT *)&name_length, + (void **)&context_ptr, &context_length, + &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_message_response(&iot_client, 200, + "12222", sizeof("12222") - 1, + "payload", sizeof("payload") - 1, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* Command APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_command_enable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_command_disable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_command_message_receive(&iot_client, + (const UCHAR **)&component_name, &component_name_length, + (const UCHAR **)&name, &name_length, + (void **)&context_ptr, &context_length, + &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_command_message_response(&iot_client, 200, + "12222", sizeof("12222") - 1, + "payload", sizeof("payload") - 1, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* Device twin APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_disable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_response_callback_set(&iot_client, + reported_properties_response_callback, + NX_NULL), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_reported_properties_send(&iot_client, + message_buffer, message_length, + &request_id, &response_status, + &version, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_properties_request(&iot_client, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_properties_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_desired_properties_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* Properties APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_properties_enable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_disable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_response_callback_set(&iot_client, + reported_properties_response_callback, + NX_NULL), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_create(&iot_client, + &packet_ptr, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_equal(nx_azure_iot_json_writer_with_buffer_init(&json_writer, json_buffer, sizeof(json_buffer)), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_json_writer_append_begin_object(&json_writer), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_component_begin(&iot_client, + &json_writer, + "componentA", + sizeof("componentA") - 1), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_component_end(&iot_client, &json_writer), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_status_begin(&iot_client, &json_writer, + "property_name", sizeof("property_name") - 1, + 200, 20, + NX_NULL, 0), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_equal(nx_azure_iot_json_writer_append_int32(&json_writer, 20), + NX_AZURE_IOT_SUCCESS); + + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_status_end(&iot_client, &json_writer), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_send(&iot_client, + packet_ptr, + &request_id, &response_status, + &version, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_request(&iot_client, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_receive(&iot_client, + &packet_ptr, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_writable_properties_receive(&iot_client, + &packet_ptr, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_component_property_next_get(&iot_client, + &json_reader, + NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES, + NX_AZURE_IOT_HUB_CLIENT_PROPERTY_WRITABLE, + (const UCHAR **)&component_name, + &component_name_length), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* Deinitialize. */ + assert_int_not_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); +} + +static VOID api_model_id_test() +{ + + /* Using PnP APIs if nx_azure_iot_hub_client_model_id_set is called after initialization. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS("host_name"), + STRING_UNSIGNED_ARGS("device_id"), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&iot_client, + "pnp_model_id_unit_test", + sizeof("pnp_model_id_unit_test") - 1), + NX_AZURE_IOT_SUCCESS); + + /* Connect APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_device_cert_set(&iot_client, &device_certificate), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_symmetric_key_set(&iot_client, "symmetric_key", sizeof("symmetric_key") - 1), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_component_add(&iot_client, "componentA", sizeof("componentA") - 1), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_connection_status_callback_set(&iot_client, connection_status_callback), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_receive_callback_set(&iot_client, NX_AZURE_IOT_HUB_PROPERTIES, + message_receive_callback_properties, NX_NULL), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_TRUE, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_disconnect(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* C2D APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_enable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_disable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_property_get(&iot_client, packet_ptr, + property_name, property_name_length, + (const UCHAR **)&property_value, &property_value_lenght), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* Telemetry APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_component_set(packet_ptr, + "componentA", sizeof("componentA") - 1, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_property_add(packet_ptr, + "propertyA", sizeof("propertyA") - 1, + "valueA", sizeof("valueA") - 1, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_send(&iot_client, packet_ptr, + "data", sizeof("data") - 1, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* Direct Method APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_enable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_disable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_message_receive(&iot_client, + (const UCHAR **)&name, (USHORT *)&name_length, + (void **)&context_ptr, &context_length, + &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_message_response(&iot_client, 200, + "12222", sizeof("12222") - 1, + "payload", sizeof("payload") - 1, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* Command APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_command_enable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_command_disable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_command_message_receive(&iot_client, + (const UCHAR **)&component_name, &component_name_length, + (const UCHAR **)&name, &name_length, + (void **)&context_ptr, &context_length, + &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_command_message_response(&iot_client, 200, + "12222", sizeof("12222") - 1, + "payload", sizeof("payload") - 1, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* Device twin APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_disable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_response_callback_set(&iot_client, + reported_properties_response_callback, + NX_NULL), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_reported_properties_send(&iot_client, + message_buffer, message_length, + &request_id, &response_status, + &version, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_properties_request(&iot_client, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_properties_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_desired_properties_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* Properties APIs. */ + assert_int_not_equal(nx_azure_iot_hub_client_properties_enable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_disable(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_response_callback_set(&iot_client, + reported_properties_response_callback, + NX_NULL), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_create(&iot_client, + &packet_ptr, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_equal(nx_azure_iot_json_writer_with_buffer_init(&json_writer, json_buffer, sizeof(json_buffer)), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_json_writer_append_begin_object(&json_writer), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_component_begin(&iot_client, + &json_writer, + "componentA", + sizeof("componentA") - 1), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_component_end(&iot_client, &json_writer), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_status_begin(&iot_client, &json_writer, + "property_name", sizeof("property_name") - 1, + 200, 20, + NX_NULL, 0), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_equal(nx_azure_iot_json_writer_append_int32(&json_writer, 20), + NX_AZURE_IOT_SUCCESS); + + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_status_end(&iot_client, &json_writer), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_send(&iot_client, + packet_ptr, + &request_id, &response_status, + &version, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_request(&iot_client, NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_receive(&iot_client, + &packet_ptr, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_writable_properties_receive(&iot_client, + &packet_ptr, + NX_NO_WAIT), + NX_AZURE_IOT_NOT_SUPPORTED); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_component_property_next_get(&iot_client, + &json_reader, + NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES, + NX_AZURE_IOT_HUB_CLIENT_PROPERTY_WRITABLE, + (const UCHAR **)&component_name, + &component_name_length), + NX_AZURE_IOT_NOT_SUPPORTED); + + /* Deinitialize. */ + assert_int_not_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_NOT_SUPPORTED); +} + +UINT __wrap_nx_azure_iot_publish_packet_get(NX_AZURE_IOT *nx_azure_iot_ptr, NXD_MQTT_CLIENT *client_ptr, + NX_PACKET **packet_pptr, UINT wait_option) +{ + return(NX_AZURE_IOT_FAILURE); +} + +UINT __wrap_az_iot_hub_client_properties_builder_begin_component(az_iot_hub_client const* client, + az_json_writer* ref_json_writer, + az_span component_name) +{ + return(NX_AZURE_IOT_FAILURE); +} + +UINT __wrap_az_iot_hub_client_properties_builder_end_component(az_iot_hub_client const* client, + az_json_writer* ref_json_writer) +{ + return(NX_AZURE_IOT_FAILURE); +} + +UINT __wrap_az_iot_hub_client_properties_builder_begin_response_status(az_iot_hub_client const* client, + az_json_writer* ref_json_writer, + az_span property_name, + int32_t ack_code, + int32_t ack_version, + az_span ack_description) +{ + return(NX_AZURE_IOT_FAILURE); +} + +UINT __wrap_az_iot_hub_client_properties_builder_end_response_status(az_iot_hub_client const* client, + az_json_writer* ref_json_writer) +{ + return(NX_AZURE_IOT_FAILURE); +} diff --git a/test/regression/azure_iot/c2d_property_unit_test.c b/test/regression/azure_iot/c2d_property_unit_test.c new file mode 100644 index 00000000..bcf3c803 --- /dev/null +++ b/test/regression/azure_iot/c2d_property_unit_test.c @@ -0,0 +1,357 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + +#define C2D_TOPIC "devices/device_id/messages/devicebound/" + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +#ifndef MAXIMUM_PROPERTY_LENGTH +#define MAXIMUM_PROPERTY_LENGTH 1400 /* packet size */ +#endif /* MAXIMUM_PROPERTY_LENGTH */ + +typedef struct +{ + UCHAR *name; + USHORT name_length; + UCHAR *value; + USHORT value_length; +} PROPERTY; + +#define PROPERTY_INIT(name, value) {(name), sizeof(name) - 1, (value), sizeof(value) - 1} + +static VOID initialize_data(); +static VOID empty_property_test(); +static VOID multiple_properties_test(); +static VOID construct_c2d_packet(NX_PACKET **packet_pptr, PROPERTY *properties, UINT property_count, + UCHAR *message_payload_ptr, ULONG message_payload_length); +extern UINT _nxd_mqtt_client_append_message(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, CHAR *message, + UINT length, ULONG wait_option); +extern UINT _nxd_mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + UCHAR control_header, UINT length, UINT wait_option); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +static UCHAR property_name[MAXIMUM_PROPERTY_LENGTH]; +static UCHAR property_value[MAXIMUM_PROPERTY_LENGTH]; +static UCHAR message_payload[32]; + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ +CHAR *host_name = "host_name"; +CHAR *device_id = "device_id"; +CHAR *module_id = "module_id"; +CHAR *symmetric_key = "symmetric_key"; +ULONG pool_ptr_available_packet; + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert, (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* Record number of available packet before test */ + pool_ptr_available_packet = pool_ptr -> nx_packet_pool_available; + + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + + /* Perform actual tests. */ + initialize_data(); + empty_property_test(); + multiple_properties_test(); + + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* Check if all the packet are released */ + assert_int_equal(pool_ptr -> nx_packet_pool_available, pool_ptr_available_packet); + + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); +} + +static VOID initialize_data() +{ +UINT i; + + for (i = 0; i < MAXIMUM_PROPERTY_LENGTH; i++) + { + property_name[i] = (NX_RAND() % 26) + 'a'; + property_value[i] = (NX_RAND() % 26) + 'a'; + } + + for (i = 0; i < sizeof(message_payload); i++) + { + message_payload[i] = (NX_RAND() % 26) + 'a'; + } +} + +static VOID construct_c2d_packet(NX_PACKET **packet_pptr, PROPERTY *properties, UINT property_count, + UCHAR *message_payload_ptr, ULONG message_payload_length) +{ +NX_PACKET *packet_ptr; +ULONG topic_length = sizeof(C2D_TOPIC) - 1; +ULONG total_length; +UCHAR bytes[2]; +UINT i; + + assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + for (i = 0; i < property_count; i++) + { + topic_length += properties[i].name_length + properties[i].value_length + 2; /* '=' and '&' */ + } + + if (property_count) + { + topic_length--; /* Reduce by one since last '&' is not needed. */ + } + total_length = topic_length + 2 + 2 + message_payload_length; /* Two bytes for fixed topic_length field + and two bytes for packet id. */ + + /* Set fixed header. */ + assert_int_equal(_nxd_mqtt_client_set_fixed_header(&(iot_client.nx_azure_iot_hub_client_resource.resource_mqtt), packet_ptr, + (UCHAR)((MQTT_CONTROL_PACKET_TYPE_PUBLISH << 4) | MQTT_PUBLISH_QOS_LEVEL_1), + total_length, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic length. */ + bytes[0] = (topic_length >> 8) & 0xFF; + bytes[1] = topic_length & 0xFF; + assert_int_equal(nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic. */ + assert_int_equal(nx_packet_data_append(packet_ptr, C2D_TOPIC, sizeof(C2D_TOPIC) - 1, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + for (i = 0; i < property_count; i++) + { + if (i != 0) + { + assert_int_equal(nx_packet_data_append(packet_ptr, "&", 1, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + assert_int_equal(nx_packet_data_append(packet_ptr, properties[i].name, properties[i].name_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_packet_data_append(packet_ptr, "=", 1, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_packet_data_append(packet_ptr, properties[i].value, properties[i].value_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + + /* Set packet ID. The value does not matter. */ + assert_int_equal(nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set message payload. */ + if (message_payload_length > 0) + { + assert_int_equal(nx_packet_data_append(packet_ptr, message_payload_ptr, message_payload_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + + *packet_pptr = packet_ptr; +} + +static VOID empty_property_test() +{ +NX_PACKET *packet_ptr; +CHAR *fake_property_name = "fake_property_name"; +USHORT result_size; +const UCHAR *result; + + /* No properties are added. */ + construct_c2d_packet(&packet_ptr, NX_NULL, 0, NX_NULL, 0); + + /* Search for NX_NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_property_get(&iot_client, packet_ptr, NX_NULL, + 0, &result, &result_size), + NX_AZURE_IOT_SUCCESS); + + /* Search for a property does not existed. */ + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_property_get(&iot_client, packet_ptr, fake_property_name, + (USHORT)strlen(fake_property_name), + &result, &result_size), + NX_AZURE_IOT_SUCCESS); + + nx_packet_release(packet_ptr); +} + +static VOID multiple_properties_test() +{ +NX_PACKET *packet_ptr; +CHAR *fake_property_name = "fake_property_name"; +USHORT result_size; +const UCHAR *result; +ULONG fixed_property_length = 10; +PROPERTY property_0 = PROPERTY_INIT("property_name_0", "property_value_0"); +PROPERTY property_1 = PROPERTY_INIT("property_name_1", "property_value_1"); +PROPERTY property_random = {property_name, 0, property_value, 0}; +PROPERTY properties[3]; +ULONG message_payload_length; +UINT property_count; +UINT i, j, k, l; + + for (i = 0; i < 2; i++) + { + + if (i == 0) + { + + /* First round, length of property name is variable. + * Length of property value is fixed. */ + property_random.value_length = fixed_property_length; + } + else + { + + /* Second round, length of property name is fixed. + * Length of property value is variable. */ + property_random.name_length = fixed_property_length; + } + + for (j = 1; j < MAXIMUM_PROPERTY_LENGTH; j++) + { + if (i == 0) + { + + /* First round, length of property name is variable. + * Length of property value is fixed. */ + property_random.name_length = j; + } + else + { + + /* Second round, length of property name is fixed. + * Length of property value is variable. */ + property_random.value_length = j; + } + + for (k = 0; k < 4; k++) + { + + /* For each random property, test the following situations. + * 1. One property with random length. + * 2. Three properties. The first one with random length and last two with fixed lengths. + * 3. Three properties. The first and last with fixed lengths, the middle one with random length. + * 4. Three properties. The first two with fixed lengths, the last one with random length. */ + if (k == 0) + { + + /* Test only one random length property. */ + property_count = 1; + properties[0] = property_random; + } + else + { + + /* Test three properties with different sequence. */ + property_count = 3; + if (k == 1) + { + properties[0] = property_random; + properties[1] = property_0; + properties[2] = property_1; + } + else if (k == 2) + { + properties[0] = property_0; + properties[1] = property_random; + properties[2] = property_1; + } + else + { + properties[0] = property_0; + properties[1] = property_1; + properties[2] = property_random; + } + } + + message_payload_length = (NX_RAND() & 31); + construct_c2d_packet(&packet_ptr, properties, property_count, message_payload, message_payload_length); + + /* Search for a property does not existed. */ + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_property_get(&iot_client, packet_ptr, fake_property_name, + (USHORT)strlen(fake_property_name), + &result, &result_size), + NX_AZURE_IOT_SUCCESS); + + /* Verify all properties. */ + for (l = 0; l < property_count; l++) + { + + /* Search for an existing property. */ + assert_int_equal(nx_azure_iot_hub_client_cloud_message_property_get(&iot_client, packet_ptr, properties[l].name, + properties[l].name_length, + &result, &result_size), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(properties[l].value_length, result_size); + assert_memory_equal(properties[l].value, result, result_size); + } + + nx_packet_release(packet_ptr); + } + } + } +} diff --git a/test/regression/azure_iot/c2d_unit_test.c b/test/regression/azure_iot/c2d_unit_test.c new file mode 100644 index 00000000..5fd0f9db --- /dev/null +++ b/test/regression/azure_iot/c2d_unit_test.c @@ -0,0 +1,584 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + +#define C2D_TOPIC "devices/device_id/messages/devicebound/" + +#define CALLBACK_ARGS 0x12345678 + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +#ifndef MAXIMUM_PROPERTY_LENGTH +#define MAXIMUM_PROPERTY_LENGTH 1400 /* packet size */ +#endif /* MAXIMUM_PROPERTY_LENGTH */ + +#ifndef MAXIMUM_PAYLOAD_LENGTH +#define MAXIMUM_PAYLOAD_LENGTH 10240 +#endif /* MAXIMUM_PAYLOAD_LENGTH */ + +#define MQTT_CLIENT_GET(c) ((c) -> nx_azure_iot_hub_client_resource.resource_mqtt) +#define TX_MUTEX_GET(c) ((c) -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr) + +typedef struct +{ + UCHAR *name; + ULONG name_length; + UCHAR *value; + ULONG value_length; +} PROPERTY; + +#define PROPERTY_INIT(name, value) {(name), sizeof(name) - 1, (value), sizeof(value) - 1} + +static VOID initialize_data(); +static VOID property_payload_test(UINT packet_offset); +static VOID callback_test(); +static VOID invalid_packet_test(); +static VOID wait_timeout_test(); +static VOID no_receiver_test(); +static VOID construct_c2d_packet(NX_PACKET **packet_pptr, PROPERTY *properties, UINT property_count, + UCHAR *message_payload_ptr, ULONG message_payload_length, + UINT packet_offset); +static VOID c2d_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *args); +extern UINT _nxd_mqtt_client_append_message(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, CHAR *message, + UINT length, ULONG wait_option); +extern UINT _nxd_mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + UCHAR control_header, UINT length, UINT wait_option); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +static UCHAR property_name[MAXIMUM_PROPERTY_LENGTH]; +static UCHAR property_value[MAXIMUM_PROPERTY_LENGTH]; +static UCHAR message_payload[MAXIMUM_PAYLOAD_LENGTH]; +static UCHAR result_buffer[MAXIMUM_PAYLOAD_LENGTH]; +static VOID (*test_receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count) = NX_NULL; + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ +CHAR *host_name = "host_name"; +CHAR *device_id = "device_id"; +CHAR *module_id = "module_id"; +CHAR *symmetric_key = "symmetric_key"; +ULONG pool_ptr_available_packet; + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert, (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* Record number of available packet before test */ + pool_ptr_available_packet = pool_ptr -> nx_packet_pool_available; + + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_cloud_message_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + /* Connect IoTHub client */ + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + /* Perform actual tests. */ + initialize_data(); + property_payload_test(0); + property_payload_test(1000); + callback_test(); + invalid_packet_test(); + wait_timeout_test(); + no_receiver_test(); + + + will_return(__wrap__nxde_mqtt_client_unsubscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_cloud_message_disable(&iot_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_disconnect(&iot_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* Check if all the packet are released */ + assert_int_equal(pool_ptr -> nx_packet_pool_available, pool_ptr_available_packet); + + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); +} + +static VOID initialize_data() +{ +UINT i; + + for (i = 0; i < MAXIMUM_PROPERTY_LENGTH; i++) + { + property_name[i] = (NX_RAND() % 26) + 'a'; + property_value[i] = (NX_RAND() % 26) + 'a'; + } + + for (i = 0; i < sizeof(message_payload); i++) + { + message_payload[i] = (NX_RAND() % 26) + 'a'; + } +} + +static VOID construct_c2d_packet(NX_PACKET **packet_pptr, PROPERTY *properties, UINT property_count, + UCHAR *message_payload_ptr, ULONG message_payload_length, UINT packet_offset) +{ +NX_PACKET *packet_ptr; +ULONG topic_length = sizeof(C2D_TOPIC) - 1; +ULONG total_length; +UCHAR bytes[2]; +UINT i; + + assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, packet_offset, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + for (i = 0; i < property_count; i++) + { + topic_length += properties[i].name_length + properties[i].value_length + 2; /* '=' and '&' */ + } + + if (property_count) + { + topic_length--; /* Reduce by one since last '&' is not needed. */ + } + total_length = topic_length + 2 + 2 + message_payload_length; /* Two bytes for fixed topic_length field + and two bytes for packet id. */ + + /* Set fixed header. */ + assert_int_equal(_nxd_mqtt_client_set_fixed_header(&(MQTT_CLIENT_GET(&iot_client)), packet_ptr, + (UCHAR)((MQTT_CONTROL_PACKET_TYPE_PUBLISH << 4) | MQTT_PUBLISH_QOS_LEVEL_1), + total_length, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic length. */ + bytes[0] = (topic_length >> 8) & 0xFF; + bytes[1] = topic_length & 0xFF; + assert_int_equal(nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic. */ + assert_int_equal(nx_packet_data_append(packet_ptr, C2D_TOPIC, sizeof(C2D_TOPIC) - 1, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + for (i = 0; i < property_count; i++) + { + if (i != 0) + { + assert_int_equal(nx_packet_data_append(packet_ptr, "&", 1, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + assert_int_equal(nx_packet_data_append(packet_ptr, properties[i].name, properties[i].name_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_packet_data_append(packet_ptr, "=", 1, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_packet_data_append(packet_ptr, properties[i].value, properties[i].value_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + + /* Set packet ID. The value does not matter. */ + assert_int_equal(nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set message payload. */ + if (message_payload_length > 0) + { + assert_int_equal(nx_packet_data_append(packet_ptr, message_payload_ptr, message_payload_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + + *packet_pptr = packet_ptr; +} + +static VOID property_payload_test(UINT packet_offset) +{ +NX_PACKET *packet_ptr; +ULONG bytes_copied; +USHORT result_size; +const UCHAR *result; +PROPERTY property = {property_name, 10, property_value, 10}; +ULONG message_payload_length; +ULONG *length; +ULONG loop; +UINT i; + + for (i = 0; i < 3; i++) + { + if (i == 0) + { + + /* First round, length of property name is variable. */ + loop = MAXIMUM_PROPERTY_LENGTH; + length = &property.name_length; + property.value_length = 10; + message_payload_length = 10; + } + else if (i == 1) + { + + /* Second round, length of property value is variable. */ + loop = MAXIMUM_PROPERTY_LENGTH; + length = &property.value_length; + property.name_length = 10; + message_payload_length = 10; + } + else + { + + /* Third round, length of message is variable. */ + loop = MAXIMUM_PAYLOAD_LENGTH; /* It is supported when message is spanned in multiple packets. */ + length = &message_payload_length; + property.name_length = 10; + property.value_length = 10; + } + for (*length = 0; *length < loop; (*length)++) + { + if ((i < 2) && (*length == 0)) + { + + /* Skip length 0 for property. */ + continue; + } + + construct_c2d_packet(&packet_ptr, &property, 1, message_payload, message_payload_length, packet_offset); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(&iot_client).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(&iot_client).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(&iot_client), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(&iot_client)), 1); + tx_mutex_put(TX_MUTEX_GET(&iot_client)); + + assert_int_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Validate property. */ + memset(result_buffer, property.value_length, 0); + assert_int_equal(nx_azure_iot_hub_client_cloud_message_property_get(&iot_client, packet_ptr, + property.name, property.name_length, + &result, &result_size), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(property.value_length, result_size); + assert_memory_equal(property.value, result, result_size); + + /* Validate payload. */ + memset(result_buffer, message_payload_length, 0); + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(message_payload_length, bytes_copied); + assert_memory_equal(message_payload, result_buffer, bytes_copied); + + nx_packet_release(packet_ptr); + } + } +} + +static UINT (*c2d_message_process)(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr, + NX_PACKET *packet_ptr, ULONG topic_offset, USHORT topic_length); + +static VOID callback_test() +{ +ULONG arg = CALLBACK_ARGS; +NX_PACKET *packet_ptr; +ULONG bytes_copied; +ULONG message_payload_length = 10; +UINT c2d_control_flag; + + /* Expected fail: NX_AZURE_IOT_HUB_CLIENT is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_receive_callback_set(NX_NULL, + NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE, + c2d_callback, + &arg), + NX_AZURE_IOT_SUCCESS); + + /* Expected fail: unknown message type. */ + assert_int_not_equal(nx_azure_iot_hub_client_receive_callback_set(&iot_client, + 0xFFFFFFFF, + c2d_callback, + &arg), + NX_AZURE_IOT_SUCCESS); + + /* Expect c2d_callback to be called once. */ + expect_function_calls(c2d_callback, 1); + + /* Set callback function. */ + assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iot_client, + NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE, + c2d_callback, + &arg), + NX_AZURE_IOT_SUCCESS); + + /* Put C2D packet to MQTT receive queue. */ + construct_c2d_packet(&packet_ptr, NX_NULL, 0, message_payload, message_payload_length, 0); + MQTT_CLIENT_GET(&iot_client).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(&iot_client).message_receive_queue_depth = 1; + + /* Expected callback function to be set. */ + assert_ptr_not_equal(test_receive_notify, NX_NULL); + + /* Simulate callback from MQTT layer. */ + tx_mutex_get(TX_MUTEX_GET(&iot_client), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(&iot_client)), 1); + tx_mutex_put(TX_MUTEX_GET(&iot_client)); + + /* Expected fail: NX_AZURE_IOT_HUB_CLIENT is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(NX_NULL, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Expected fail: packet pointer is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, NX_NULL, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Expected fail: packet pointer is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, NX_NULL, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Expected fail: message_process is NULL. */ + c2d_message_process = iot_client.nx_azure_iot_hub_client_c2d_message.message_process; + iot_client.nx_azure_iot_hub_client_c2d_message.message_process = NX_NULL; + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + iot_client.nx_azure_iot_hub_client_c2d_message.message_process = c2d_message_process; + + /* Receive packet by API. */ + assert_int_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Validate payload. */ + memset(result_buffer, message_payload_length, 0); + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(message_payload_length, bytes_copied); + assert_memory_equal(message_payload, result_buffer, bytes_copied); + nx_packet_release(packet_ptr); + + /* Expected fail: no packet available. */ + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Clear C2D callback function. */ + assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iot_client, + NX_AZURE_IOT_HUB_CLOUD_TO_DEVICE_MESSAGE, + NX_NULL, + NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +static VOID invalid_packet_test() +{ +NX_PACKET *packet_ptr; +UCHAR bytes[2] = {0, 0}; + + assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Put invalid packet to MQTT receive queue. */ + MQTT_CLIENT_GET(&iot_client).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(&iot_client).message_receive_queue_depth = 1; + + /* Simulate callback from MQTT layer. */ + tx_mutex_get(TX_MUTEX_GET(&iot_client), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(&iot_client)), 1); + tx_mutex_put(TX_MUTEX_GET(&iot_client)); + + /* Expected fail: no packet available. */ + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + + assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Put invalid packet to receive header. */ + iot_client.nx_azure_iot_hub_client_c2d_message.message_head = packet_ptr; + + /* Expected fail: no packet available. */ + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); +} + +static VOID wait_timeout_test() +{ +NX_PACKET *packet_ptr; +ULONG message_payload_length = 10; + + /* Expect fail: no packet available. */ + assert_int_not_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, 1), + NX_AZURE_IOT_SUCCESS); + + /* Put C2D packet to MQTT receive queue. */ + construct_c2d_packet(&packet_ptr, NX_NULL, 0, message_payload, message_payload_length, 0); + MQTT_CLIENT_GET(&iot_client).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(&iot_client).message_receive_queue_depth = 1; + + /* Simulate callback from MQTT layer. */ + tx_mutex_get(TX_MUTEX_GET(&iot_client), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(&iot_client)), 1); + tx_mutex_put(TX_MUTEX_GET(&iot_client)); + + /* Receive packet by API. */ + assert_int_equal(nx_azure_iot_hub_client_cloud_message_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + nx_packet_release(packet_ptr); +} + +static VOID no_receiver_test() +{ +NX_PACKET *packet_ptr; +ULONG message_payload_length = 10; + + /* Put C2D packet to MQTT receive queue. */ + construct_c2d_packet(&packet_ptr, NX_NULL, 0, message_payload, message_payload_length, 0); + MQTT_CLIENT_GET(&iot_client).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(&iot_client).message_receive_queue_depth = 1; + + /* Simulate callback from MQTT layer. */ + tx_mutex_get(TX_MUTEX_GET(&iot_client), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(&iot_client)), 1); + tx_mutex_put(TX_MUTEX_GET(&iot_client)); + + /* No one will receive this packet. Packet leak will be checked at last step of test. */ +} + +static VOID c2d_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *args) +{ + function_called(); + assert_ptr_equal(hub_client_ptr, &iot_client); + assert_int_equal(*(ULONG *)args, CALLBACK_ARGS); +} + +UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr, + VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count)) +{ + printf("HIJACKED: %s\n", __func__); + test_receive_notify = receive_notify; + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_subscribe(NXD_MQTT_CLIENT *client_ptr, UINT op, + CHAR *topic_name, UINT topic_name_length, + USHORT *packet_id_ptr, UINT QoS) +{ + printf("HIJACKED: %s\n", __func__); + return((UINT)mock()); +} + +UINT __wrap__nxde_mqtt_client_unsubscribe(NXD_MQTT_CLIENT *client_ptr, CHAR *topic_name, + UINT topic_name_length, UINT QoS) +{ + printf("HIJACKED: %s\n", __func__); + return((UINT)mock()); +} + +UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, + UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *, + NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *), + UINT keepalive, UINT clean_session, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + + tx_thread_suspend(&(iot.nx_azure_iot_ip_ptr -> nx_ip_thread)); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + client_ptr -> nxd_mqtt_client_packet_identifier = 1; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_FALSE; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &client_ptr -> nxd_mqtt_client_socket; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr) +{ + printf("HIJACKED: %s\n", __func__); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ + printf("HIJACKED: %s\n", __func__); + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NX_DNS_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} diff --git a/test/regression/azure_iot/connection_non_block_ram_test.c b/test/regression/azure_iot/connection_non_block_ram_test.c new file mode 100644 index 00000000..dca03de5 --- /dev/null +++ b/test/regression/azure_iot/connection_non_block_ram_test.c @@ -0,0 +1,499 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (3) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +static void mqtt_server_init(NX_IP *ip_ptr); +static void mqtt_server_accept(NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr); +static void mqtt_server_deinit(NX_IP *ip_ptr); +void connection_status_cb(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr, UINT status); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; + +static UINT connection_status = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED; + +/* Define server side data. */ +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_certificate; +static NX_TCP_SOCKET server_socket; +static UCHAR server_metadata_buffer[16 * 1024]; +static UCHAR server_tls_packet_buffer[4096]; + +static unsigned char server_cert_der[] = { + 0x30, 0x82, 0x03, 0xd2, 0x30, 0x82, 0x02, 0xba, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7a, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x53, 0x61, + 0x6e, 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x31, 0x14, 0x30, 0x12, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x65, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x13, 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, + 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, + 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x31, 0x31, 0x31, 0x31, 0x39, 0x35, + 0x31, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x31, 0x31, 0x30, 0x39, + 0x31, 0x39, 0x35, 0x31, 0x30, 0x30, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45, 0x78, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x31, + 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x4e, 0x65, + 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x77, 0x77, 0x2e, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, + 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, + 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xae, 0x03, 0x2c, 0xec, + 0xa2, 0x79, 0xd1, 0x15, 0x20, 0x88, 0x4d, 0xcd, 0xa2, 0x1b, 0x05, 0xe3, + 0xbd, 0x55, 0xad, 0xc6, 0x1f, 0x64, 0xe8, 0xb5, 0xc5, 0x0d, 0x67, 0xfc, + 0x7e, 0xda, 0xfb, 0x70, 0xf6, 0xc9, 0x47, 0x87, 0x3a, 0xaa, 0x88, 0x00, + 0xf1, 0xa7, 0xf7, 0xe1, 0xf5, 0x2c, 0x54, 0x0e, 0x33, 0xda, 0xbe, 0x9c, + 0x66, 0x30, 0xd9, 0x40, 0xeb, 0x1d, 0xce, 0xe1, 0x55, 0x15, 0x2b, 0x11, + 0x47, 0x6c, 0x7e, 0x88, 0xc6, 0x24, 0xcf, 0x87, 0x1b, 0xb5, 0x1f, 0x47, + 0xb9, 0xef, 0xad, 0x29, 0xd3, 0x2e, 0x43, 0xee, 0x39, 0xdd, 0x09, 0x54, + 0xba, 0xfc, 0xed, 0xbc, 0x2e, 0x0e, 0x53, 0x15, 0x37, 0xcb, 0xc5, 0xf5, + 0xee, 0x70, 0x2a, 0xe8, 0x01, 0x6d, 0xb1, 0x39, 0x94, 0x5a, 0xc2, 0x8a, + 0x00, 0x04, 0xa9, 0xff, 0xea, 0x56, 0xf7, 0xd7, 0xa8, 0x1b, 0xa4, 0x26, + 0xcd, 0x28, 0xaf, 0xfa, 0x52, 0x85, 0x1c, 0x26, 0x3e, 0x5e, 0x01, 0xf7, + 0xe1, 0x66, 0xff, 0xac, 0xad, 0x9c, 0x98, 0x2f, 0xe0, 0x7e, 0x9f, 0xf1, + 0x33, 0x31, 0xc3, 0x7f, 0xe6, 0x58, 0x5d, 0xd8, 0x5f, 0x7d, 0x2b, 0x5a, + 0x55, 0xcf, 0xb1, 0x91, 0x53, 0x41, 0x04, 0xac, 0x86, 0x5e, 0x01, 0x35, + 0x2b, 0x74, 0x8d, 0x46, 0x4d, 0x48, 0xc0, 0x5f, 0x83, 0x67, 0xb5, 0x6d, + 0x52, 0x3f, 0x3e, 0xe6, 0xec, 0xf8, 0x2e, 0x10, 0x28, 0xdb, 0x69, 0xa6, + 0x9d, 0x4b, 0xde, 0x19, 0x2e, 0xd2, 0x5f, 0xc8, 0xa9, 0x3b, 0x52, 0xe9, + 0xb2, 0xcd, 0x6e, 0x19, 0x22, 0xf9, 0x99, 0xa6, 0xcc, 0xf5, 0xd3, 0xec, + 0xff, 0x0c, 0x77, 0x6f, 0x25, 0x92, 0x07, 0x4c, 0x64, 0x7d, 0x34, 0x49, + 0x6f, 0xff, 0x0a, 0xa8, 0x15, 0x64, 0x72, 0x2d, 0x4f, 0x42, 0x05, 0xe8, + 0x2b, 0x01, 0xf1, 0xe3, 0x65, 0x94, 0x23, 0xd9, 0xdf, 0x5e, 0x3b, 0xb5, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x7b, 0x30, 0x79, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x2c, 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x1f, 0x16, + 0x1d, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53, 0x4c, 0x20, 0x47, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, + 0x0e, 0x04, 0x16, 0x04, 0x14, 0x8d, 0xb0, 0xee, 0x8f, 0x6b, 0x43, 0x52, + 0x29, 0xf4, 0x25, 0xff, 0x3c, 0xda, 0x5f, 0xb3, 0xce, 0x9b, 0x7b, 0x75, + 0xe1, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x1b, 0x8d, 0x06, 0xd9, 0x6b, 0xad, 0xee, 0x82, 0x24, 0x26, + 0x55, 0x9a, 0x1b, 0x03, 0x44, 0x92, 0x0a, 0x06, 0x92, 0x48, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x75, 0x83, 0x89, 0xab, 0x84, 0x52, + 0x5f, 0xa4, 0x9e, 0x98, 0xca, 0xa3, 0xf9, 0xab, 0xd4, 0x04, 0x32, 0xa4, + 0x8c, 0x96, 0x90, 0x39, 0x88, 0x92, 0xc3, 0xcd, 0x51, 0xc3, 0x01, 0x35, + 0x03, 0x78, 0xfa, 0x0d, 0x1e, 0x7b, 0x79, 0xe9, 0x7d, 0xd8, 0x68, 0x7a, + 0x65, 0xc6, 0x00, 0x7c, 0xa1, 0x7a, 0x52, 0xc9, 0xa3, 0xf4, 0x0b, 0xbd, + 0x76, 0x24, 0xdf, 0xde, 0x22, 0x2d, 0x95, 0xc5, 0xb6, 0x54, 0xb1, 0xac, + 0xb6, 0x9a, 0xe4, 0x68, 0x0f, 0x97, 0x4a, 0x44, 0xa2, 0x87, 0x01, 0x82, + 0xd4, 0x25, 0xbd, 0x01, 0xbc, 0x35, 0x8a, 0x6d, 0xb7, 0x7c, 0x48, 0xaa, + 0x92, 0xd7, 0x57, 0x76, 0x6a, 0xb0, 0xc9, 0x46, 0xa6, 0xbe, 0xbf, 0x0f, + 0xf0, 0xea, 0x62, 0x57, 0x71, 0x42, 0xf6, 0x67, 0xa7, 0xa1, 0x50, 0x87, + 0x14, 0x8e, 0x32, 0xd0, 0x5e, 0xc9, 0x7b, 0x79, 0x7e, 0xfa, 0x17, 0xc7, + 0xad, 0xbd, 0xc3, 0x98, 0x79, 0x45, 0xfb, 0x7f, 0xf7, 0xe6, 0x9f, 0x77, + 0xb3, 0x44, 0xc3, 0xaf, 0x6b, 0x61, 0x6a, 0x04, 0x68, 0x24, 0x2d, 0x31, + 0xf1, 0x28, 0x2c, 0xf4, 0xf0, 0x07, 0xfe, 0xfd, 0x66, 0x98, 0x77, 0x37, + 0x7b, 0x80, 0x1f, 0xb2, 0x49, 0xe4, 0xa6, 0x24, 0x72, 0x42, 0xf4, 0xca, + 0x91, 0x80, 0xa1, 0xb2, 0x0a, 0xc9, 0xc0, 0x93, 0xa7, 0x22, 0x0b, 0x13, + 0x8a, 0xb2, 0x75, 0x4b, 0x66, 0xf9, 0x87, 0x3a, 0x51, 0x97, 0xc7, 0x1e, + 0x2b, 0x61, 0x81, 0x5c, 0xf0, 0xf8, 0x4c, 0xdb, 0x36, 0xc7, 0xba, 0x49, + 0xd9, 0x04, 0x6a, 0x95, 0xb0, 0x7f, 0xfc, 0xce, 0xca, 0x23, 0xad, 0xf9, + 0xaf, 0x8a, 0x72, 0x8e, 0xab, 0xb8, 0x8b, 0x7e, 0xf7, 0x39, 0xa6, 0x22, + 0x56, 0x03, 0x72, 0x06, 0xc3, 0x57, 0x1f, 0x32, 0xaa, 0xb5, 0xa6, 0x00, + 0x67, 0x88, 0x4b, 0x40, 0xe9, 0x5e, 0x4a, 0x6f, 0x76, 0xe8 +}; + +static unsigned char server_cert_key_der[] = { + 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xae, 0x03, 0x2c, 0xec, 0xa2, 0x79, 0xd1, 0x15, 0x20, 0x88, 0x4d, 0xcd, + 0xa2, 0x1b, 0x05, 0xe3, 0xbd, 0x55, 0xad, 0xc6, 0x1f, 0x64, 0xe8, 0xb5, + 0xc5, 0x0d, 0x67, 0xfc, 0x7e, 0xda, 0xfb, 0x70, 0xf6, 0xc9, 0x47, 0x87, + 0x3a, 0xaa, 0x88, 0x00, 0xf1, 0xa7, 0xf7, 0xe1, 0xf5, 0x2c, 0x54, 0x0e, + 0x33, 0xda, 0xbe, 0x9c, 0x66, 0x30, 0xd9, 0x40, 0xeb, 0x1d, 0xce, 0xe1, + 0x55, 0x15, 0x2b, 0x11, 0x47, 0x6c, 0x7e, 0x88, 0xc6, 0x24, 0xcf, 0x87, + 0x1b, 0xb5, 0x1f, 0x47, 0xb9, 0xef, 0xad, 0x29, 0xd3, 0x2e, 0x43, 0xee, + 0x39, 0xdd, 0x09, 0x54, 0xba, 0xfc, 0xed, 0xbc, 0x2e, 0x0e, 0x53, 0x15, + 0x37, 0xcb, 0xc5, 0xf5, 0xee, 0x70, 0x2a, 0xe8, 0x01, 0x6d, 0xb1, 0x39, + 0x94, 0x5a, 0xc2, 0x8a, 0x00, 0x04, 0xa9, 0xff, 0xea, 0x56, 0xf7, 0xd7, + 0xa8, 0x1b, 0xa4, 0x26, 0xcd, 0x28, 0xaf, 0xfa, 0x52, 0x85, 0x1c, 0x26, + 0x3e, 0x5e, 0x01, 0xf7, 0xe1, 0x66, 0xff, 0xac, 0xad, 0x9c, 0x98, 0x2f, + 0xe0, 0x7e, 0x9f, 0xf1, 0x33, 0x31, 0xc3, 0x7f, 0xe6, 0x58, 0x5d, 0xd8, + 0x5f, 0x7d, 0x2b, 0x5a, 0x55, 0xcf, 0xb1, 0x91, 0x53, 0x41, 0x04, 0xac, + 0x86, 0x5e, 0x01, 0x35, 0x2b, 0x74, 0x8d, 0x46, 0x4d, 0x48, 0xc0, 0x5f, + 0x83, 0x67, 0xb5, 0x6d, 0x52, 0x3f, 0x3e, 0xe6, 0xec, 0xf8, 0x2e, 0x10, + 0x28, 0xdb, 0x69, 0xa6, 0x9d, 0x4b, 0xde, 0x19, 0x2e, 0xd2, 0x5f, 0xc8, + 0xa9, 0x3b, 0x52, 0xe9, 0xb2, 0xcd, 0x6e, 0x19, 0x22, 0xf9, 0x99, 0xa6, + 0xcc, 0xf5, 0xd3, 0xec, 0xff, 0x0c, 0x77, 0x6f, 0x25, 0x92, 0x07, 0x4c, + 0x64, 0x7d, 0x34, 0x49, 0x6f, 0xff, 0x0a, 0xa8, 0x15, 0x64, 0x72, 0x2d, + 0x4f, 0x42, 0x05, 0xe8, 0x2b, 0x01, 0xf1, 0xe3, 0x65, 0x94, 0x23, 0xd9, + 0xdf, 0x5e, 0x3b, 0xb5, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xa5, 0x22, 0x2c, 0x52, 0xd0, 0x09, 0x4c, 0x4a, 0x81, 0x59, + 0xf8, 0x83, 0xa9, 0x4f, 0x7d, 0xb2, 0x56, 0xad, 0xe5, 0x3f, 0xfb, 0xf0, + 0xf6, 0x09, 0xf1, 0x5b, 0x3c, 0x90, 0x58, 0x0e, 0x15, 0xc9, 0x68, 0xd9, + 0x30, 0x40, 0xfb, 0x82, 0x73, 0x98, 0x79, 0xbb, 0xcd, 0xb8, 0x27, 0xc3, + 0x8e, 0x6c, 0xff, 0xf6, 0x99, 0x26, 0xb0, 0xaf, 0xb0, 0xac, 0x33, 0xb3, + 0x50, 0xed, 0x73, 0xa1, 0xa8, 0x02, 0x38, 0xc6, 0x93, 0xf9, 0xd6, 0x17, + 0x7e, 0xbd, 0x97, 0xa4, 0xb5, 0x6f, 0x8a, 0xdb, 0x11, 0x78, 0x7c, 0x89, + 0x0e, 0x3c, 0x17, 0xbb, 0x54, 0x2c, 0x8d, 0x5a, 0x93, 0x7d, 0x1e, 0x33, + 0xc7, 0xd2, 0x7d, 0xe5, 0xaa, 0x12, 0x2d, 0xd9, 0x52, 0x4e, 0x63, 0x74, + 0xa6, 0x57, 0x9f, 0x1a, 0xd6, 0x3c, 0xc1, 0xb1, 0xab, 0x66, 0x4a, 0x0b, + 0x88, 0x1d, 0xa6, 0xd1, 0xbc, 0x60, 0x7a, 0x17, 0x1f, 0x8f, 0x9b, 0x35, + 0x57, 0xf8, 0xd0, 0x1c, 0xd3, 0xa6, 0x56, 0xc8, 0x03, 0x9c, 0x08, 0x3b, + 0x1b, 0x5b, 0xc2, 0x03, 0x3b, 0x3a, 0xa4, 0xe8, 0xed, 0x75, 0x66, 0xb0, + 0x85, 0x56, 0x40, 0xfe, 0xae, 0x97, 0x7e, 0xc0, 0x79, 0x49, 0x13, 0x8b, + 0x01, 0x0c, 0xae, 0x4c, 0x3d, 0x54, 0x47, 0xc5, 0x51, 0x40, 0x3d, 0xcc, + 0x4d, 0x17, 0xb3, 0x4e, 0x1d, 0x85, 0x1c, 0x41, 0x07, 0x03, 0x5e, 0xf9, + 0xfa, 0x17, 0x81, 0x24, 0x34, 0xaa, 0xbf, 0x67, 0x73, 0xb6, 0x9c, 0x67, + 0x36, 0xd9, 0xee, 0xf7, 0x86, 0x4c, 0x4d, 0x79, 0xca, 0xd7, 0xfd, 0x72, + 0xf9, 0xb3, 0x73, 0xc3, 0x57, 0xe5, 0x39, 0x72, 0x93, 0x56, 0xc2, 0xec, + 0xf8, 0x25, 0xe4, 0x8f, 0xba, 0xd0, 0x6f, 0x23, 0x8c, 0x39, 0x9e, 0x05, + 0x1a, 0x4e, 0xdc, 0x5e, 0xcd, 0x17, 0x59, 0x94, 0x37, 0x22, 0xb7, 0x39, + 0x50, 0x65, 0xdc, 0x91, 0x3c, 0xe1, 0x02, 0x81, 0x81, 0x00, 0xe4, 0xc6, + 0x42, 0xe5, 0xea, 0xe5, 0x32, 0xf3, 0x51, 0x36, 0x7b, 0x8c, 0x5b, 0x72, + 0x24, 0x1a, 0x4a, 0x44, 0x4f, 0x64, 0xe5, 0xa7, 0x74, 0xd9, 0xb2, 0x29, + 0x8a, 0x08, 0xcf, 0x9b, 0xd2, 0x9d, 0xc4, 0x20, 0x4c, 0xd3, 0x60, 0x4d, + 0xf7, 0xb7, 0xac, 0x92, 0x6b, 0x2b, 0x95, 0x73, 0x6e, 0x57, 0x00, 0x20, + 0x9d, 0xb2, 0xf6, 0xbd, 0x0b, 0xbb, 0xaa, 0x7e, 0x7e, 0x3e, 0x53, 0xfb, + 0x79, 0x7e, 0x45, 0xd5, 0x2e, 0xab, 0x5e, 0xff, 0x5c, 0x0a, 0x45, 0x2d, + 0x27, 0x19, 0xb0, 0x59, 0x0a, 0x39, 0x89, 0xf6, 0xae, 0xc6, 0xe2, 0xd1, + 0x07, 0x58, 0xbe, 0x95, 0x27, 0xaf, 0xf7, 0xa6, 0x2f, 0xaa, 0x37, 0x25, + 0x7c, 0x7b, 0xd3, 0xda, 0x13, 0x76, 0x0a, 0xb6, 0x6c, 0x99, 0x53, 0x5d, + 0xa5, 0x75, 0xfa, 0x10, 0x9b, 0x7f, 0xfe, 0xd7, 0xb4, 0x18, 0x95, 0xa8, + 0x65, 0x85, 0x07, 0xc5, 0xc4, 0xad, 0x02, 0x81, 0x81, 0x00, 0xc2, 0xb8, + 0x8e, 0xed, 0x9d, 0x4a, 0x1f, 0x9c, 0xda, 0x73, 0xf0, 0x2c, 0x35, 0x91, + 0xe4, 0x40, 0x78, 0xe1, 0x12, 0xf3, 0x08, 0xef, 0xdf, 0x97, 0xa0, 0xb0, + 0xdd, 0xea, 0xc2, 0xb9, 0x5b, 0xf8, 0xa1, 0xac, 0x32, 0xfd, 0xb8, 0xe9, + 0x0f, 0xed, 0xfd, 0xe0, 0xdc, 0x38, 0x90, 0x5e, 0xf5, 0x4c, 0x02, 0xc3, + 0x1a, 0x72, 0x18, 0xf7, 0xfe, 0xb7, 0xb8, 0x2a, 0xf8, 0x72, 0xbb, 0x99, + 0x56, 0xec, 0x85, 0x58, 0x31, 0x7e, 0x64, 0xdf, 0x02, 0x05, 0xe3, 0xb2, + 0xbb, 0xe2, 0x1b, 0xd6, 0x43, 0x73, 0xf8, 0x0f, 0xaf, 0x89, 0x57, 0x44, + 0x5f, 0x30, 0x1c, 0xe5, 0x78, 0xbf, 0x0b, 0xe7, 0x4b, 0xbe, 0x80, 0x2f, + 0x3d, 0x35, 0x44, 0xfc, 0x9e, 0x0d, 0x85, 0x5d, 0x94, 0x6e, 0xe9, 0x6a, + 0x72, 0xa7, 0x46, 0xd8, 0x64, 0x6c, 0xe9, 0x61, 0x92, 0xa0, 0xb6, 0xd1, + 0xee, 0xa6, 0xa6, 0xf4, 0x2c, 0x29, 0x02, 0x81, 0x81, 0x00, 0xb4, 0xa7, + 0x7b, 0x1c, 0x64, 0x29, 0x29, 0xda, 0xca, 0x3e, 0xe3, 0xc1, 0x2a, 0x55, + 0x2f, 0xfd, 0x32, 0xb8, 0x4e, 0x99, 0xb6, 0x60, 0x4d, 0xfd, 0xba, 0x9a, + 0xe2, 0xcd, 0xa2, 0x63, 0xc2, 0x25, 0xa3, 0x42, 0x7e, 0x68, 0x4c, 0x9c, + 0x45, 0x09, 0x5d, 0xd5, 0x21, 0x9c, 0x01, 0x20, 0x6d, 0xf9, 0x75, 0xb8, + 0x4b, 0xcf, 0x8e, 0xd8, 0x29, 0xf3, 0xbf, 0xe6, 0xb3, 0x7a, 0x34, 0x87, + 0x58, 0xa1, 0x46, 0x33, 0xd9, 0xee, 0xa9, 0xcd, 0xac, 0xb8, 0xcf, 0x77, + 0xa0, 0x70, 0xc0, 0xb9, 0x0f, 0x41, 0xf0, 0x98, 0x43, 0xdb, 0xfa, 0x30, + 0x66, 0x44, 0xc5, 0xfa, 0xb2, 0xa4, 0x5a, 0x43, 0x79, 0x50, 0x48, 0xcb, + 0xe9, 0x49, 0x3f, 0x39, 0xee, 0x34, 0x40, 0xb1, 0x5d, 0x80, 0x96, 0x3c, + 0x54, 0xf4, 0x9c, 0xcb, 0x90, 0x7f, 0xba, 0x96, 0x4b, 0x39, 0x3e, 0xb5, + 0x03, 0xb5, 0xd1, 0x35, 0x72, 0xe1, 0x02, 0x81, 0x80, 0x60, 0x14, 0xd5, + 0x61, 0xe6, 0x24, 0xf7, 0x28, 0x5c, 0x9a, 0xac, 0xbe, 0x03, 0xc8, 0xf3, + 0x49, 0xe4, 0xdb, 0x9a, 0x90, 0x15, 0xae, 0xd7, 0x33, 0x68, 0x75, 0x1d, + 0x6b, 0x83, 0x9e, 0x17, 0x05, 0xbe, 0x30, 0xcc, 0x10, 0x6a, 0x37, 0x86, + 0x46, 0xb6, 0xe9, 0x47, 0x81, 0x19, 0xab, 0xe1, 0x7a, 0x1a, 0x3a, 0xcf, + 0x47, 0xd1, 0x8e, 0x3d, 0x3f, 0xc6, 0x3e, 0x5d, 0xcd, 0xaf, 0x47, 0xe0, + 0x9e, 0x60, 0xc5, 0xbd, 0xd6, 0x52, 0x4b, 0xc0, 0x21, 0xcb, 0xd3, 0x1b, + 0xe6, 0x5c, 0x3a, 0x03, 0x9a, 0xab, 0xa2, 0x81, 0xc9, 0x51, 0x28, 0x49, + 0x97, 0xe2, 0x0a, 0x50, 0xe4, 0x64, 0x29, 0x43, 0x34, 0xc2, 0xe7, 0x8c, + 0x5a, 0x46, 0xaa, 0x28, 0x0b, 0x1f, 0xed, 0xa7, 0x1a, 0x7b, 0x4e, 0xad, + 0x38, 0x61, 0x3a, 0xd1, 0x82, 0xf4, 0x3d, 0xd3, 0x2e, 0x3e, 0x47, 0xa4, + 0x6c, 0xd3, 0x20, 0xd4, 0xd1, 0x02, 0x81, 0x80, 0x68, 0x1a, 0x8d, 0x3c, + 0x18, 0x3f, 0x42, 0x5e, 0x38, 0x6d, 0x0a, 0x1e, 0x52, 0xd5, 0x8f, 0xd6, + 0x32, 0xff, 0x7c, 0x1c, 0xf3, 0x20, 0x8b, 0x92, 0xa5, 0x44, 0xff, 0x08, + 0x21, 0xa1, 0xce, 0x68, 0x8b, 0x03, 0xe0, 0x90, 0xeb, 0x01, 0x4e, 0x85, + 0xf9, 0xc5, 0xb7, 0x86, 0xee, 0xd0, 0x59, 0x10, 0x73, 0x98, 0x2a, 0xcb, + 0xf6, 0xfe, 0x0d, 0xba, 0x07, 0x91, 0x18, 0xf6, 0xbc, 0x93, 0x8a, 0x91, + 0xdd, 0x80, 0x16, 0x37, 0xdf, 0x75, 0x46, 0x87, 0x68, 0xee, 0xf4, 0x76, + 0x0c, 0xc5, 0x87, 0x38, 0xf5, 0xb6, 0xda, 0x8a, 0xee, 0x62, 0xc8, 0xc0, + 0xa2, 0x8d, 0xbf, 0xd5, 0xf8, 0xba, 0xb5, 0x74, 0xf0, 0x07, 0xa6, 0x1c, + 0xcf, 0x76, 0x61, 0xbe, 0xa4, 0x88, 0x4a, 0x95, 0xb0, 0xa3, 0x70, 0x73, + 0xa1, 0x6f, 0x73, 0xf0, 0xe8, 0x38, 0x8d, 0xe8, 0xd0, 0x7e, 0x2c, 0x0c, + 0xdc, 0x21, 0xfa, 0xc1 +}; + +static unsigned char ca_cert_der[] = { + 0x30, 0x82, 0x03, 0xc7, 0x30, 0x82, 0x02, 0xaf, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0xa1, 0x79, 0xb0, 0x6a, 0x32, 0xbc, 0x48, 0x67, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x05, 0x00, 0x30, 0x7a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x12, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x53, 0x61, 0x6e, 0x20, 0x44, 0x69, + 0x65, 0x67, 0x6f, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x0d, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, + 0x67, 0x69, 0x63, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x0b, 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x65, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, + 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, + 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x36, 0x31, 0x31, 0x31, 0x31, 0x31, 0x39, 0x35, 0x30, 0x30, 0x38, 0x5a, + 0x17, 0x0d, 0x32, 0x36, 0x31, 0x31, 0x30, 0x39, 0x31, 0x39, 0x35, 0x30, + 0x30, 0x38, 0x5a, 0x30, 0x7a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x12, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x53, 0x61, 0x6e, 0x20, 0x44, 0x69, + 0x65, 0x67, 0x6f, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x0d, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, + 0x67, 0x69, 0x63, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x0b, 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x65, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, + 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, + 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xd1, 0xdc, 0x3c, 0xe1, 0x1c, 0x7a, 0x3d, 0xb7, + 0x76, 0xcf, 0xab, 0xd7, 0x3c, 0x38, 0xb0, 0x81, 0xb6, 0x37, 0x52, 0xa3, + 0x3d, 0x6f, 0xcd, 0x89, 0xa6, 0xa2, 0xf3, 0xa8, 0xb0, 0x8d, 0xee, 0x0b, + 0x36, 0x94, 0x83, 0x0e, 0x7f, 0x39, 0x87, 0x6e, 0xee, 0x19, 0xe2, 0x1f, + 0x92, 0x3d, 0x01, 0x05, 0x4f, 0x11, 0xcd, 0xcb, 0xa0, 0x79, 0xfc, 0x9d, + 0x6e, 0x93, 0xb1, 0xb7, 0x03, 0xf3, 0xfe, 0xeb, 0x30, 0x67, 0x38, 0x85, + 0x28, 0xdf, 0x93, 0xdb, 0xcb, 0xcb, 0xb1, 0xbe, 0xd3, 0xe1, 0xc2, 0x7d, + 0x8d, 0xbb, 0x70, 0x76, 0x99, 0x08, 0x7c, 0x3f, 0x21, 0x2f, 0x37, 0x97, + 0xf7, 0xe8, 0x6e, 0x8c, 0x7e, 0xbc, 0x30, 0x5f, 0xbf, 0x32, 0x51, 0x1d, + 0x66, 0x76, 0xad, 0x39, 0xfc, 0x94, 0xd4, 0x65, 0xf6, 0xd2, 0x0b, 0x37, + 0xd3, 0x4a, 0xe6, 0xe1, 0xdf, 0x4a, 0x8f, 0x3b, 0x33, 0x16, 0xbe, 0xf7, + 0xd9, 0xbd, 0x73, 0x64, 0xdf, 0x34, 0xa3, 0x55, 0xe7, 0xac, 0xab, 0xa7, + 0xae, 0xc2, 0x20, 0x46, 0xc2, 0xd1, 0xe3, 0x25, 0x3a, 0x47, 0x68, 0x92, + 0xac, 0xd6, 0x12, 0xa4, 0x0a, 0xce, 0xdc, 0xe2, 0x24, 0x12, 0xee, 0xe1, + 0xb2, 0xcd, 0x09, 0xa8, 0xef, 0x36, 0xea, 0x76, 0xf9, 0xb6, 0x63, 0xaa, + 0xac, 0xdd, 0x46, 0x06, 0x6e, 0xd9, 0x1e, 0x08, 0xac, 0x57, 0x12, 0x6c, + 0x21, 0xef, 0x8e, 0xae, 0xf0, 0x27, 0xf1, 0x5c, 0x79, 0xb4, 0xb6, 0x26, + 0x92, 0x11, 0xda, 0xca, 0x80, 0x5e, 0x92, 0x4c, 0xb5, 0xd8, 0xb5, 0x84, + 0x95, 0xe3, 0xef, 0xbc, 0x7e, 0x7d, 0x68, 0x74, 0x4c, 0x34, 0x1a, 0x50, + 0x6d, 0x2d, 0x5f, 0x1b, 0x0e, 0xbe, 0xf5, 0xb4, 0xf1, 0x32, 0x16, 0x44, + 0x24, 0x7a, 0x0e, 0x4b, 0xcd, 0xfa, 0xa5, 0x03, 0x95, 0x2e, 0x44, 0x65, + 0xa8, 0x74, 0xea, 0x17, 0xdd, 0x99, 0xbd, 0xcb, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x1b, 0x8d, 0x06, 0xd9, 0x6b, 0xad, 0xee, 0x82, + 0x24, 0x26, 0x55, 0x9a, 0x1b, 0x03, 0x44, 0x92, 0x0a, 0x06, 0x92, 0x48, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, + 0x14, 0x1b, 0x8d, 0x06, 0xd9, 0x6b, 0xad, 0xee, 0x82, 0x24, 0x26, 0x55, + 0x9a, 0x1b, 0x03, 0x44, 0x92, 0x0a, 0x06, 0x92, 0x48, 0x30, 0x0c, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x70, 0xc7, 0x6a, 0x75, 0x27, + 0x14, 0xa0, 0x1c, 0xe0, 0xe0, 0x84, 0x7c, 0x6c, 0x16, 0xa9, 0x0d, 0x4d, + 0xb1, 0xc3, 0x87, 0x37, 0xf6, 0x86, 0x89, 0x6f, 0x73, 0xf0, 0x59, 0x9b, + 0x8c, 0xa4, 0x83, 0x10, 0x2d, 0xb7, 0x8b, 0xd0, 0x9a, 0x81, 0xe0, 0x5c, + 0xd7, 0x20, 0x6f, 0xdc, 0xfc, 0xc8, 0xa0, 0xc2, 0x8e, 0x54, 0xe6, 0xfb, + 0x61, 0x85, 0x37, 0x4b, 0x22, 0x47, 0x09, 0x95, 0x44, 0x12, 0x75, 0xf0, + 0xcf, 0x0b, 0x90, 0x48, 0xb0, 0x02, 0x4c, 0xef, 0x3f, 0xde, 0x6a, 0xfd, + 0xb1, 0x8b, 0x88, 0xd7, 0x84, 0xe5, 0x34, 0x02, 0x96, 0x0a, 0x3f, 0xa8, + 0x8c, 0xbd, 0x1a, 0xd8, 0xf7, 0xf9, 0xe5, 0x49, 0x87, 0xd0, 0x20, 0x4f, + 0xd8, 0xcd, 0xc0, 0xb9, 0x11, 0x2a, 0xd9, 0x0f, 0x75, 0xa6, 0xee, 0x76, + 0x15, 0x9f, 0x12, 0x50, 0x68, 0x4c, 0xc0, 0x05, 0x46, 0x8d, 0xdd, 0x93, + 0x74, 0x31, 0x82, 0x20, 0x37, 0x24, 0x58, 0xb2, 0x88, 0x9b, 0x21, 0xc1, + 0x48, 0xc4, 0x8d, 0x68, 0x3b, 0x91, 0x2c, 0x34, 0xcb, 0x94, 0xd0, 0xbc, + 0xe3, 0x05, 0x24, 0x05, 0xcc, 0xea, 0x05, 0xb1, 0x52, 0x74, 0x4a, 0x23, + 0x65, 0xc4, 0x40, 0x04, 0x86, 0xb1, 0x80, 0x61, 0x97, 0xdc, 0x94, 0x16, + 0x4e, 0x63, 0x31, 0x72, 0x4e, 0x45, 0xe8, 0x3e, 0x3b, 0xb6, 0x99, 0xae, + 0xd8, 0x91, 0x25, 0x3d, 0x62, 0x92, 0x6d, 0x72, 0x01, 0x2c, 0xca, 0x67, + 0x0a, 0xec, 0x00, 0xeb, 0x10, 0xff, 0x6d, 0xac, 0x89, 0x19, 0x2c, 0xb7, + 0xb3, 0xa5, 0xf7, 0xa1, 0x4a, 0xc3, 0xc1, 0xdd, 0xaf, 0xb5, 0x1a, 0x16, + 0x44, 0xdc, 0xa8, 0xb5, 0xca, 0xd0, 0x30, 0xaa, 0x7e, 0x73, 0xd5, 0x2e, + 0x65, 0xd6, 0xf9, 0xbf, 0x5f, 0xda, 0x6f, 0x13, 0xe9, 0xd7, 0x12, 0x6c, + 0x3a, 0x6c, 0x50, 0x26, 0x78, 0x6e, 0xc6, 0xeb, 0x75, 0xe1, 0x3c +}; + +static void mqtt_server_init(NX_IP *ip_ptr); + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ +CHAR *host_name = "www.example.com"; +CHAR *device_id = "device_id"; +CHAR *module_id = "module_id"; +CHAR *symmetric_key = "symmetric_key"; +ULONG pool_ptr_available_packet; + + /* Setup an MQTT server first. */ + mqtt_server_init(ip_ptr); + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)ca_cert_der, sizeof(ca_cert_der), + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* Record number of available packet before test */ + pool_ptr_available_packet = pool_ptr -> nx_packet_pool_available; + + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_connection_status_callback_set(&iot_client, + connection_status_cb), + NX_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_TRUE, NX_NO_WAIT), + NX_AZURE_IOT_CONNECTING); + + /* Establish MQTT connection. */ + mqtt_server_accept(ip_ptr, pool_ptr); + + /* Wait one second for connection. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check connection status. */ + assert_int_equal(connection_status, NX_AZURE_IOT_SUCCESS); + +#if (NX_AZURE_IOT_MQTT_KEEP_ALIVE > 0 && defined(NX_AZURE_DISABLE_IOT_SECURITY_MODULE)) + /* Let keep alive timeout. */ + tx_thread_sleep(NX_AZURE_IOT_MQTT_KEEP_ALIVE * NX_IP_PERIODIC_RATE + NXD_MQTT_PING_TIMEOUT_DELAY + NX_IP_PERIODIC_RATE); + + /* Check connection status. */ + assert_int_equal(connection_status, NX_AZURE_IOT_DISCONNECTED); +#endif + + /* Cleanup MQTT server. */ + mqtt_server_deinit(ip_ptr); + + assert_int_equal(nx_azure_iot_hub_client_disconnect(&iot_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* Check if all the packet are released */ + assert_int_equal(pool_ptr -> nx_packet_pool_available, pool_ptr_available_packet); + + /* SUCCESS: iot is created. */ + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); +} + + +static void mqtt_server_init(NX_IP *ip_ptr) +{ + + /* Create a socket. */ + assert_int_equal(nx_tcp_socket_create(ip_ptr, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL), + NX_SUCCESS); + + /* Setup this thread to listen. */ + assert_int_equal(nx_tcp_server_socket_listen(ip_ptr, NXD_MQTT_TLS_PORT, + &server_socket, 5, NX_NULL), + NX_SUCCESS); + + assert_int_equal(_nx_secure_tls_session_create_ext(&tls_server_session, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + server_metadata_buffer, + sizeof(server_metadata_buffer)), + NX_SUCCESS); + + assert_int_equal(nx_secure_x509_certificate_initialize(&server_certificate, + server_cert_der, sizeof(server_cert_der), + NX_NULL, 0, server_cert_key_der, + sizeof(server_cert_key_der), NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER), + NX_SUCCESS); + + assert_int_equal(nx_secure_tls_local_certificate_add(&tls_server_session, &server_certificate), NX_SUCCESS); + + assert_int_equal(nx_secure_tls_session_packet_buffer_set(&tls_server_session, + server_tls_packet_buffer, + sizeof(server_tls_packet_buffer)), + NX_SUCCESS); +} + +static void mqtt_server_accept(NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr) +{ +NX_PACKET *packet_ptr; +UCHAR *byte; + + /* Accept a connection from client socket. */ + assert_int_equal(nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER), NX_SUCCESS); + assert_int_equal(nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER), NX_SUCCESS); + + /* Receive MQTT CONN. */ + assert_int_equal(nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER), NX_SUCCESS); + assert_int_equal(nx_packet_release(packet_ptr), NX_SUCCESS); + assert_int_equal(nx_secure_tls_packet_allocate(&tls_server_session, pool_ptr, &packet_ptr, NX_WAIT_FOREVER), NX_SUCCESS); + + /* Construct CONNACK packet. */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + /* Send CONNACK packet. */ + assert_int_equal(nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER), NX_SUCCESS); +} + +static void mqtt_server_deinit(NX_IP *ip_ptr) +{ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + nx_tcp_server_socket_unaccept(&server_socket); + nx_secure_tls_session_delete(&tls_server_session); + nx_tcp_server_socket_unlisten(ip_ptr, NXD_MQTT_TLS_PORT); + nx_tcp_socket_delete(&server_socket); +} + +void connection_status_cb(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr, UINT status) +{ + connection_status = status; +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ + printf("HIJACKED: %s\n", __func__); + host_address_ptr -> nxd_ip_version = NX_IP_VERSION_V4; + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NX_SUCCESS); +} diff --git a/test/regression/azure_iot/connection_sas_expiry_ram_test.c b/test/regression/azure_iot/connection_sas_expiry_ram_test.c new file mode 100644 index 00000000..c6fbe218 --- /dev/null +++ b/test/regression/azure_iot/connection_sas_expiry_ram_test.c @@ -0,0 +1,512 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (3) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +static void mqtt_server_init(NX_IP *ip_ptr); +static void mqtt_server_accept(NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr); +static void mqtt_server_deinit(NX_IP *ip_ptr); +void connection_status_cb(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr, UINT status); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; + +static UINT connection_status = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED; + +/* Define server side data. */ +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_certificate; +static NX_TCP_SOCKET server_socket; +static UCHAR server_metadata_buffer[16 * 1024]; +static UCHAR server_tls_packet_buffer[4096]; + +static unsigned char server_cert_der[] = { + 0x30, 0x82, 0x03, 0xd2, 0x30, 0x82, 0x02, 0xba, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7a, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, + 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x53, 0x61, + 0x6e, 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x31, 0x14, 0x30, 0x12, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x65, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x13, 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, + 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, + 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x31, 0x31, 0x31, 0x31, 0x39, 0x35, + 0x31, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x31, 0x31, 0x30, 0x39, + 0x31, 0x39, 0x35, 0x31, 0x30, 0x30, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45, 0x78, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x31, + 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x4e, 0x65, + 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x77, 0x77, 0x77, 0x2e, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, + 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, + 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xae, 0x03, 0x2c, 0xec, + 0xa2, 0x79, 0xd1, 0x15, 0x20, 0x88, 0x4d, 0xcd, 0xa2, 0x1b, 0x05, 0xe3, + 0xbd, 0x55, 0xad, 0xc6, 0x1f, 0x64, 0xe8, 0xb5, 0xc5, 0x0d, 0x67, 0xfc, + 0x7e, 0xda, 0xfb, 0x70, 0xf6, 0xc9, 0x47, 0x87, 0x3a, 0xaa, 0x88, 0x00, + 0xf1, 0xa7, 0xf7, 0xe1, 0xf5, 0x2c, 0x54, 0x0e, 0x33, 0xda, 0xbe, 0x9c, + 0x66, 0x30, 0xd9, 0x40, 0xeb, 0x1d, 0xce, 0xe1, 0x55, 0x15, 0x2b, 0x11, + 0x47, 0x6c, 0x7e, 0x88, 0xc6, 0x24, 0xcf, 0x87, 0x1b, 0xb5, 0x1f, 0x47, + 0xb9, 0xef, 0xad, 0x29, 0xd3, 0x2e, 0x43, 0xee, 0x39, 0xdd, 0x09, 0x54, + 0xba, 0xfc, 0xed, 0xbc, 0x2e, 0x0e, 0x53, 0x15, 0x37, 0xcb, 0xc5, 0xf5, + 0xee, 0x70, 0x2a, 0xe8, 0x01, 0x6d, 0xb1, 0x39, 0x94, 0x5a, 0xc2, 0x8a, + 0x00, 0x04, 0xa9, 0xff, 0xea, 0x56, 0xf7, 0xd7, 0xa8, 0x1b, 0xa4, 0x26, + 0xcd, 0x28, 0xaf, 0xfa, 0x52, 0x85, 0x1c, 0x26, 0x3e, 0x5e, 0x01, 0xf7, + 0xe1, 0x66, 0xff, 0xac, 0xad, 0x9c, 0x98, 0x2f, 0xe0, 0x7e, 0x9f, 0xf1, + 0x33, 0x31, 0xc3, 0x7f, 0xe6, 0x58, 0x5d, 0xd8, 0x5f, 0x7d, 0x2b, 0x5a, + 0x55, 0xcf, 0xb1, 0x91, 0x53, 0x41, 0x04, 0xac, 0x86, 0x5e, 0x01, 0x35, + 0x2b, 0x74, 0x8d, 0x46, 0x4d, 0x48, 0xc0, 0x5f, 0x83, 0x67, 0xb5, 0x6d, + 0x52, 0x3f, 0x3e, 0xe6, 0xec, 0xf8, 0x2e, 0x10, 0x28, 0xdb, 0x69, 0xa6, + 0x9d, 0x4b, 0xde, 0x19, 0x2e, 0xd2, 0x5f, 0xc8, 0xa9, 0x3b, 0x52, 0xe9, + 0xb2, 0xcd, 0x6e, 0x19, 0x22, 0xf9, 0x99, 0xa6, 0xcc, 0xf5, 0xd3, 0xec, + 0xff, 0x0c, 0x77, 0x6f, 0x25, 0x92, 0x07, 0x4c, 0x64, 0x7d, 0x34, 0x49, + 0x6f, 0xff, 0x0a, 0xa8, 0x15, 0x64, 0x72, 0x2d, 0x4f, 0x42, 0x05, 0xe8, + 0x2b, 0x01, 0xf1, 0xe3, 0x65, 0x94, 0x23, 0xd9, 0xdf, 0x5e, 0x3b, 0xb5, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x7b, 0x30, 0x79, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x2c, 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x1f, 0x16, + 0x1d, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53, 0x4c, 0x20, 0x47, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, + 0x0e, 0x04, 0x16, 0x04, 0x14, 0x8d, 0xb0, 0xee, 0x8f, 0x6b, 0x43, 0x52, + 0x29, 0xf4, 0x25, 0xff, 0x3c, 0xda, 0x5f, 0xb3, 0xce, 0x9b, 0x7b, 0x75, + 0xe1, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x1b, 0x8d, 0x06, 0xd9, 0x6b, 0xad, 0xee, 0x82, 0x24, 0x26, + 0x55, 0x9a, 0x1b, 0x03, 0x44, 0x92, 0x0a, 0x06, 0x92, 0x48, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x75, 0x83, 0x89, 0xab, 0x84, 0x52, + 0x5f, 0xa4, 0x9e, 0x98, 0xca, 0xa3, 0xf9, 0xab, 0xd4, 0x04, 0x32, 0xa4, + 0x8c, 0x96, 0x90, 0x39, 0x88, 0x92, 0xc3, 0xcd, 0x51, 0xc3, 0x01, 0x35, + 0x03, 0x78, 0xfa, 0x0d, 0x1e, 0x7b, 0x79, 0xe9, 0x7d, 0xd8, 0x68, 0x7a, + 0x65, 0xc6, 0x00, 0x7c, 0xa1, 0x7a, 0x52, 0xc9, 0xa3, 0xf4, 0x0b, 0xbd, + 0x76, 0x24, 0xdf, 0xde, 0x22, 0x2d, 0x95, 0xc5, 0xb6, 0x54, 0xb1, 0xac, + 0xb6, 0x9a, 0xe4, 0x68, 0x0f, 0x97, 0x4a, 0x44, 0xa2, 0x87, 0x01, 0x82, + 0xd4, 0x25, 0xbd, 0x01, 0xbc, 0x35, 0x8a, 0x6d, 0xb7, 0x7c, 0x48, 0xaa, + 0x92, 0xd7, 0x57, 0x76, 0x6a, 0xb0, 0xc9, 0x46, 0xa6, 0xbe, 0xbf, 0x0f, + 0xf0, 0xea, 0x62, 0x57, 0x71, 0x42, 0xf6, 0x67, 0xa7, 0xa1, 0x50, 0x87, + 0x14, 0x8e, 0x32, 0xd0, 0x5e, 0xc9, 0x7b, 0x79, 0x7e, 0xfa, 0x17, 0xc7, + 0xad, 0xbd, 0xc3, 0x98, 0x79, 0x45, 0xfb, 0x7f, 0xf7, 0xe6, 0x9f, 0x77, + 0xb3, 0x44, 0xc3, 0xaf, 0x6b, 0x61, 0x6a, 0x04, 0x68, 0x24, 0x2d, 0x31, + 0xf1, 0x28, 0x2c, 0xf4, 0xf0, 0x07, 0xfe, 0xfd, 0x66, 0x98, 0x77, 0x37, + 0x7b, 0x80, 0x1f, 0xb2, 0x49, 0xe4, 0xa6, 0x24, 0x72, 0x42, 0xf4, 0xca, + 0x91, 0x80, 0xa1, 0xb2, 0x0a, 0xc9, 0xc0, 0x93, 0xa7, 0x22, 0x0b, 0x13, + 0x8a, 0xb2, 0x75, 0x4b, 0x66, 0xf9, 0x87, 0x3a, 0x51, 0x97, 0xc7, 0x1e, + 0x2b, 0x61, 0x81, 0x5c, 0xf0, 0xf8, 0x4c, 0xdb, 0x36, 0xc7, 0xba, 0x49, + 0xd9, 0x04, 0x6a, 0x95, 0xb0, 0x7f, 0xfc, 0xce, 0xca, 0x23, 0xad, 0xf9, + 0xaf, 0x8a, 0x72, 0x8e, 0xab, 0xb8, 0x8b, 0x7e, 0xf7, 0x39, 0xa6, 0x22, + 0x56, 0x03, 0x72, 0x06, 0xc3, 0x57, 0x1f, 0x32, 0xaa, 0xb5, 0xa6, 0x00, + 0x67, 0x88, 0x4b, 0x40, 0xe9, 0x5e, 0x4a, 0x6f, 0x76, 0xe8 +}; + +static unsigned char server_cert_key_der[] = { + 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xae, 0x03, 0x2c, 0xec, 0xa2, 0x79, 0xd1, 0x15, 0x20, 0x88, 0x4d, 0xcd, + 0xa2, 0x1b, 0x05, 0xe3, 0xbd, 0x55, 0xad, 0xc6, 0x1f, 0x64, 0xe8, 0xb5, + 0xc5, 0x0d, 0x67, 0xfc, 0x7e, 0xda, 0xfb, 0x70, 0xf6, 0xc9, 0x47, 0x87, + 0x3a, 0xaa, 0x88, 0x00, 0xf1, 0xa7, 0xf7, 0xe1, 0xf5, 0x2c, 0x54, 0x0e, + 0x33, 0xda, 0xbe, 0x9c, 0x66, 0x30, 0xd9, 0x40, 0xeb, 0x1d, 0xce, 0xe1, + 0x55, 0x15, 0x2b, 0x11, 0x47, 0x6c, 0x7e, 0x88, 0xc6, 0x24, 0xcf, 0x87, + 0x1b, 0xb5, 0x1f, 0x47, 0xb9, 0xef, 0xad, 0x29, 0xd3, 0x2e, 0x43, 0xee, + 0x39, 0xdd, 0x09, 0x54, 0xba, 0xfc, 0xed, 0xbc, 0x2e, 0x0e, 0x53, 0x15, + 0x37, 0xcb, 0xc5, 0xf5, 0xee, 0x70, 0x2a, 0xe8, 0x01, 0x6d, 0xb1, 0x39, + 0x94, 0x5a, 0xc2, 0x8a, 0x00, 0x04, 0xa9, 0xff, 0xea, 0x56, 0xf7, 0xd7, + 0xa8, 0x1b, 0xa4, 0x26, 0xcd, 0x28, 0xaf, 0xfa, 0x52, 0x85, 0x1c, 0x26, + 0x3e, 0x5e, 0x01, 0xf7, 0xe1, 0x66, 0xff, 0xac, 0xad, 0x9c, 0x98, 0x2f, + 0xe0, 0x7e, 0x9f, 0xf1, 0x33, 0x31, 0xc3, 0x7f, 0xe6, 0x58, 0x5d, 0xd8, + 0x5f, 0x7d, 0x2b, 0x5a, 0x55, 0xcf, 0xb1, 0x91, 0x53, 0x41, 0x04, 0xac, + 0x86, 0x5e, 0x01, 0x35, 0x2b, 0x74, 0x8d, 0x46, 0x4d, 0x48, 0xc0, 0x5f, + 0x83, 0x67, 0xb5, 0x6d, 0x52, 0x3f, 0x3e, 0xe6, 0xec, 0xf8, 0x2e, 0x10, + 0x28, 0xdb, 0x69, 0xa6, 0x9d, 0x4b, 0xde, 0x19, 0x2e, 0xd2, 0x5f, 0xc8, + 0xa9, 0x3b, 0x52, 0xe9, 0xb2, 0xcd, 0x6e, 0x19, 0x22, 0xf9, 0x99, 0xa6, + 0xcc, 0xf5, 0xd3, 0xec, 0xff, 0x0c, 0x77, 0x6f, 0x25, 0x92, 0x07, 0x4c, + 0x64, 0x7d, 0x34, 0x49, 0x6f, 0xff, 0x0a, 0xa8, 0x15, 0x64, 0x72, 0x2d, + 0x4f, 0x42, 0x05, 0xe8, 0x2b, 0x01, 0xf1, 0xe3, 0x65, 0x94, 0x23, 0xd9, + 0xdf, 0x5e, 0x3b, 0xb5, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xa5, 0x22, 0x2c, 0x52, 0xd0, 0x09, 0x4c, 0x4a, 0x81, 0x59, + 0xf8, 0x83, 0xa9, 0x4f, 0x7d, 0xb2, 0x56, 0xad, 0xe5, 0x3f, 0xfb, 0xf0, + 0xf6, 0x09, 0xf1, 0x5b, 0x3c, 0x90, 0x58, 0x0e, 0x15, 0xc9, 0x68, 0xd9, + 0x30, 0x40, 0xfb, 0x82, 0x73, 0x98, 0x79, 0xbb, 0xcd, 0xb8, 0x27, 0xc3, + 0x8e, 0x6c, 0xff, 0xf6, 0x99, 0x26, 0xb0, 0xaf, 0xb0, 0xac, 0x33, 0xb3, + 0x50, 0xed, 0x73, 0xa1, 0xa8, 0x02, 0x38, 0xc6, 0x93, 0xf9, 0xd6, 0x17, + 0x7e, 0xbd, 0x97, 0xa4, 0xb5, 0x6f, 0x8a, 0xdb, 0x11, 0x78, 0x7c, 0x89, + 0x0e, 0x3c, 0x17, 0xbb, 0x54, 0x2c, 0x8d, 0x5a, 0x93, 0x7d, 0x1e, 0x33, + 0xc7, 0xd2, 0x7d, 0xe5, 0xaa, 0x12, 0x2d, 0xd9, 0x52, 0x4e, 0x63, 0x74, + 0xa6, 0x57, 0x9f, 0x1a, 0xd6, 0x3c, 0xc1, 0xb1, 0xab, 0x66, 0x4a, 0x0b, + 0x88, 0x1d, 0xa6, 0xd1, 0xbc, 0x60, 0x7a, 0x17, 0x1f, 0x8f, 0x9b, 0x35, + 0x57, 0xf8, 0xd0, 0x1c, 0xd3, 0xa6, 0x56, 0xc8, 0x03, 0x9c, 0x08, 0x3b, + 0x1b, 0x5b, 0xc2, 0x03, 0x3b, 0x3a, 0xa4, 0xe8, 0xed, 0x75, 0x66, 0xb0, + 0x85, 0x56, 0x40, 0xfe, 0xae, 0x97, 0x7e, 0xc0, 0x79, 0x49, 0x13, 0x8b, + 0x01, 0x0c, 0xae, 0x4c, 0x3d, 0x54, 0x47, 0xc5, 0x51, 0x40, 0x3d, 0xcc, + 0x4d, 0x17, 0xb3, 0x4e, 0x1d, 0x85, 0x1c, 0x41, 0x07, 0x03, 0x5e, 0xf9, + 0xfa, 0x17, 0x81, 0x24, 0x34, 0xaa, 0xbf, 0x67, 0x73, 0xb6, 0x9c, 0x67, + 0x36, 0xd9, 0xee, 0xf7, 0x86, 0x4c, 0x4d, 0x79, 0xca, 0xd7, 0xfd, 0x72, + 0xf9, 0xb3, 0x73, 0xc3, 0x57, 0xe5, 0x39, 0x72, 0x93, 0x56, 0xc2, 0xec, + 0xf8, 0x25, 0xe4, 0x8f, 0xba, 0xd0, 0x6f, 0x23, 0x8c, 0x39, 0x9e, 0x05, + 0x1a, 0x4e, 0xdc, 0x5e, 0xcd, 0x17, 0x59, 0x94, 0x37, 0x22, 0xb7, 0x39, + 0x50, 0x65, 0xdc, 0x91, 0x3c, 0xe1, 0x02, 0x81, 0x81, 0x00, 0xe4, 0xc6, + 0x42, 0xe5, 0xea, 0xe5, 0x32, 0xf3, 0x51, 0x36, 0x7b, 0x8c, 0x5b, 0x72, + 0x24, 0x1a, 0x4a, 0x44, 0x4f, 0x64, 0xe5, 0xa7, 0x74, 0xd9, 0xb2, 0x29, + 0x8a, 0x08, 0xcf, 0x9b, 0xd2, 0x9d, 0xc4, 0x20, 0x4c, 0xd3, 0x60, 0x4d, + 0xf7, 0xb7, 0xac, 0x92, 0x6b, 0x2b, 0x95, 0x73, 0x6e, 0x57, 0x00, 0x20, + 0x9d, 0xb2, 0xf6, 0xbd, 0x0b, 0xbb, 0xaa, 0x7e, 0x7e, 0x3e, 0x53, 0xfb, + 0x79, 0x7e, 0x45, 0xd5, 0x2e, 0xab, 0x5e, 0xff, 0x5c, 0x0a, 0x45, 0x2d, + 0x27, 0x19, 0xb0, 0x59, 0x0a, 0x39, 0x89, 0xf6, 0xae, 0xc6, 0xe2, 0xd1, + 0x07, 0x58, 0xbe, 0x95, 0x27, 0xaf, 0xf7, 0xa6, 0x2f, 0xaa, 0x37, 0x25, + 0x7c, 0x7b, 0xd3, 0xda, 0x13, 0x76, 0x0a, 0xb6, 0x6c, 0x99, 0x53, 0x5d, + 0xa5, 0x75, 0xfa, 0x10, 0x9b, 0x7f, 0xfe, 0xd7, 0xb4, 0x18, 0x95, 0xa8, + 0x65, 0x85, 0x07, 0xc5, 0xc4, 0xad, 0x02, 0x81, 0x81, 0x00, 0xc2, 0xb8, + 0x8e, 0xed, 0x9d, 0x4a, 0x1f, 0x9c, 0xda, 0x73, 0xf0, 0x2c, 0x35, 0x91, + 0xe4, 0x40, 0x78, 0xe1, 0x12, 0xf3, 0x08, 0xef, 0xdf, 0x97, 0xa0, 0xb0, + 0xdd, 0xea, 0xc2, 0xb9, 0x5b, 0xf8, 0xa1, 0xac, 0x32, 0xfd, 0xb8, 0xe9, + 0x0f, 0xed, 0xfd, 0xe0, 0xdc, 0x38, 0x90, 0x5e, 0xf5, 0x4c, 0x02, 0xc3, + 0x1a, 0x72, 0x18, 0xf7, 0xfe, 0xb7, 0xb8, 0x2a, 0xf8, 0x72, 0xbb, 0x99, + 0x56, 0xec, 0x85, 0x58, 0x31, 0x7e, 0x64, 0xdf, 0x02, 0x05, 0xe3, 0xb2, + 0xbb, 0xe2, 0x1b, 0xd6, 0x43, 0x73, 0xf8, 0x0f, 0xaf, 0x89, 0x57, 0x44, + 0x5f, 0x30, 0x1c, 0xe5, 0x78, 0xbf, 0x0b, 0xe7, 0x4b, 0xbe, 0x80, 0x2f, + 0x3d, 0x35, 0x44, 0xfc, 0x9e, 0x0d, 0x85, 0x5d, 0x94, 0x6e, 0xe9, 0x6a, + 0x72, 0xa7, 0x46, 0xd8, 0x64, 0x6c, 0xe9, 0x61, 0x92, 0xa0, 0xb6, 0xd1, + 0xee, 0xa6, 0xa6, 0xf4, 0x2c, 0x29, 0x02, 0x81, 0x81, 0x00, 0xb4, 0xa7, + 0x7b, 0x1c, 0x64, 0x29, 0x29, 0xda, 0xca, 0x3e, 0xe3, 0xc1, 0x2a, 0x55, + 0x2f, 0xfd, 0x32, 0xb8, 0x4e, 0x99, 0xb6, 0x60, 0x4d, 0xfd, 0xba, 0x9a, + 0xe2, 0xcd, 0xa2, 0x63, 0xc2, 0x25, 0xa3, 0x42, 0x7e, 0x68, 0x4c, 0x9c, + 0x45, 0x09, 0x5d, 0xd5, 0x21, 0x9c, 0x01, 0x20, 0x6d, 0xf9, 0x75, 0xb8, + 0x4b, 0xcf, 0x8e, 0xd8, 0x29, 0xf3, 0xbf, 0xe6, 0xb3, 0x7a, 0x34, 0x87, + 0x58, 0xa1, 0x46, 0x33, 0xd9, 0xee, 0xa9, 0xcd, 0xac, 0xb8, 0xcf, 0x77, + 0xa0, 0x70, 0xc0, 0xb9, 0x0f, 0x41, 0xf0, 0x98, 0x43, 0xdb, 0xfa, 0x30, + 0x66, 0x44, 0xc5, 0xfa, 0xb2, 0xa4, 0x5a, 0x43, 0x79, 0x50, 0x48, 0xcb, + 0xe9, 0x49, 0x3f, 0x39, 0xee, 0x34, 0x40, 0xb1, 0x5d, 0x80, 0x96, 0x3c, + 0x54, 0xf4, 0x9c, 0xcb, 0x90, 0x7f, 0xba, 0x96, 0x4b, 0x39, 0x3e, 0xb5, + 0x03, 0xb5, 0xd1, 0x35, 0x72, 0xe1, 0x02, 0x81, 0x80, 0x60, 0x14, 0xd5, + 0x61, 0xe6, 0x24, 0xf7, 0x28, 0x5c, 0x9a, 0xac, 0xbe, 0x03, 0xc8, 0xf3, + 0x49, 0xe4, 0xdb, 0x9a, 0x90, 0x15, 0xae, 0xd7, 0x33, 0x68, 0x75, 0x1d, + 0x6b, 0x83, 0x9e, 0x17, 0x05, 0xbe, 0x30, 0xcc, 0x10, 0x6a, 0x37, 0x86, + 0x46, 0xb6, 0xe9, 0x47, 0x81, 0x19, 0xab, 0xe1, 0x7a, 0x1a, 0x3a, 0xcf, + 0x47, 0xd1, 0x8e, 0x3d, 0x3f, 0xc6, 0x3e, 0x5d, 0xcd, 0xaf, 0x47, 0xe0, + 0x9e, 0x60, 0xc5, 0xbd, 0xd6, 0x52, 0x4b, 0xc0, 0x21, 0xcb, 0xd3, 0x1b, + 0xe6, 0x5c, 0x3a, 0x03, 0x9a, 0xab, 0xa2, 0x81, 0xc9, 0x51, 0x28, 0x49, + 0x97, 0xe2, 0x0a, 0x50, 0xe4, 0x64, 0x29, 0x43, 0x34, 0xc2, 0xe7, 0x8c, + 0x5a, 0x46, 0xaa, 0x28, 0x0b, 0x1f, 0xed, 0xa7, 0x1a, 0x7b, 0x4e, 0xad, + 0x38, 0x61, 0x3a, 0xd1, 0x82, 0xf4, 0x3d, 0xd3, 0x2e, 0x3e, 0x47, 0xa4, + 0x6c, 0xd3, 0x20, 0xd4, 0xd1, 0x02, 0x81, 0x80, 0x68, 0x1a, 0x8d, 0x3c, + 0x18, 0x3f, 0x42, 0x5e, 0x38, 0x6d, 0x0a, 0x1e, 0x52, 0xd5, 0x8f, 0xd6, + 0x32, 0xff, 0x7c, 0x1c, 0xf3, 0x20, 0x8b, 0x92, 0xa5, 0x44, 0xff, 0x08, + 0x21, 0xa1, 0xce, 0x68, 0x8b, 0x03, 0xe0, 0x90, 0xeb, 0x01, 0x4e, 0x85, + 0xf9, 0xc5, 0xb7, 0x86, 0xee, 0xd0, 0x59, 0x10, 0x73, 0x98, 0x2a, 0xcb, + 0xf6, 0xfe, 0x0d, 0xba, 0x07, 0x91, 0x18, 0xf6, 0xbc, 0x93, 0x8a, 0x91, + 0xdd, 0x80, 0x16, 0x37, 0xdf, 0x75, 0x46, 0x87, 0x68, 0xee, 0xf4, 0x76, + 0x0c, 0xc5, 0x87, 0x38, 0xf5, 0xb6, 0xda, 0x8a, 0xee, 0x62, 0xc8, 0xc0, + 0xa2, 0x8d, 0xbf, 0xd5, 0xf8, 0xba, 0xb5, 0x74, 0xf0, 0x07, 0xa6, 0x1c, + 0xcf, 0x76, 0x61, 0xbe, 0xa4, 0x88, 0x4a, 0x95, 0xb0, 0xa3, 0x70, 0x73, + 0xa1, 0x6f, 0x73, 0xf0, 0xe8, 0x38, 0x8d, 0xe8, 0xd0, 0x7e, 0x2c, 0x0c, + 0xdc, 0x21, 0xfa, 0xc1 +}; + +static unsigned char ca_cert_der[] = { + 0x30, 0x82, 0x03, 0xc7, 0x30, 0x82, 0x02, 0xaf, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0xa1, 0x79, 0xb0, 0x6a, 0x32, 0xbc, 0x48, 0x67, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x05, 0x00, 0x30, 0x7a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x12, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x53, 0x61, 0x6e, 0x20, 0x44, 0x69, + 0x65, 0x67, 0x6f, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x0d, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, + 0x67, 0x69, 0x63, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x0b, 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x65, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, + 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, + 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x36, 0x31, 0x31, 0x31, 0x31, 0x31, 0x39, 0x35, 0x30, 0x30, 0x38, 0x5a, + 0x17, 0x0d, 0x32, 0x36, 0x31, 0x31, 0x30, 0x39, 0x31, 0x39, 0x35, 0x30, + 0x30, 0x38, 0x5a, 0x30, 0x7a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x12, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x53, 0x61, 0x6e, 0x20, 0x44, 0x69, + 0x65, 0x67, 0x6f, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x0c, 0x0d, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, + 0x67, 0x69, 0x63, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x0c, 0x0b, 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x65, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, + 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, + 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xd1, 0xdc, 0x3c, 0xe1, 0x1c, 0x7a, 0x3d, 0xb7, + 0x76, 0xcf, 0xab, 0xd7, 0x3c, 0x38, 0xb0, 0x81, 0xb6, 0x37, 0x52, 0xa3, + 0x3d, 0x6f, 0xcd, 0x89, 0xa6, 0xa2, 0xf3, 0xa8, 0xb0, 0x8d, 0xee, 0x0b, + 0x36, 0x94, 0x83, 0x0e, 0x7f, 0x39, 0x87, 0x6e, 0xee, 0x19, 0xe2, 0x1f, + 0x92, 0x3d, 0x01, 0x05, 0x4f, 0x11, 0xcd, 0xcb, 0xa0, 0x79, 0xfc, 0x9d, + 0x6e, 0x93, 0xb1, 0xb7, 0x03, 0xf3, 0xfe, 0xeb, 0x30, 0x67, 0x38, 0x85, + 0x28, 0xdf, 0x93, 0xdb, 0xcb, 0xcb, 0xb1, 0xbe, 0xd3, 0xe1, 0xc2, 0x7d, + 0x8d, 0xbb, 0x70, 0x76, 0x99, 0x08, 0x7c, 0x3f, 0x21, 0x2f, 0x37, 0x97, + 0xf7, 0xe8, 0x6e, 0x8c, 0x7e, 0xbc, 0x30, 0x5f, 0xbf, 0x32, 0x51, 0x1d, + 0x66, 0x76, 0xad, 0x39, 0xfc, 0x94, 0xd4, 0x65, 0xf6, 0xd2, 0x0b, 0x37, + 0xd3, 0x4a, 0xe6, 0xe1, 0xdf, 0x4a, 0x8f, 0x3b, 0x33, 0x16, 0xbe, 0xf7, + 0xd9, 0xbd, 0x73, 0x64, 0xdf, 0x34, 0xa3, 0x55, 0xe7, 0xac, 0xab, 0xa7, + 0xae, 0xc2, 0x20, 0x46, 0xc2, 0xd1, 0xe3, 0x25, 0x3a, 0x47, 0x68, 0x92, + 0xac, 0xd6, 0x12, 0xa4, 0x0a, 0xce, 0xdc, 0xe2, 0x24, 0x12, 0xee, 0xe1, + 0xb2, 0xcd, 0x09, 0xa8, 0xef, 0x36, 0xea, 0x76, 0xf9, 0xb6, 0x63, 0xaa, + 0xac, 0xdd, 0x46, 0x06, 0x6e, 0xd9, 0x1e, 0x08, 0xac, 0x57, 0x12, 0x6c, + 0x21, 0xef, 0x8e, 0xae, 0xf0, 0x27, 0xf1, 0x5c, 0x79, 0xb4, 0xb6, 0x26, + 0x92, 0x11, 0xda, 0xca, 0x80, 0x5e, 0x92, 0x4c, 0xb5, 0xd8, 0xb5, 0x84, + 0x95, 0xe3, 0xef, 0xbc, 0x7e, 0x7d, 0x68, 0x74, 0x4c, 0x34, 0x1a, 0x50, + 0x6d, 0x2d, 0x5f, 0x1b, 0x0e, 0xbe, 0xf5, 0xb4, 0xf1, 0x32, 0x16, 0x44, + 0x24, 0x7a, 0x0e, 0x4b, 0xcd, 0xfa, 0xa5, 0x03, 0x95, 0x2e, 0x44, 0x65, + 0xa8, 0x74, 0xea, 0x17, 0xdd, 0x99, 0xbd, 0xcb, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x1b, 0x8d, 0x06, 0xd9, 0x6b, 0xad, 0xee, 0x82, + 0x24, 0x26, 0x55, 0x9a, 0x1b, 0x03, 0x44, 0x92, 0x0a, 0x06, 0x92, 0x48, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, + 0x14, 0x1b, 0x8d, 0x06, 0xd9, 0x6b, 0xad, 0xee, 0x82, 0x24, 0x26, 0x55, + 0x9a, 0x1b, 0x03, 0x44, 0x92, 0x0a, 0x06, 0x92, 0x48, 0x30, 0x0c, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x70, 0xc7, 0x6a, 0x75, 0x27, + 0x14, 0xa0, 0x1c, 0xe0, 0xe0, 0x84, 0x7c, 0x6c, 0x16, 0xa9, 0x0d, 0x4d, + 0xb1, 0xc3, 0x87, 0x37, 0xf6, 0x86, 0x89, 0x6f, 0x73, 0xf0, 0x59, 0x9b, + 0x8c, 0xa4, 0x83, 0x10, 0x2d, 0xb7, 0x8b, 0xd0, 0x9a, 0x81, 0xe0, 0x5c, + 0xd7, 0x20, 0x6f, 0xdc, 0xfc, 0xc8, 0xa0, 0xc2, 0x8e, 0x54, 0xe6, 0xfb, + 0x61, 0x85, 0x37, 0x4b, 0x22, 0x47, 0x09, 0x95, 0x44, 0x12, 0x75, 0xf0, + 0xcf, 0x0b, 0x90, 0x48, 0xb0, 0x02, 0x4c, 0xef, 0x3f, 0xde, 0x6a, 0xfd, + 0xb1, 0x8b, 0x88, 0xd7, 0x84, 0xe5, 0x34, 0x02, 0x96, 0x0a, 0x3f, 0xa8, + 0x8c, 0xbd, 0x1a, 0xd8, 0xf7, 0xf9, 0xe5, 0x49, 0x87, 0xd0, 0x20, 0x4f, + 0xd8, 0xcd, 0xc0, 0xb9, 0x11, 0x2a, 0xd9, 0x0f, 0x75, 0xa6, 0xee, 0x76, + 0x15, 0x9f, 0x12, 0x50, 0x68, 0x4c, 0xc0, 0x05, 0x46, 0x8d, 0xdd, 0x93, + 0x74, 0x31, 0x82, 0x20, 0x37, 0x24, 0x58, 0xb2, 0x88, 0x9b, 0x21, 0xc1, + 0x48, 0xc4, 0x8d, 0x68, 0x3b, 0x91, 0x2c, 0x34, 0xcb, 0x94, 0xd0, 0xbc, + 0xe3, 0x05, 0x24, 0x05, 0xcc, 0xea, 0x05, 0xb1, 0x52, 0x74, 0x4a, 0x23, + 0x65, 0xc4, 0x40, 0x04, 0x86, 0xb1, 0x80, 0x61, 0x97, 0xdc, 0x94, 0x16, + 0x4e, 0x63, 0x31, 0x72, 0x4e, 0x45, 0xe8, 0x3e, 0x3b, 0xb6, 0x99, 0xae, + 0xd8, 0x91, 0x25, 0x3d, 0x62, 0x92, 0x6d, 0x72, 0x01, 0x2c, 0xca, 0x67, + 0x0a, 0xec, 0x00, 0xeb, 0x10, 0xff, 0x6d, 0xac, 0x89, 0x19, 0x2c, 0xb7, + 0xb3, 0xa5, 0xf7, 0xa1, 0x4a, 0xc3, 0xc1, 0xdd, 0xaf, 0xb5, 0x1a, 0x16, + 0x44, 0xdc, 0xa8, 0xb5, 0xca, 0xd0, 0x30, 0xaa, 0x7e, 0x73, 0xd5, 0x2e, + 0x65, 0xd6, 0xf9, 0xbf, 0x5f, 0xda, 0x6f, 0x13, 0xe9, 0xd7, 0x12, 0x6c, + 0x3a, 0x6c, 0x50, 0x26, 0x78, 0x6e, 0xc6, 0xeb, 0x75, 0xe1, 0x3c +}; + +static void mqtt_server_init(NX_IP *ip_ptr); + +static UINT time_callback(ULONG *unix_time); + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ +CHAR *host_name = "www.example.com"; +CHAR *device_id = "device_id"; +CHAR *module_id = "module_id"; +CHAR *symmetric_key = "symmetric_key"; +ULONG pool_ptr_available_packet; + + /* Setup an MQTT server first. */ + mqtt_server_init(ip_ptr); + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)ca_cert_der, sizeof(ca_cert_der), + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, time_callback), + NX_AZURE_IOT_SUCCESS); + + /* Record number of available packet before test */ + pool_ptr_available_packet = pool_ptr -> nx_packet_pool_available; + + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_connection_status_callback_set(&iot_client, + connection_status_cb), + NX_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_symmetric_key_set(&iot_client, STRING_UNSIGNED_ARGS(symmetric_key)), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_TRUE, NX_NO_WAIT), + NX_AZURE_IOT_CONNECTING); + + /* Establish MQTT connection. */ + mqtt_server_accept(ip_ptr, pool_ptr); + + /* Wait one second for connection. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check connection status. */ + assert_int_equal(connection_status, NX_AZURE_IOT_SUCCESS); + + /* Wait until SAS token expired. */ + tx_time_set(tx_time_get() + NX_AZURE_IOT_HUB_CLIENT_TOKEN_CONNECTION_TIMEOUT * NX_IP_PERIODIC_RATE); + + /* Disconnect from server. */ + nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Check connection status. */ + assert_int_equal(connection_status, NX_AZURE_IOT_SAS_TOKEN_EXPIRED); + + /* Cleanup MQTT server. */ + mqtt_server_deinit(ip_ptr); + + assert_int_equal(nx_azure_iot_hub_client_disconnect(&iot_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* Check if all the packet are released */ + assert_int_equal(pool_ptr -> nx_packet_pool_available, pool_ptr_available_packet); + + /* SUCCESS: iot is created. */ + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); +} + + +static UINT time_callback(ULONG *unix_time) +{ + *unix_time = 1612174237 + tx_time_get() / NX_IP_PERIODIC_RATE; + return(NX_SUCCESS); +} + + +static void mqtt_server_init(NX_IP *ip_ptr) +{ + + /* Create a socket. */ + assert_int_equal(nx_tcp_socket_create(ip_ptr, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL), + NX_SUCCESS); + + /* Setup this thread to listen. */ + assert_int_equal(nx_tcp_server_socket_listen(ip_ptr, NXD_MQTT_TLS_PORT, + &server_socket, 5, NX_NULL), + NX_SUCCESS); + + assert_int_equal(_nx_secure_tls_session_create_ext(&tls_server_session, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + server_metadata_buffer, + sizeof(server_metadata_buffer)), + NX_SUCCESS); + + assert_int_equal(nx_secure_x509_certificate_initialize(&server_certificate, + server_cert_der, sizeof(server_cert_der), + NX_NULL, 0, server_cert_key_der, + sizeof(server_cert_key_der), NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER), + NX_SUCCESS); + + assert_int_equal(nx_secure_tls_local_certificate_add(&tls_server_session, &server_certificate), NX_SUCCESS); + + assert_int_equal(nx_secure_tls_session_packet_buffer_set(&tls_server_session, + server_tls_packet_buffer, + sizeof(server_tls_packet_buffer)), + NX_SUCCESS); +} + +static void mqtt_server_accept(NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr) +{ +NX_PACKET *packet_ptr; +UCHAR *byte; + + /* Accept a connection from client socket. */ + assert_int_equal(nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER), NX_SUCCESS); + assert_int_equal(nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER), NX_SUCCESS); + + /* Receive MQTT CONN. */ + assert_int_equal(nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER), NX_SUCCESS); + assert_int_equal(nx_packet_release(packet_ptr), NX_SUCCESS); + assert_int_equal(nx_secure_tls_packet_allocate(&tls_server_session, pool_ptr, &packet_ptr, NX_WAIT_FOREVER), NX_SUCCESS); + + /* Construct CONNACK packet. */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + /* Send CONNACK packet. */ + assert_int_equal(nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER), NX_SUCCESS); +} + +static void mqtt_server_deinit(NX_IP *ip_ptr) +{ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + nx_tcp_server_socket_unaccept(&server_socket); + nx_secure_tls_session_delete(&tls_server_session); + nx_tcp_server_socket_unlisten(ip_ptr, NXD_MQTT_TLS_PORT); + nx_tcp_socket_delete(&server_socket); +} + +void connection_status_cb(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr, UINT status) +{ + connection_status = status; +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ + printf("HIJACKED: %s\n", __func__); + host_address_ptr -> nxd_ip_version = NX_IP_VERSION_V4; + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NX_SUCCESS); +} diff --git a/test/regression/azure_iot/connection_unit_test.c b/test/regression/azure_iot/connection_unit_test.c new file mode 100644 index 00000000..0b69a5fe --- /dev/null +++ b/test/regression/azure_iot/connection_unit_test.c @@ -0,0 +1,244 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +static VOID connection_status_cb(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr, UINT status); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +extern int g_argc; +extern char **g_argv; + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ +CHAR *host_name = "host_name"; +CHAR *device_id = "device_id"; +CHAR *module_id = "module_id"; +CHAR *symmetric_key = "symmetric_key"; +UINT i; +ULONG pool_ptr_available_packet; + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert, (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* Record number of available packet before test */ + pool_ptr_available_packet = pool_ptr -> nx_packet_pool_available; + + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + NX_NULL, 0, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Setup callback function. */ + /* FAIL: NX_AZURE_IOT_HUB_CLIENT pointer is null. */ + assert_int_not_equal(nx_azure_iot_hub_client_connection_status_callback_set(NX_NULL, connection_status_cb), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: Setup callback function. */ + assert_int_equal(nx_azure_iot_hub_client_connection_status_callback_set(&iot_client, connection_status_cb), + NX_AZURE_IOT_SUCCESS); + + /* Setup Setup model Id. */ + /* FAIL: NX_AZURE_IOT_HUB_CLIENT pointer is null. */ + assert_int_not_equal(nx_azure_iot_hub_client_model_id_set(NX_NULL, STRING_UNSIGNED_ARGS("test::pnp")), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: Setup model Id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&iot_client, STRING_UNSIGNED_ARGS("test::pnp")), + NX_AZURE_IOT_SUCCESS); + + /* Setup Setup symmetric key. */ + /* FAIL: NX_AZURE_IOT_HUB_CLIENT pointer is null. */ + assert_int_not_equal(nx_azure_iot_hub_client_symmetric_key_set(NX_NULL, STRING_UNSIGNED_ARGS("SGVsbG8gdGhpcyBpcyB0ZXN0")), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: Setup Setup symmetric key. */ + assert_int_equal(nx_azure_iot_hub_client_symmetric_key_set(&iot_client, STRING_UNSIGNED_ARGS("SGVsbG8gdGhpcyBpcyB0ZXN0")), + NX_AZURE_IOT_SUCCESS); + + /*********** Test nx_azure_iot_hub_client_connect() ***********/ + /* FAIL: NX_AZURE_IOT_HUB_CLIENT pointer is null. */ + assert_int_not_equal(nx_azure_iot_hub_client_connect(NX_NULL, NX_FALSE, 20 * NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: nx_azure_iot_ptr is null. */ + iot_client.nx_azure_iot_ptr = NX_NULL; + assert_int_not_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, 20 * NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + iot_client.nx_azure_iot_ptr = &iot; + + /* FAIL: Invalid value of nx_azure_iot_hub_client_state. */ + iot_client.nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTED; + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, 20 * NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_ALREADY_CONNECTED); + iot_client.nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_CONNECTING; + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, 20 * NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_CONNECTING); + iot_client.nx_azure_iot_hub_client_state = NX_AZURE_IOT_HUB_CLIENT_STATUS_NOT_CONNECTED; + + /* FAIL: nxd_dns_host_by_name_get will fail by hijacked function. */ + will_return(__wrap__nxde_dns_host_by_name_get, NX_DNS_PARAM_ERROR); + assert_int_not_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, 20 * NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + will_return_always(__wrap__nxde_dns_host_by_name_get, NXD_MQTT_SUCCESS); + + /* TODO: add more test points for packet buffer. */ + + /* FAIL: nxd_mqtt_client_secure_connect will fail by hijacked function. */ + will_return(__wrap__nxde_mqtt_client_secure_connect, NXD_MQTT_INVALID_PARAMETER); + expect_value(connection_status_cb, status, NXD_MQTT_INVALID_PARAMETER); + assert_int_not_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, 20 * NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: connected. */ + will_return_always(__wrap__nxde_mqtt_client_secure_connect, NXD_MQTT_SUCCESS); + expect_value(connection_status_cb, status, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, 20 * NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /*********** Test nx_azure_iot_hub_client_disconnect() ***********/ + /* FAIL: NX_AZURE_IOT_HUB_CLIENT pointer is null. */ + assert_int_not_equal(nx_azure_iot_hub_client_disconnect(NX_NULL), NX_AZURE_IOT_SUCCESS); + + /* FAIL: nxd_mqtt_client_disconnect will fail by hijacked function. */ + will_return(__wrap__nxde_mqtt_client_disconnect, NXD_MQTT_INVALID_PARAMETER); + assert_int_not_equal(nx_azure_iot_hub_client_disconnect(&iot_client), NX_AZURE_IOT_SUCCESS); + will_return_always(__wrap__nxde_mqtt_client_disconnect, NXD_MQTT_SUCCESS); + + /* SUCCESS: disconnected. */ + assert_int_equal(nx_azure_iot_hub_client_disconnect(&iot_client), NX_AZURE_IOT_SUCCESS); + + /* Try reconnect. */ + expect_value(connection_status_cb, status, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, 20 * NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: disconnected. */ + assert_int_equal(nx_azure_iot_hub_client_disconnect(&iot_client), NX_AZURE_IOT_SUCCESS); + + /*********** End Test ***********/ + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* Check if all the packet are released */ + assert_int_equal(pool_ptr -> nx_packet_pool_available, pool_ptr_available_packet); + + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ +UINT status = (UINT)mock(); + + printf("HIJACKED: %s\n", __func__); + if (status) + { + return(status); + } + + assert_memory_equal(host_name, "host_name", strlen("host_name")); + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(status); +} + +UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, + UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *, + NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *), + UINT keepalive, UINT clean_session, ULONG wait_option) +{ +UINT status = (UINT)mock(); + + printf("HIJACKED: %s\n", __func__); + if (status) + { + return(status); + } + + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + return(status); +} + +UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr) +{ +UINT status = (UINT)mock(); + + printf("HIJACKED: %s\n", __func__); + if (status) + { + return(status); + } + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE; + return(status); +} + +static VOID connection_status_cb(struct NX_AZURE_IOT_HUB_CLIENT_STRUCT *hub_client_ptr, UINT status) +{ + assert_ptr_equal(hub_client_ptr, &iot_client); + check_expected(status); +} + +UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} diff --git a/test/regression/azure_iot/d2c_unit_test.c b/test/regression/azure_iot/d2c_unit_test.c new file mode 100644 index 00000000..df98ed10 --- /dev/null +++ b/test/regression/azure_iot/d2c_unit_test.c @@ -0,0 +1,368 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +static UINT deplete_packets(NX_PACKET_POOL *pool_ptr, UINT remaining_packets); +static VOID release_packets(NX_PACKET_POOL *pool_ptr, UINT count); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +static NX_PACKET *allocated_packets[256]; +static UCHAR large_property_name[2048]; +static ULONG small_pool_stack[1024 >> 2]; +static NX_PACKET_POOL small_pool; +extern int g_argc; +extern char **g_argv; + +CHAR *expected_topic = ""; +CHAR *expected_message = ""; + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ +CHAR *host_name = "host_name"; +CHAR *device_id = "device_id"; +CHAR *module_id = "module_id"; +CHAR *symmetric_key = "symmetric_key"; +CHAR property_name[] = "property_name"; +CHAR property_value[] = "property_value"; +NX_PACKET *packet_ptr; +UINT count; +ULONG pool_ptr_available_packet; +ULONG small_pool_available_packet; + + assert_int_equal(nx_packet_pool_create(&small_pool, "Small Packet Pool", 4, + (UCHAR *)small_pool_stack , sizeof(small_pool_stack)), + NX_AZURE_IOT_SUCCESS); + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert, (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* Record number of available packet before test */ + pool_ptr_available_packet = pool_ptr -> nx_packet_pool_available; + small_pool_available_packet = small_pool.nx_packet_pool_available; + + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: allocate packet before connect. */ + iot_client.nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_client_use_tls = NX_TRUE; + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, &packet_ptr, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + iot_client.nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_client_use_tls = NX_FALSE; + + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_TRUE, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + expected_topic = "devices/device_id/messages/events/"; + expected_message = "{\"Message\": \"Empty\"}"; + + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NXD_MQTT_NOT_CONNECTED); + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, &packet_ptr, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_send(&iot_client, packet_ptr, expected_message, + strlen(expected_message), NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr), NX_AZURE_IOT_SUCCESS); + + will_return_always(__wrap__nxd_mqtt_client_publish_packet_send, NXD_MQTT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, &packet_ptr, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: hub_client_ptr is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_send(NX_NULL, packet_ptr, expected_message, + strlen(expected_message), NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: packet_ptr is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_send(&iot_client, NX_NULL, expected_message, + strlen(expected_message), NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: Send telemetry as a device. */ + assert_int_equal(nx_azure_iot_hub_client_telemetry_send(&iot_client, packet_ptr, expected_message, + strlen(expected_message), NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: hub_client_ptr is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_message_create(NX_NULL, &packet_ptr, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: packet_pptr is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, NX_NULL, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: All packets are depleted. */ + count = deplete_packets(pool_ptr, 0); + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, &packet_ptr, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + release_packets(pool_ptr, count); + + /* FAIL: Packet pool is too small. */ + iot.nx_azure_iot_pool_ptr = &small_pool; + iot_client.nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_client_use_tls = NX_TRUE; + iot_client.nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_client_packet_pool_ptr = iot.nx_azure_iot_pool_ptr; + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, &packet_ptr, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + iot.nx_azure_iot_pool_ptr = pool_ptr; + iot_client.nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_client_use_tls = NX_FALSE; + iot_client.nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_client_packet_pool_ptr = iot.nx_azure_iot_pool_ptr; + + /* SUCCESS: All parameters are valid. */ + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, &packet_ptr, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: packet_ptr is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_property_add(NX_NULL, + STRING_UNSIGNED_ARGS(property_name), + STRING_UNSIGNED_ARGS(property_value), + NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: property_name is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_property_add(packet_ptr, + NX_NULL, 0, + STRING_UNSIGNED_ARGS(property_value), + NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: property_value is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_property_add(packet_ptr, + STRING_UNSIGNED_ARGS(property_name), + NX_NULL, 0, + NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: All packets are depleted and current packet is too small to hold property. */ + count = deplete_packets(pool_ptr, 0); + memset(large_property_name, 'A', sizeof(large_property_name) - 1); + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_property_add(packet_ptr, + STRING_UNSIGNED_ARGS(large_property_name), + STRING_UNSIGNED_ARGS(property_value), + NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + nx_packet_release(packet_ptr); + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, &packet_ptr, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: All parameters are valid. */ + assert_int_equal(nx_azure_iot_hub_client_telemetry_property_add(packet_ptr, + STRING_UNSIGNED_ARGS(property_name), + STRING_UNSIGNED_ARGS(property_value), + NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: Adjust the current packet to full. No room to append '&' */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_data_end; + packet_ptr -> nx_packet_length = (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr); + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_property_add(packet_ptr, + STRING_UNSIGNED_ARGS(property_name), + STRING_UNSIGNED_ARGS(property_value), + NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + nx_packet_release(packet_ptr); + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, &packet_ptr, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: Adjust the current packet to full. Left two bytes for '&' and property name 'n' */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_data_end - 2; + packet_ptr -> nx_packet_length = (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) - 2; + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_property_add(packet_ptr, + "n", 1, + STRING_UNSIGNED_ARGS(property_value), + NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + nx_packet_release(packet_ptr); + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, &packet_ptr, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + release_packets(pool_ptr, count); + + /* SUCCESS: All parameters are valid. */ + assert_int_equal(nx_azure_iot_hub_client_telemetry_property_add(packet_ptr, + STRING_UNSIGNED_ARGS(property_name), + STRING_UNSIGNED_ARGS(property_value), + NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + nx_packet_release(packet_ptr); + + iot_client.nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(module_id), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_TRUE, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: Send telemetry as a module. */ + expected_topic = "devices/device_id/modules/module_id/messages/events/"; + expected_message = "{\"Message\": \"Empty\"}"; + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_create(&iot_client, &packet_ptr, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_telemetry_send(&iot_client, packet_ptr, expected_message, + strlen(expected_message), NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + iot_client.nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* Check if all the packet are released */ + assert_int_equal(pool_ptr -> nx_packet_pool_available, pool_ptr_available_packet); + assert_int_equal(small_pool.nx_packet_pool_available, small_pool_available_packet); + + /* SUCCESS: iot is created. */ + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); +} + +static UINT deplete_packets(NX_PACKET_POOL *pool_ptr, UINT remaining_packets) +{ +UINT count = 0; + + while (pool_ptr -> nx_packet_pool_available > remaining_packets) + { + nx_packet_allocate(pool_ptr, &allocated_packets[count++], 0, NX_WAIT_FOREVER); + } + return(count); +} + +static VOID release_packets(NX_PACKET_POOL *pool_ptr, UINT count) +{ + while (count != 0) + { + nx_packet_release(allocated_packets[--count]); + } +} + +UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, + UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *, + NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *), + UINT keepalive, UINT clean_session, ULONG timeout) +{ + printf("HIJACKED: %s\n", __func__); + tx_thread_suspend(&(iot.nx_azure_iot_ip_ptr -> nx_ip_thread)); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + client_ptr -> nxd_mqtt_client_packet_identifier = 1; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_FALSE; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &client_ptr -> nxd_mqtt_client_socket; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ + printf("HIJACKED: %s\n", __func__); + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NX_DNS_SUCCESS); +} + +UINT __wrap__nxd_mqtt_client_publish_packet_send(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + USHORT packet_id, UINT QoS, ULONG wait_option) +{ +UINT topic_name_length; +UINT message_length; +UCHAR *buffer_ptr; +UINT status = (UINT)mock(); + + printf("HIJACKED: %s\n", __func__); + tx_mutex_put(client_ptr -> nxd_mqtt_client_mutex_ptr); + + if (status) + { + return(status); + } + + buffer_ptr = packet_ptr -> nx_packet_prepend_ptr; + topic_name_length = (buffer_ptr[5] << 8) | (buffer_ptr[6]); + message_length = packet_ptr -> nx_packet_length - (9 + topic_name_length); + assert_int_equal(topic_name_length, strlen(expected_topic)); + assert_memory_equal(&buffer_ptr[7], expected_topic, topic_name_length); + assert_int_equal(message_length, strlen(expected_message)); + assert_memory_equal(&buffer_ptr[9 + topic_name_length], expected_message, message_length); + assert_int_equal(QoS, 1); + + /* packet ownership taken and released */ + nx_packet_release(packet_ptr); + + return(status); +} + +UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} diff --git a/test/regression/azure_iot/device_cert_unit_test.c b/test/regression/azure_iot/device_cert_unit_test.c new file mode 100644 index 00000000..4e14f792 --- /dev/null +++ b/test/regression/azure_iot/device_cert_unit_test.c @@ -0,0 +1,210 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" +#include "nx_azure_iot_provisioning_client.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_AZURE_IOT_PROVISIONING_CLIENT iot_prov_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +static NX_PACKET *allocated_packets[256]; +static UCHAR large_property_name[2048]; +static ULONG small_pool_stack[1024 >> 2]; +static NX_PACKET_POOL small_pool; +extern int g_argc; +extern char **g_argv; + +CHAR *expected_topic = ""; +CHAR *expected_message = ""; + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ +CHAR *host_name = "host_name"; +CHAR *device_id = "device_id"; +CHAR *module_id = "module_id"; +CHAR *endpoint = "host_name"; +CHAR *id_scope = "id_scope"; +CHAR *reg_id = "reg_id"; +NX_SECURE_X509_CERT device_certificate; + + assert_int_equal(nx_packet_pool_create(&small_pool, "Small Packet Pool", 4, + (UCHAR *)small_pool_stack , sizeof(small_pool_stack)), + NX_AZURE_IOT_SUCCESS); + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert, (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* Initialize IoT hub client. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: hub_client_ptr is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_device_cert_set(NX_NULL, &device_certificate), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: device_certificate is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_device_cert_set(&iot_client, NX_NULL), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: set device certificate. */ + assert_int_equal(nx_azure_iot_hub_client_device_cert_set(&iot_client, &device_certificate), + NX_AZURE_IOT_SUCCESS); + +#if NX_AZURE_IOT_MAX_NUM_OF_DEVICE_CERTS > 1 + /* SUCCESS: set device certificate again. */ + assert_int_equal(nx_azure_iot_hub_client_device_cert_set(&iot_client, &device_certificate), + NX_AZURE_IOT_SUCCESS); +#endif + + /* FAIL: no entry for device cert. */ + assert_int_not_equal(nx_azure_iot_hub_client_device_cert_set(&iot_client, &device_certificate), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: connected. */ + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, 20 * NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* Deinitialize IoT hub client. */ + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + + /* Initialize provisioning client. */ + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + endpoint, sizeof(endpoint) - 1, + id_scope, sizeof(id_scope) - 1, + reg_id, sizeof(reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: prov_client_ptr is NULL. */ + assert_int_not_equal(nx_azure_iot_provisioning_client_device_cert_set(NX_NULL, &device_certificate), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: device_certificate is NULL. */ + assert_int_not_equal(nx_azure_iot_provisioning_client_device_cert_set(&iot_prov_client, NX_NULL), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: set device certificate. */ + assert_int_equal(nx_azure_iot_provisioning_client_device_cert_set(&iot_prov_client, &device_certificate), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: pending. */ + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Deinitialize IoT provisioning client. */ + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); + + + /* SUCCESS: iot is deleted. */ + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ + printf("HIJACKED: %s\n", __func__); + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_login_set(NXD_MQTT_CLIENT *client_ptr, + CHAR *username, UINT username_length, CHAR *password, UINT password_length) +{ + printf("HIJACKED: %s\n", __func__); + assert_null(password); + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, + UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *, + NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *), + UINT keepalive, UINT clean_session, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr) +{ + printf("HIJACKED: %s\n", __func__); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE; + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} \ No newline at end of file diff --git a/test/regression/azure_iot/device_twin_unit_test.c b/test/regression/azure_iot/device_twin_unit_test.c new file mode 100644 index 00000000..2f7dfb68 --- /dev/null +++ b/test/regression/azure_iot/device_twin_unit_test.c @@ -0,0 +1,1127 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +#ifndef MAXIMUM_PAYLOAD_LENGTH +#define MAXIMUM_PAYLOAD_LENGTH 10240 +#endif /* MAXIMUM_PAYLOAD_LENGTH */ + +#define MQTT_CLIENT_GET(c) ((c) -> nx_azure_iot_hub_client_resource.resource_mqtt) +#define TX_MUTEX_GET(c) ((c) -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr) + +typedef VOID (*NX_AZURE_TEST_FN)(); + + +static UCHAR g_hostname[] = "unit-test.iot-azure.com"; +static UCHAR g_device_id[] = "unit_test_device"; + +static const UINT test_dt_document_response_status = 201; +static const UINT test_dt_reported_properties_response_status = 204; +static const UINT test_request_id = 1; + +static const CHAR test_device_twin_reported_properties_response_topic[] = "$iothub/twin/res/204/?$rid=1&$version=6"; +static const CHAR test_device_twin_reported_properties_throttled_response_topic[] = "$iothub/twin/res/429/?$rid=1"; +static const CHAR test_device_twin_reported_properties_response_payload[] = ""; +static const UINT test_reported_properties_response_id = 1; +static const CHAR test_device_twin_document_response_topic[] = "$iothub/twin/res/201/?$rid=2"; +static const CHAR test_device_twin_document_response_payload[] = "{ \ + \"desired\": { \ + \"telemetrySendFrequency\": \"5m\", \ + \"$version\": 12 \ + }, \ + \"reported\": { \ + \"telemetrySendFrequency\": \"5m\", \ + \"batteryLevel\": 55, \ + \"$version\": 123 \ + } \ +}"; +static const CHAR test_device_twin_document_response_throttled_topic[] = "$iothub/twin/res/429/?$rid=2"; +static const UINT test_device_twin_document_response_id = 2; +static const CHAR test_device_twin_desired_properties_response_topic[] = "$iothub/twin/PATCH/properties/desired/?$version=10"; +static const CHAR test_device_twin_desired_properties_response_payload[] = "{ \ + \"telemetrySendFrequency\": \"5m\", \ + \"route\": null, \ + \"$version\": 8 \ +}"; +static CHAR fixed_reported_properties[] = "{\"sample_report\": \"OK\"}"; + +static UINT g_total_append = 0; +static UINT g_failed_append_index = 0; +static UINT g_total_allocation = 0; +static UINT g_failed_allocation_index = -1; +static NX_IP* g_ip_ptr; +static NX_PACKET_POOL* g_pool_ptr; +static NX_DNS* g_dns_ptr; +static ULONG g_available_packet; +static CHAR *g_expected_message; +static UINT g_response_status; +static UINT g_request_id; + +extern UINT _nxd_mqtt_client_append_message(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, CHAR *message, + UINT length, ULONG wait_option); +extern UINT _nxd_mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + UCHAR control_header, UINT length, UINT wait_option); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +static UCHAR message_payload[MAXIMUM_PAYLOAD_LENGTH]; +static UCHAR result_buffer[MAXIMUM_PAYLOAD_LENGTH]; +static VOID (*test_receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count) = NX_NULL; + +UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr, + VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count)) +{ + printf("HIJACKED: %s\n", __func__); + test_receive_notify = receive_notify; + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_subscribe(NXD_MQTT_CLIENT *client_ptr, CHAR *topic_name, + UINT topic_name_length, UINT QoS) +{ + printf("HIJACKED: %s\n", __func__); + + iot_client.nx_azure_iot_hub_client_properties_subscribe_ack = NX_TRUE; + + return((UINT)mock()); +} + +UINT __wrap__nxde_mqtt_client_unsubscribe(NXD_MQTT_CLIENT *client_ptr, CHAR *topic_name, + UINT topic_name_length, UINT QoS) +{ + printf("HIJACKED: %s\n", __func__); + return((UINT)mock()); +} + +UINT __real__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option); +UINT __wrap__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_append_index == g_total_append) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_append++; + return __real__nx_packet_data_append(packet_ptr, data_start, data_size, pool_ptr, wait_option); +} + +UINT __real_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context); +UINT __wrap_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_allocation_index == g_total_allocation) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_allocation++; + return __real_nx_azure_iot_buffer_allocate(nx_azure_iot_ptr, buffer_pptr, buffer_size, buffer_context); +} + +UINT __wrap__nxd_mqtt_client_publish_packet_send(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + USHORT packet_id, UINT QoS, ULONG wait_option) +{ +UINT status = (UINT)mock(); + + printf("HIJACKED: %s\n", __func__); + tx_mutex_put(client_ptr -> nxd_mqtt_client_mutex_ptr); + + if (status) + { + return(status); + } + + assert_int_equal(QoS, 0); + + /* packet ownership taken and released */ + nx_packet_release(packet_ptr); + + return(status); +} + +UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, + UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *, + NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *), + UINT keepalive, UINT clean_session, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + + tx_thread_suspend(&(iot.nx_azure_iot_ip_ptr -> nx_ip_thread)); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + client_ptr -> nxd_mqtt_client_packet_identifier = 1; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_FALSE; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &client_ptr -> nxd_mqtt_client_socket; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr) +{ + printf("HIJACKED: %s\n", __func__); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ + printf("HIJACKED: %s\n", __func__); + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NX_DNS_SUCCESS); +} + +static VOID on_receive_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *arg) +{ + *((UINT *)arg) = 1; +} + +static UINT mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, UCHAR control_header, UINT length, UINT wait_option) +{ +UCHAR fixed_header[5]; +UCHAR *byte = fixed_header; +UINT count = 0; +UINT ret; + + *byte = control_header; + byte++; + + do + { + if (length & 0xFFFFFF80) + { + *(byte + count) = (UCHAR)((length & 0x7F) | 0x80); + } + else + { + *(byte + count) = length & 0x7F; + } + length = length >> 7; + + count++; + } while (length != 0); + + ret = __real__nx_packet_data_append(packet_ptr, fixed_header, count + 1, + client_ptr -> nxd_mqtt_client_packet_pool_ptr, wait_option); + + return(ret); +} + +static VOID construct_device_twin_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, + const UCHAR *topic, ULONG topic_len, + const UCHAR *message_payload_ptr, ULONG message_payload_length, + NX_PACKET **packet_pptr) +{ +NX_PACKET *packet_ptr; +ULONG total_length; +ULONG topic_length = topic_len; +UCHAR bytes[2]; +UINT i; + + assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + total_length = topic_length + 2 + 2 + message_payload_length; /* Two bytes for fixed topic_length field + and two bytes for packet id. */ + + /* Set fixed header. */ + assert_int_equal(mqtt_client_set_fixed_header(&(MQTT_CLIENT_GET(hub_client_ptr)), packet_ptr, + (UCHAR)((MQTT_CONTROL_PACKET_TYPE_PUBLISH << 4) | MQTT_PUBLISH_QOS_LEVEL_1), + total_length, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic length. */ + bytes[0] = (topic_length >> 8) & 0xFF; + bytes[1] = topic_length & 0xFF; + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)topic, topic_len, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + /* Set packet ID. The value does not matter. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set message payload. */ + if (message_payload_length > 0) + { + assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)message_payload_ptr, message_payload_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + + *packet_pptr = packet_ptr; +} + +static VOID generate_device_twin_reported_properties_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr) +{ +NX_PACKET *packet_ptr; + + construct_device_twin_response(hub_client_ptr, test_device_twin_reported_properties_response_topic, + sizeof(test_device_twin_reported_properties_response_topic) - 1, + test_device_twin_reported_properties_response_payload, + sizeof(test_device_twin_reported_properties_response_payload) - 1, + &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(hub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(hub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(hub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(hub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(hub_client_ptr)); +} + +static VOID generate_device_twin_reported_properties_throttled_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr) +{ +NX_PACKET *packet_ptr; + + construct_device_twin_response(hub_client_ptr, test_device_twin_reported_properties_throttled_response_topic, + sizeof(test_device_twin_reported_properties_throttled_response_topic) - 1, + NX_NULL, 0, &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(hub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(hub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(hub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(hub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(hub_client_ptr)); +} + +static VOID generate_device_twin_document_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr) +{ +NX_PACKET *packet_ptr; + + construct_device_twin_response(hub_client_ptr, test_device_twin_document_response_topic, + sizeof(test_device_twin_document_response_topic) - 1, + test_device_twin_document_response_payload, + sizeof(test_device_twin_document_response_payload) - 1, + &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(hub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(hub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(hub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(hub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(hub_client_ptr)); +} + +static VOID generate_device_twin_document_throttled_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr) +{ +NX_PACKET *packet_ptr; + + construct_device_twin_response(hub_client_ptr, test_device_twin_document_response_throttled_topic, + sizeof(test_device_twin_document_response_throttled_topic) - 1, + "{}", sizeof("{}") - 1, &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(hub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(hub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(hub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&MQTT_CLIENT_GET(hub_client_ptr), 1); + tx_mutex_put(TX_MUTEX_GET(hub_client_ptr)); +} + +static VOID generate_device_twin_desired_properties_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr) +{ +NX_PACKET *packet_ptr; + + construct_device_twin_response(hub_client_ptr, test_device_twin_desired_properties_response_topic, + sizeof(test_device_twin_desired_properties_response_topic) - 1, + test_device_twin_desired_properties_response_payload, + sizeof(test_device_twin_desired_properties_response_payload) - 1, + &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(hub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(hub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(hub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(hub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(hub_client_ptr)); +} + +static VOID test_response_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT request_id, + UINT response_status, ULONG version, VOID *args) +{ + g_response_status = response_status; + g_request_id = request_id; +} + +static VOID reset_global_state() +{ + /* reset global state */ + g_failed_append_index = (UINT)-1; + g_total_append = 0; + g_failed_allocation_index = (UINT)-1; + g_total_allocation = 0; + g_expected_message = NX_NULL; + g_response_status = 0; + g_request_id = 0; +} + +/* Hook execute before all tests. */ +static VOID test_suit_begin() +{ + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, + (UCHAR *)_nx_azure_iot_root_cert, + (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", + g_ip_ptr, g_pool_ptr, g_dns_ptr, + (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), + DEMO_CLOUD_THREAD_PRIORITY, unix_time_get), + NX_AZURE_IOT_SUCCESS); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + g_hostname, sizeof(g_hostname), + g_device_id, sizeof(g_device_id), + "", 0, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Record number of available packet before test */ + g_available_packet = g_pool_ptr -> nx_packet_pool_available; + + /* Connect IoTHub client */ + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_suit_end() +{ + + /* Disconnect IoTHub client */ + assert_int_equal(nx_azure_iot_hub_client_disconnect(&iot_client), NX_AZURE_IOT_SUCCESS); + + /* Check if all the packet are released */ + assert_int_equal(g_pool_ptr -> nx_packet_pool_available, g_available_packet); + + /* Deinitialize IoTHub Client */ + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: iot is deleted. */ + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); +} + +/* Hook executed before every test */ +static VOID test_begin() +{ + reset_global_state(); + + /* Reset the number of request sent */ + iot_client.nx_azure_iot_hub_client_request_id = 0; +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_end() +{ +} + +/** + * Test device twin enable with invalid argument failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_enable_invalid_argument_failure() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_enable(NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin enable with unsuccessful subscribe failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_enable_failure() +{ + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_NOT_SUCCESSFUL); + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_NOT_SUCCESSFUL); + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin enable succeeds. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_enable_success() +{ + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin disable with invalid argument failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_disable_invalid_argument_failure() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_disable(NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin disable with unsuccessful un-subscribe failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_disable_failure() +{ + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_unsubscribe, NX_NOT_SUCCESSFUL); + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_disable(&iot_client), + NX_AZURE_IOT_SUCCESS); + + will_return(__wrap__nxde_mqtt_client_unsubscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_unsubscribe, NX_NOT_SUCCESSFUL); + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_disable(&iot_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin disable succeeds. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_disable_success() +{ + printf("test starts =>: %s\n", __func__); + + will_return_always(__wrap__nxde_mqtt_client_unsubscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_disable(&iot_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin reported property callback set with invalid argument failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_reported_properties_response_callback_set_invalid_argument_failure() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_response_callback_set(NX_NULL, + NX_NULL, NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin reported properties callback set succeed. + * + **/ +static VOID test_nx_azure_iot_hub_client_reported_properties_response_callback_set_success() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_equal(nx_azure_iot_hub_client_reported_properties_response_callback_set(&iot_client, + test_response_callback, NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test old API reported properties callback set with invalid argument failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_report_properties_response_callback_set_invalid_argument_failure() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_hub_client_report_properties_response_callback_set(NX_NULL, + NX_NULL, NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test old API reported properties callback set succeed. + * + **/ +static VOID test_nx_azure_iot_hub_client_report_properties_response_callback_set_success() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_equal(nx_azure_iot_hub_client_report_properties_response_callback_set(&iot_client, + test_response_callback, NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin send reported properties fail if invalid argument is passed. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_reported_propetries_send_invalid_argument_failure() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_reported_properties_send(NX_NULL, + fixed_reported_properties, + sizeof(fixed_reported_properties) - 1, + &g_request_id, &g_response_status, + NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin send reported properties fail if publish failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_reported_propetries_send_publish_failure() +{ + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_NOT_SUCCESSFUL); + + assert_int_equal(nx_azure_iot_hub_client_reported_properties_response_callback_set(&iot_client, + test_response_callback, NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_reported_properties_send(&iot_client, + fixed_reported_properties, + sizeof(fixed_reported_properties) - 1, + &g_request_id, &g_response_status, + NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin send reported properties succeed. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_reported_propetries_send_success() +{ +UINT request_id = 0xFFFFFFFF; + + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_reported_properties_response_callback_set(&iot_client, + test_response_callback, NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_reported_properties_send(&iot_client, + fixed_reported_properties, + sizeof(fixed_reported_properties) - 1, + &request_id, &g_response_status, + NX_NULL, 0), + NX_AZURE_IOT_NO_PACKET); + + generate_device_twin_reported_properties_response(&iot_client); + + assert_int_not_equal(0xFFFFFFFF, request_id); + assert_int_equal(g_request_id, request_id); + assert_int_equal(g_response_status, test_dt_reported_properties_response_status); +} + +/** + * Test device twin send reported properties throttled. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_reported_propetries_send_throttled() +{ +UINT request_id = 0xFFFFFFFF; + + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_reported_properties_response_callback_set(&iot_client, + test_response_callback, NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_reported_properties_send(&iot_client, + fixed_reported_properties, + sizeof(fixed_reported_properties) - 1, + &request_id, &g_response_status, + NX_NULL, 0), + NX_AZURE_IOT_NO_PACKET); + + generate_device_twin_reported_properties_throttled_response(&iot_client); + + assert_int_equal(nx_azure_iot_hub_client_device_twin_reported_properties_send(&iot_client, + fixed_reported_properties, + sizeof(fixed_reported_properties) - 1, + &request_id, &g_response_status, + NX_NULL, 0), + NX_AZURE_IOT_THROTTLED); + + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + while (nx_azure_iot_hub_client_device_twin_reported_properties_send(&iot_client, + fixed_reported_properties, + sizeof(fixed_reported_properties) - 1, + &request_id, &g_response_status, + NX_NULL, 0) != NX_AZURE_IOT_NO_PACKET) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + generate_device_twin_reported_properties_response(&iot_client); + + assert_int_not_equal(0xFFFFFFFF, request_id); + assert_int_equal(g_response_status, test_dt_reported_properties_response_status); +} + +/** + * Test device twin receive twin properties fail if invalid argument is passed. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_propetries_request_invalid_argument_failure() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_properties_request(NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin receive twin properties fails if publish failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_propetries_request_publish_failure() +{ +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_NOT_SUCCESSFUL); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_properties_request(&iot_client, 0), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin receive twin properties succeed. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_propetries_request_success() +{ +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_device_twin_properties_request(&iot_client, 0), + NX_AZURE_IOT_SUCCESS); + + generate_device_twin_document_response(&iot_client); + assert_int_equal(nx_azure_iot_hub_client_device_twin_properties_receive(&iot_client, &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_memory_equal(result_buffer, test_device_twin_document_response_payload, sizeof(test_device_twin_document_response_payload) - 1); + + nx_packet_release(packet_ptr); +} + +/** + * Test device twin receive twin properties succeed with NX_NO_WAIT + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_propetries_request_no_blocking_success() +{ +NX_PACKET *packet_ptr; +ULONG bytes_copied; +UINT received = 0; + + printf("test starts =>: %s\n", __func__); + + assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iot_client, + NX_AZURE_IOT_HUB_DEVICE_TWIN_PROPERTIES, + on_receive_callback, + (VOID *)&received), + NX_AZURE_IOT_SUCCESS); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_device_twin_properties_request(&iot_client, 0), + NX_AZURE_IOT_SUCCESS); + + generate_device_twin_document_response(&iot_client); + + while (!received) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(nx_azure_iot_hub_client_device_twin_properties_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_memory_equal(result_buffer, test_device_twin_document_response_payload, sizeof(test_device_twin_document_response_payload) - 1); + + nx_packet_release(packet_ptr); +} + +/** + * Test device twin receive twin properties fails with allocation fail + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_propetries_request_allocation_fail_failure() +{ +UINT total_allocation_in_success_case; +UINT status; +NX_PACKET *packet_ptr; + + printf("test starts =>: %s\n", __func__); + + test_nx_azure_iot_hub_client_device_twin_propetries_request_success(); + total_allocation_in_success_case = g_total_allocation; + + for (INT index = 0; index < total_allocation_in_success_case; index++) + { + reset_global_state(); + g_failed_allocation_index = index; + + status = nx_azure_iot_hub_client_device_twin_properties_request(&iot_client, 0); + + if (status) + { + continue; + } + + generate_device_twin_document_response(&iot_client); + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_properties_receive(&iot_client, &packet_ptr, 0), + NX_AZURE_IOT_SUCCESS); + } +} + +/** + * Test device twin receive twin desired properties fail with invalid argument. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_desired_properties_receive_invalid_argument_failure() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_desired_properties_receive(NX_NULL, NX_NULL, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin receive twin desired properties succeed. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_desired_properties_receive_success() +{ +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + generate_device_twin_desired_properties_response(&iot_client); + + assert_int_equal(nx_azure_iot_hub_client_device_twin_desired_properties_receive(&iot_client, &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_memory_equal(result_buffer, test_device_twin_desired_properties_response_payload, + sizeof(test_device_twin_desired_properties_response_payload) - 1); + + nx_packet_release(packet_ptr); +} + +/** + * Test device twin receive twin desired properties succeed. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_desired_properties_receive_no_blocking_success() +{ +NX_PACKET *packet_ptr; +ULONG bytes_copied; +UINT received = 0; + + printf("test starts =>: %s\n", __func__); + + assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iot_client, + NX_AZURE_IOT_HUB_DEVICE_TWIN_DESIRED_PROPERTIES, + on_receive_callback, + (VOID *)&received), + NX_AZURE_IOT_SUCCESS); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + generate_device_twin_desired_properties_response(&iot_client); + + while (!received) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(nx_azure_iot_hub_client_device_twin_desired_properties_receive(&iot_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_memory_equal(result_buffer, test_device_twin_desired_properties_response_payload, + sizeof(test_device_twin_desired_properties_response_payload) - 1); + + nx_packet_release(packet_ptr); +} + +/** + * Test no one is receiving device twin. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_no_receive() +{ +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + generate_device_twin_desired_properties_response(&iot_client); + generate_device_twin_document_response(&iot_client); +} + +/** + * Test invalid argument receiving device twin. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_receive_invalid_argument_failure() +{ + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_desired_properties_receive(NX_NULL, NX_NULL, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test device twin receive twin desired properties fails with allocation fail + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_desired_properties_receive_allocation_fail_failure() +{ +UINT total_allocation_in_success_case; +UINT status; +NX_PACKET *packet_ptr; + + printf("test starts =>: %s\n", __func__); + + test_nx_azure_iot_hub_client_device_twin_desired_properties_receive_success(); + total_allocation_in_success_case = g_total_allocation; + + for (INT index = 0; index < total_allocation_in_success_case; index++) + { + reset_global_state(); + g_failed_allocation_index = index; + + generate_device_twin_desired_properties_response(&iot_client); + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_desired_properties_receive(&iot_client, &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + } +} + +/** + * Test receive throttling error. + * + **/ +static VOID test_nx_azure_iot_hub_client_device_twin_propetries_request_throttle() +{ +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_device_twin_properties_request(&iot_client, 0), + NX_AZURE_IOT_SUCCESS); + + generate_device_twin_document_throttled_response(&iot_client); + assert_int_not_equal(nx_azure_iot_hub_client_device_twin_properties_receive(&iot_client, &packet_ptr, 0), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_device_twin_properties_request(&iot_client, 0), NX_AZURE_IOT_THROTTLED); + + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + while (nx_azure_iot_hub_client_device_twin_properties_request(&iot_client, 0)) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + generate_device_twin_document_response(&iot_client); + assert_int_equal(nx_azure_iot_hub_client_device_twin_properties_receive(&iot_client, &packet_ptr, 0), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_memory_equal(result_buffer, test_device_twin_document_response_payload, sizeof(test_device_twin_document_response_payload) - 1); + + nx_packet_release(packet_ptr); +} + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ + NX_AZURE_TEST_FN tests[] = { test_nx_azure_iot_hub_client_device_twin_enable_invalid_argument_failure, + test_nx_azure_iot_hub_client_device_twin_enable_failure, + test_nx_azure_iot_hub_client_device_twin_enable_success, + test_nx_azure_iot_hub_client_device_twin_disable_invalid_argument_failure, + test_nx_azure_iot_hub_client_device_twin_disable_failure, + test_nx_azure_iot_hub_client_device_twin_disable_success, + test_nx_azure_iot_hub_client_reported_properties_response_callback_set_invalid_argument_failure, + test_nx_azure_iot_hub_client_reported_properties_response_callback_set_success, + test_nx_azure_iot_hub_client_report_properties_response_callback_set_invalid_argument_failure, + test_nx_azure_iot_hub_client_report_properties_response_callback_set_success, + test_nx_azure_iot_hub_client_device_twin_reported_propetries_send_invalid_argument_failure, + test_nx_azure_iot_hub_client_device_twin_reported_propetries_send_publish_failure, + test_nx_azure_iot_hub_client_device_twin_reported_propetries_send_success, + test_nx_azure_iot_hub_client_device_twin_reported_propetries_send_throttled, + test_nx_azure_iot_hub_client_device_twin_propetries_request_invalid_argument_failure, + test_nx_azure_iot_hub_client_device_twin_propetries_request_publish_failure, + test_nx_azure_iot_hub_client_device_twin_propetries_request_success, + test_nx_azure_iot_hub_client_device_twin_propetries_request_no_blocking_success, + test_nx_azure_iot_hub_client_device_twin_propetries_request_throttle, + test_nx_azure_iot_hub_client_device_twin_propetries_request_allocation_fail_failure, + test_nx_azure_iot_hub_client_device_twin_desired_properties_receive_invalid_argument_failure, + test_nx_azure_iot_hub_client_device_twin_desired_properties_receive_success, + test_nx_azure_iot_hub_client_device_twin_desired_properties_receive_no_blocking_success, + test_nx_azure_iot_hub_client_device_twin_no_receive, + test_nx_azure_iot_hub_client_device_twin_receive_invalid_argument_failure, + test_nx_azure_iot_hub_client_device_twin_desired_properties_receive_allocation_fail_failure }; + INT number_of_tests = sizeof(tests)/sizeof(tests[0]); + g_ip_ptr = ip_ptr; + g_pool_ptr = pool_ptr; + g_dns_ptr = dns_ptr; + + test_suit_begin(); + + printf("Number of tests %d\r\n", number_of_tests); + for (INT index = 0; index < number_of_tests; index++) + { + test_begin(); + tests[index](); + test_end(); + } + + test_suit_end(); +} diff --git a/test/regression/azure_iot/direct_method_unit_test.c b/test/regression/azure_iot/direct_method_unit_test.c new file mode 100644 index 00000000..fc9de791 --- /dev/null +++ b/test/regression/azure_iot/direct_method_unit_test.c @@ -0,0 +1,694 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +#ifndef MAXIMUM_PAYLOAD_LENGTH +#define MAXIMUM_PAYLOAD_LENGTH 10240 +#endif /* MAXIMUM_PAYLOAD_LENGTH */ + +typedef VOID (*NX_AZURE_TEST_FN)(); + + +static UCHAR g_hostname[] = "unit-test.iot-azure.com"; +static UCHAR g_device_id[] = "unit_test_device"; + +static const CHAR direct_method_response_topic[] = "$iothub/methods/POST/test_method/?$rid=1"; +static const CHAR test_method_response_payload[] = "{\"method\" : \"test_method\", \"parameter\": 1}"; +static const CHAR test_method_name[] = "test_method"; +static const CHAR test_request_id[] = "1"; +static const CHAR test_send_payload[] = "{\"return\" : \"OK\"}"; + +static UINT g_total_append = 0; +static UINT g_failed_append_index = 0; +static UINT g_total_allocation = 0; +static UINT g_failed_allocation_index = -1; +static NX_IP* g_ip_ptr; +static NX_PACKET_POOL* g_pool_ptr; +static NX_DNS* g_dns_ptr; +static ULONG g_available_packet; +static CHAR *g_expected_message; + +extern UINT _nxd_mqtt_client_append_message(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, CHAR *message, + UINT length, ULONG wait_option); +extern UINT _nxd_mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + UCHAR control_header, UINT length, UINT wait_option); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +static UCHAR message_payload[MAXIMUM_PAYLOAD_LENGTH]; +static UCHAR result_buffer[MAXIMUM_PAYLOAD_LENGTH]; +static VOID (*test_receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count) = NX_NULL; + +UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr, + VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count)) +{ + printf("HIJACKED: %s\n", __func__); + test_receive_notify = receive_notify; + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_subscribe(NXD_MQTT_CLIENT *client_ptr, UINT op, + CHAR *topic_name, UINT topic_name_length, + USHORT *packet_id_ptr, UINT QoS) +{ + printf("HIJACKED: %s\n", __func__); + + return((UINT)mock()); +} + +UINT __wrap__nxde_mqtt_client_unsubscribe(NXD_MQTT_CLIENT *client_ptr, CHAR *topic_name, + UINT topic_name_length, UINT QoS) +{ + printf("HIJACKED: %s\n", __func__); + return((UINT)mock()); +} + +UINT __real__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option); +UINT __wrap__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_append_index == g_total_append) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_append++; + return __real__nx_packet_data_append(packet_ptr, data_start, data_size, pool_ptr, wait_option); +} + +UINT __real_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context); +UINT __wrap_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_allocation_index == g_total_allocation) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_allocation++; + return __real_nx_azure_iot_buffer_allocate(nx_azure_iot_ptr, buffer_pptr, buffer_size, buffer_context); +} + +UINT __wrap__nxd_mqtt_client_publish_packet_send(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + USHORT packet_id, UINT QoS, ULONG wait_option) +{ +UINT topic_name_length; +UINT message_length; +UCHAR *buffer_ptr; +UINT status = (UINT)mock(); + + printf("HIJACKED: %s\n", __func__); + tx_mutex_put(client_ptr -> nxd_mqtt_client_mutex_ptr); + + if (status) + { + return(status); + } + + buffer_ptr = packet_ptr -> nx_packet_prepend_ptr; + topic_name_length = (buffer_ptr[5] << 8) | (buffer_ptr[6]); + message_length = packet_ptr -> nx_packet_length - (9 + topic_name_length); + assert_memory_equal(&buffer_ptr[7 + topic_name_length], g_expected_message, message_length); + assert_int_equal(QoS, 0); + + /* packet ownership taken and released */ + nx_packet_release(packet_ptr); + + return(status); +} + +UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, + UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *, + NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *), + UINT keepalive, UINT clean_session, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + + tx_thread_suspend(&(iot.nx_azure_iot_ip_ptr -> nx_ip_thread)); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + client_ptr -> nxd_mqtt_client_packet_identifier = 1; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_FALSE; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &client_ptr -> nxd_mqtt_client_socket; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr) +{ + printf("HIJACKED: %s\n", __func__); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ + printf("HIJACKED: %s\n", __func__); + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NX_DNS_SUCCESS); +} + +static VOID on_receive_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, VOID *arg) +{ + *((UINT *)arg) = 1; +} + +static UINT mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, UCHAR control_header, UINT length, UINT wait_option) +{ +UCHAR fixed_header[5]; +UCHAR *byte = fixed_header; +UINT count = 0; +UINT ret; + + *byte = control_header; + byte++; + + do + { + if (length & 0xFFFFFF80) + { + *(byte + count) = (UCHAR)((length & 0x7F) | 0x80); + } + else + { + *(byte + count) = length & 0x7F; + } + length = length >> 7; + + count++; + } while (length != 0); + + ret = __real__nx_packet_data_append(packet_ptr, fixed_header, count + 1, + client_ptr -> nxd_mqtt_client_packet_pool_ptr, wait_option); + + return(ret); +} + +static VOID construct_direct_method_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, + const UCHAR *topic, ULONG topic_len, + const UCHAR *message_payload_ptr, ULONG message_payload_length, + NX_PACKET **packet_pptr) +{ +NX_PACKET *packet_ptr; +ULONG total_length; +ULONG topic_length = topic_len; +UCHAR bytes[2]; +UINT i; + + assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + total_length = topic_length + 2 + 2 + message_payload_length; /* Two bytes for fixed topic_length field + and two bytes for packet id. */ + + /* Set fixed header. */ + assert_int_equal(mqtt_client_set_fixed_header(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt), packet_ptr, + (UCHAR)((MQTT_CONTROL_PACKET_TYPE_PUBLISH << 4) | MQTT_PUBLISH_QOS_LEVEL_1), + total_length, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic length. */ + bytes[0] = (topic_length >> 8) & 0xFF; + bytes[1] = topic_length & 0xFF; + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)topic, topic_len, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + /* Set packet ID. The value does not matter. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set message payload. */ + if (message_payload_length > 0) + { + assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)message_payload_ptr, message_payload_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + + *packet_pptr = packet_ptr; +} + +static VOID generate_direct_method_response(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr) +{ +NX_PACKET *packet_ptr; + + construct_direct_method_response(hub_client_ptr, direct_method_response_topic, sizeof(direct_method_response_topic) - 1, + test_method_response_payload, sizeof(test_method_response_payload) - 1, + &packet_ptr); + + /* Simulate callback from MQTT layer. */ + hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt.message_receive_queue_head = packet_ptr; + hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt.message_receive_queue_depth = 1; + tx_mutex_get(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, NX_WAIT_FOREVER); + test_receive_notify(&(hub_client_ptr -> nx_azure_iot_hub_client_resource.resource_mqtt), 1); + tx_mutex_put(hub_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr); +} + +static VOID reset_global_state() +{ + /* reset global state */ + g_failed_append_index = (UINT)-1; + g_total_append = 0; + g_failed_allocation_index = (UINT)-1; + g_total_allocation = 0; + g_expected_message = NX_NULL; +} + +/* Hook execute before all tests. */ +static VOID test_suit_begin() +{ + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, + (UCHAR *)_nx_azure_iot_root_cert, + (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", + g_ip_ptr, g_pool_ptr, g_dns_ptr, + (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), + DEMO_CLOUD_THREAD_PRIORITY, unix_time_get), + NX_AZURE_IOT_SUCCESS); + + /* Record number of available packet before test */ + g_available_packet = g_pool_ptr -> nx_packet_pool_available; + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + g_hostname, sizeof(g_hostname), + g_device_id, sizeof(g_device_id), + "", 0, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Connect IoTHub client */ + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_suit_end() +{ + + /* Disconnect IoTHub client */ + assert_int_equal(nx_azure_iot_hub_client_disconnect(&iot_client), NX_AZURE_IOT_SUCCESS); + + /* Check if all the packet are released */ + assert_int_equal(g_pool_ptr -> nx_packet_pool_available, g_available_packet); + + /* Deinitialize IoTHub Client */ + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: iot is deleted. */ + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); +} + +/* Hook executed before every test */ +static VOID test_begin() +{ + reset_global_state(); +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_end() +{ +} + +/** + * Test direct method enable with invalid argument failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_enable_invalid_argument_failure() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_enable(NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test direct method enable with unsuccessful subscribe failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_enable_failure() +{ + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_NOT_SUCCESSFUL); + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test direct method enable succeeds. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_enable_success() +{ + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_direct_method_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test direct method disable with invalid argument failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_disable_invalid_argument_failure() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_disable(NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test direct method disable with unsuccessful un-subscribe failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_disable_failure() +{ + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_unsubscribe, NX_NOT_SUCCESSFUL); + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_disable(&iot_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test direct method disable succeeds. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_disable_success() +{ + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_unsubscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_direct_method_disable(&iot_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test direct method receive with invalid argument failed. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_message_receive_invalid_argument_failure() +{ +const UCHAR *method_name_ptr; +USHORT method_name_length; +VOID *context_ptr; +USHORT context_length; +NX_PACKET *packet_ptr; + + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_message_receive(NX_NULL, + &method_name_ptr, &method_name_length, + &context_ptr, &context_length, + &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test direct method receive succeeds. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_message_receive_success() +{ +const UCHAR *method_name_ptr; +USHORT method_name_length; +VOID *context_ptr; +USHORT context_length; +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_direct_method_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + generate_direct_method_response(&iot_client); + + assert_int_equal(nx_azure_iot_hub_client_direct_method_message_receive(&iot_client, + &method_name_ptr, &method_name_length, + &context_ptr, &context_length, + &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_memory_equal(method_name_ptr, test_method_name, sizeof(test_method_name) - 1); + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_memory_equal(result_buffer, test_method_response_payload, sizeof(test_method_response_payload) - 1); + + nx_packet_release(packet_ptr); +} + +/** + * Test direct method receive succeeds with NX_NO_WAIT. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_message_receive_no_blocking_success() +{ +const UCHAR *method_name_ptr; +USHORT method_name_length; +VOID *context_ptr; +USHORT context_length; +NX_PACKET *packet_ptr; +ULONG bytes_copied; +UINT received = 0; + + printf("test starts =>: %s\n", __func__); + + assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iot_client, + NX_AZURE_IOT_HUB_DIRECT_METHOD, + on_receive_callback, + (VOID *)&received), + NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_direct_method_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + generate_direct_method_response(&iot_client); + + while (!received) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(nx_azure_iot_hub_client_direct_method_message_receive(&iot_client, + &method_name_ptr, &method_name_length, + &context_ptr, &context_length, + &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + assert_memory_equal(method_name_ptr, test_method_name, sizeof(test_method_name) - 1); + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_memory_equal(result_buffer, test_method_response_payload, sizeof(test_method_response_payload) - 1); + + nx_packet_release(packet_ptr); +} + +/** + * Test no one is receiving direct method. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_message_no_receive() +{ +const UCHAR *method_name_ptr; +USHORT method_name_length; +VOID *context_ptr; +USHORT context_length; +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + printf("test starts =>: %s\n", __func__); + + will_return(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_direct_method_enable(&iot_client), + NX_AZURE_IOT_SUCCESS); + generate_direct_method_response(&iot_client); +} + + +/** + * Test direct method response invalid argument fail. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_message_response_invalid_argument_fail() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_message_response(NX_NULL, + 200, (VOID *)test_request_id, sizeof(test_request_id) - 1, + (UCHAR *)test_send_payload, sizeof(test_send_payload) - 1, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_message_response(&iot_client, + 200, NX_NULL, 0, + (UCHAR *)test_send_payload, sizeof(test_send_payload) - 1, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + + +/** + * Test direct method response send fail. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_message_response_send_failure_fail() +{ + printf("test starts =>: %s\n", __func__); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_NOT_SUCCESSFUL); + + assert_int_not_equal(nx_azure_iot_hub_client_direct_method_message_response(&iot_client, + 200, (VOID *)test_request_id, sizeof(test_request_id) - 1, + (UCHAR *)test_send_payload, sizeof(test_send_payload) - 1, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test direct method response succeeds. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_message_response_success() +{ + printf("test starts =>: %s\n", __func__); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + g_expected_message = (CHAR *)test_send_payload; + + assert_int_equal(nx_azure_iot_hub_client_direct_method_message_response(&iot_client, + 200, (VOID *)test_request_id, sizeof(test_request_id) - 1, + (UCHAR *)test_send_payload, sizeof(test_send_payload) - 1, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test direct method response empty json succeeds. + * + **/ +static VOID test_nx_azure_iot_hub_client_direct_method_message_response_empty_success() +{ + printf("test starts =>: %s\n", __func__); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + g_expected_message = (CHAR *)"{}"; + + assert_int_equal(nx_azure_iot_hub_client_direct_method_message_response(&iot_client, + 200, (VOID *)test_request_id, sizeof(test_request_id) - 1, + NX_NULL, 0, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ + NX_AZURE_TEST_FN tests[] = { test_nx_azure_iot_hub_client_direct_method_enable_invalid_argument_failure, + test_nx_azure_iot_hub_client_direct_method_enable_failure, + test_nx_azure_iot_hub_client_direct_method_enable_success, + test_nx_azure_iot_hub_client_direct_method_disable_invalid_argument_failure, + test_nx_azure_iot_hub_client_direct_method_disable_failure, + test_nx_azure_iot_hub_client_direct_method_disable_success, + test_nx_azure_iot_hub_client_direct_method_message_receive_invalid_argument_failure, + test_nx_azure_iot_hub_client_direct_method_message_receive_success, + test_nx_azure_iot_hub_client_direct_method_message_receive_no_blocking_success, + test_nx_azure_iot_hub_client_direct_method_message_no_receive, + test_nx_azure_iot_hub_client_direct_method_message_response_invalid_argument_fail, + test_nx_azure_iot_hub_client_direct_method_message_response_send_failure_fail, + test_nx_azure_iot_hub_client_direct_method_message_response_success, + test_nx_azure_iot_hub_client_direct_method_message_response_empty_success }; + INT number_of_tests = sizeof(tests)/sizeof(tests[0]); + g_ip_ptr = ip_ptr; + g_pool_ptr = pool_ptr; + g_dns_ptr = dns_ptr; + + test_suit_begin(); + + printf("Number of tests %d\r\n", number_of_tests); + for (INT index = 0; index < number_of_tests; index++) + { + test_begin(); + tests[index](); + test_end(); + } + + test_suit_end(); +} diff --git a/test/regression/azure_iot/initialization_unit_test.c b/test/regression/azure_iot/initialization_unit_test.c new file mode 100644 index 00000000..87322501 --- /dev/null +++ b/test/regression/azure_iot/initialization_unit_test.c @@ -0,0 +1,362 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +UINT __wrap__nxde_mqtt_client_delete(NXD_MQTT_CLIENT *client_ptr); +UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr, + VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr, + UINT message_count)); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_AZURE_IOT_HUB_CLIENT iot_clients[3]; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +extern int g_argc; +extern char **g_argv; +extern NX_AZURE_IOT *_nx_azure_iot_created_ptr; + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ +CHAR *host_name = "host_name"; +CHAR *device_id = "device_id"; +CHAR *module_id = "module_id"; +CHAR *symmetric_key = "symmetric_key"; +UINT i; + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert, (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + /*********** Test nx_azure_iot_create() ***********/ + /* FAIL: NX_AZURE_IOT pointer is null. */ + assert_int_not_equal(nx_azure_iot_create(NX_NULL, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: NX_IP pointer is null. */ + assert_int_not_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", NX_NULL, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: NX_PACKET_POOL pointer is null. */ + assert_int_not_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, NX_NULL, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: NX_DNS pointer is null. */ + assert_int_not_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, NX_NULL, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: stack pointer is null. */ + assert_int_not_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, NX_NULL, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: stack size is 0. */ + assert_int_not_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + 0, DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: all parameters are valid. */ + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /*********** Test nx_azure_iot_delete() ***********/ + /* FAIL: NX_AZURE_IOT pointer is null. */ + assert_int_not_equal(nx_azure_iot_delete(NX_NULL), NX_AZURE_IOT_SUCCESS); + + /* FAIL: nx_cloud_delete fail. */ + /* Manually set nx_cloud_modules_count to none zero. */ + iot.nx_azure_iot_cloud.nx_cloud_modules_count++; + assert_int_not_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); + iot.nx_azure_iot_cloud.nx_cloud_modules_count--; + + /* SUCCESS: iot is created. */ + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); + + + /*********** Test nx_azure_iot_hub_client_initialize() ***********/ + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: NX_AZURE_IOT pointer is null. */ + assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, NX_NULL, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(module_id), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: NX_AZURE_IOT_HUB_CLIENT pointer is null. */ + assert_int_not_equal(nx_azure_iot_hub_client_initialize(NX_NULL, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(module_id), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: host_name pointer is null. */ + assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + NX_NULL, 0, + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(module_id), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: device_id pointer is null. */ + assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + NX_NULL, 0, + STRING_UNSIGNED_ARGS(module_id), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: host_name_length is 0. */ + assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + "", 0, + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(module_id), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: device_id_length is 0. */ + assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + "", 0, + STRING_UNSIGNED_ARGS(module_id), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: invalidate cloud_id manually. */ + iot.nx_azure_iot_cloud.nx_cloud_id = 0; + assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(module_id), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + iot.nx_azure_iot_cloud.nx_cloud_id = NX_CLOUD_ID; + + /* FAIL: nxd_mqtt_client_receive_notify_set will fail by hijacked function. */ + will_return(__wrap__nxde_mqtt_client_receive_notify_set, NXD_MQTT_INVALID_PARAMETER); + will_return(__wrap__nxde_mqtt_client_delete, NXD_MQTT_SUCCESS); + assert_int_not_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(module_id), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: all parameters are valid. */ + will_return_always(__wrap__nxde_mqtt_client_receive_notify_set, NXD_MQTT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_delete, NXD_MQTT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(module_id), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: all parameters are valid and module_id pointer is null. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + NX_NULL, 0, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + will_return(__wrap__nxde_mqtt_client_delete, NXD_MQTT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: all parameters are valid and module_id pointer is null. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + NX_NULL, 0, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + + /*********** Test nx_azure_iot_hub_client_deinitialize() ***********/ + /* FAIL: NX_AZURE_IOT_HUB_CLIENT pointer is null. */ + assert_int_not_equal(nx_azure_iot_hub_client_deinitialize(NX_NULL), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: iot_client is not deleted yet. */ + assert_int_not_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); + + /* FAIL: nxd_mqtt_client_delete will fail by hijacked function. */ + will_return(__wrap__nxde_mqtt_client_delete, NXD_MQTT_INVALID_PARAMETER); + assert_int_not_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* SUCCESS: iot_client is created. */ + will_return_always(__wrap__nxde_mqtt_client_delete, NXD_MQTT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: iot_client is already deleted. */ + assert_int_not_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + + /*********** Test multiple nx_azure_iot_hub_client_initialize()/deinitialize() ***********/ + for (i = 0; i < sizeof(iot_clients) / sizeof(NX_AZURE_IOT_HUB_CLIENT); i++) + { + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_clients[i], &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + NX_NULL, 0, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + } + + /* Manually remove the header of nx_azure_iot_hub_client_list_header. */ + /* FAIL: this one removed from nx_azure_iot_hub_client_list_header. */ + _nx_azure_iot_created_ptr -> nx_azure_iot_resource_list_header = _nx_azure_iot_created_ptr -> nx_azure_iot_resource_list_header -> resource_next; + assert_int_not_equal(nx_azure_iot_hub_client_deinitialize(&iot_clients[sizeof(iot_clients) / sizeof(NX_AZURE_IOT_HUB_CLIENT) - 1]), + NX_AZURE_IOT_SUCCESS); + + for (i = 0; i < sizeof(iot_clients) / sizeof(NX_AZURE_IOT_HUB_CLIENT) - 1; i++) + { + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_clients[i]), + NX_AZURE_IOT_SUCCESS); + } + + + /* SUCCESS: iot is created. */ + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); + + /* Check if all the packet are released */ + assert_int_equal(pool_ptr -> nx_packet_pool_available, pool_ptr -> nx_packet_pool_total); +} + +UINT __real__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr, + VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr, + UINT message_count)); +UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr, + VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr, + UINT message_count)) +{ + if ((UINT)mock() != NXD_MQTT_SUCCESS) + { + printf("HIJACKED: %s\n", __func__); + return(NXD_MQTT_INVALID_PARAMETER); + } + return(__real__nxde_mqtt_client_receive_notify_set(client_ptr, receive_notify)); +} + +UINT __real__nxde_mqtt_client_delete(NXD_MQTT_CLIENT *client_ptr); +UINT __wrap__nxde_mqtt_client_delete(NXD_MQTT_CLIENT *client_ptr) +{ + if ((UINT)mock() != NXD_MQTT_SUCCESS) + { + printf("HIJACKED: %s\n", __func__); + return(NXD_MQTT_INVALID_PARAMETER); + } + return(__real__nxde_mqtt_client_delete(client_ptr)); +} diff --git a/test/regression/azure_iot/iot_provisioning_client_unit_test.c b/test/regression/azure_iot/iot_provisioning_client_unit_test.c new file mode 100644 index 00000000..3bd94a40 --- /dev/null +++ b/test/regression/azure_iot/iot_provisioning_client_unit_test.c @@ -0,0 +1,1965 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot_provisioning_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +#ifndef MAXIMUM_PROPERTY_BUFFER +#define MAXIMUM_PROPERTY_BUFFER 256 +#endif /* MAXIMUM_PROPERTY_BUFFER */ + +#ifndef TEST_DEFAULT_WAIT_TIME +#define TEST_DEFAULT_WAIT_TIME 500 +#endif /* TEST_DEFAULT_WAIT_TIME */ + +#define PROVISIONING_SERVICE_REPONSE_TOPIC "$dps/registrations/res/202/?" +#define PROVISIONING_SERVICE_REPONSE_200_TOPIC "$dps/registrations/res/200/?" +#define PROVISIONING_SERVICE_REPONSE_BAD_TOPIC "$dps/registrations/res/401/?" +#define PROVISIONING_SERVICE_REPONSE_THROTTLE_TOPIC "$dps/registrations/res/429/?" + +#define CUSTOM_PAYLOAD "{\"modelId\":\"pnp_model\"}" + +typedef VOID (*NX_AZURE_TEST_FN)(); + +typedef struct +{ + UCHAR *name; + ULONG name_length; + UCHAR *value; + ULONG value_length; +} PROPERTY; + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_PROVISIONING_CLIENT iot_prov_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; + +static const CHAR *expected_register_topic_start = "$dps/registrations/PUT/iotdps-register/?$rid="; +static const CHAR *expected_query_topic_start = "$dps/registrations/GET/iotdps-get-operationstatus/?$rid="; +static const CHAR *expected_message = "{\"registrationId\" : \"reg_id\"}"; +static const CHAR *expected_message_with_custom_payload = "{\"registrationId\" : \"reg_id\", \"payload\" : "CUSTOM_PAYLOAD"}"; +static const CHAR assigned_hub_response[] = "{ \ + \"operationId\":\"4.002305f54fc89692.b1f11200-8776-4b5d-867b-dc21c4b59c12\",\"status\":\"assigned\",\"registrationState\": \ + {\"registrationId\":\"reg_id\",\"createdDateTimeUtc\":\"2019-12-27T19:51:41.6630592Z\",\"assignedHub\":\"test.azure-iothub.com\", \ + \"deviceId\":\"testId\",\"status\":\"assigned\",\"substatus\":\"initialAssignment\",\"lastUpdatedDateTimeUtc\":\"2019-12-27T19:51:41.8579703Z\", \ + \"etag\":\"XXXXXXXXXXX=\"\ + }\ +}"; +static const CHAR failure_hub_response[] = "{ \ + \"operationId\":\"4.002305f54fc89692.b1f11200-8776-4b5d-867b-dc21c4b59c12\",\"status\":\"failed\",\"registrationState\": \ + {\"registrationId\":\"reg_id\",\"createdDateTimeUtc\":\"2019-12-27T19:51:41.6630592Z\",\ + \"status\":\"failed\",\"errorCode\":400207,\"errorMessage\":\"Custom allocation failed with status code: 400\",\ + \"lastUpdatedDateTimeUtc\":\"2019-12-27T19:51:41.8579703Z\", \ + \"etag\":\"XXXXXXXXXXX=\"\ + }\ +}"; +static const CHAR *assigned_hub_name = "test.azure-iothub.com"; +static const CHAR *assigned_device_id = "testId"; +static const CHAR assigning_hub_response[] = "{ \ + \"operationId\":\"4.002305f54fc89692.b1f11200-8776-4b5d-867b-dc21c4b59c12\",\"status\":\"assigning\" \ +}"; +static const CHAR *invalid_response_data_set[] = { + + /* operationId in the response is invalid */ + "{ \ + \"operationId\": [],\"status\":\"assigned\",\"registrationState\": \ + {\"registrationId\":\"reg_id\",\"createdDateTimeUtc\":\"2019-12-27T19:51:41.6630592Z\",\"assignedHub\":\"test.azure-iothub.com\", \ + \"deviceId\":\"testId\",\"status\":\"assigned\",\"substatus\":\"initialAssignment\",\"lastUpdatedDateTimeUtc\":\"2019-12-27T19:51:41.8579703Z\", \ + \"etag\":\"XXXXXXXXXXX=\"\ + }\ + }", + + /* status in the response is invalid */ + "{ \ + \"operationId\":\"4.002305f54fc89692.b1f11200-8776-4b5d-867b-dc21c4b59c12\",\"status\":[],\"registrationState\": \ + {\"registrationId\":\"reg_id\",\"createdDateTimeUtc\":\"2019-12-27T19:51:41.6630592Z\",\"assignedHub\":\"test.azure-iothub.com\", \ + \"deviceId\":\"testId\",\"status\":[],\"substatus\":\"initialAssignment\",\"lastUpdatedDateTimeUtc\":\"2019-12-27T19:51:41.8579703Z\", \ + \"etag\":\"XXXXXXXXXXX=\"\ + }\ + }", + + /* invalid deviceId in the response */ + "{ \ + \"operationId\":\"4.002305f54fc89692.b1f11200-8776-4b5d-867b-dc21c4b59c12\",\"status\":\"assigned\",\"registrationState\": \ + {\"registrationId\":\"reg_id\",\"createdDateTimeUtc\":\"2019-12-27T19:51:41.6630592Z\",\"assignedHub\":\"test.azure-iothub.com\", \ + \"deviceId\":[],\"status\":\"assigned\",\"substatus\":\"initialAssignment\",\"lastUpdatedDateTimeUtc\":\"2019-12-27T19:51:41.8579703Z\", \ + \"etag\":\"XXXXXXXXXXX=\"\ + }\ + }", + + /* invalid assignedHub in the response */ + "{ \ + \"operationId\":\"4.002305f54fc89692.b1f11200-8776-4b5d-867b-dc21c4b59c12\",\"status\":\"assigned\",\"registrationState\": \ + {\"registrationId\":\"reg_id\",\"createdDateTimeUtc\":\"2019-12-27T19:51:41.6630592Z\",\"assignedHub\":[], \ + \"deviceId\":\"test1\",\"status\":\"assigned\",\"substatus\":\"initialAssignment\",\"lastUpdatedDateTimeUtc\":\"2019-12-27T19:51:41.8579703Z\", \ + \"etag\":\"XXXXXXXXXXX=\"\ + }\ + }", + + /* no JSON object return via dps */ + "[\"invalid dps response json\"]", + + /* Invalid JSON */ + "[\"invalid json\"}" + + /* Invalid JSON */ + "\n" +}; +static const CHAR throttle_hub_response[] = "{ \ + \"errorCode\":429001, \ + \"trackingId\":\"\",\"message\":\"Operations are being throttled for this tenant.\", \ + \"timestampUtc\":\"2021-10-26T00:02:24.263671Z\" \ +}"; +static CHAR *symmetric_key = "MTIzNDU2Nzg5MGFiY2RlZmdoaWprbG1ub3BxcnN0dXY=="; /* 1234567890abcdefghijklmnopqrstuv */ + +static NX_IP* g_ip_ptr; +static NX_PACKET_POOL* g_pool_ptr; +static NX_DNS* g_dns_ptr; +static ULONG g_available_packet; + +static CHAR g_endpoint[] = "host_name"; +static CHAR g_id_scope[] = "id_scope"; +static CHAR g_reg_id[] = "reg_id"; +static CHAR g_SAS_token[] = "SAS_token"; +static UINT g_done = 0; +static UINT g__wrap__nxde_mqtt_client_secure_connect_status = 0; +static UINT g__wrap__nxde_mqtt_client_subscribe_status = 0; +static UINT g__wrap__nxde_mqtt_client_disconnect_status = 0; +static UINT g__wrap__nxd_mqtt_client_publish_packet_send_status = 0; +static UINT g__wrap__nxde_dns_host_by_name_get_status = 0; +static UINT g_req_id = 0; +static UINT g_assigned_response_after = 0; +static UINT g_total_append = 0; +static UINT g_failed_append_index = 0; +static UINT g_total_allocation = 0; +static UINT g_failed_allocation_index = 0; +static UCHAR property_value[MAXIMUM_PROPERTY_BUFFER]; +static UCHAR property_value2[MAXIMUM_PROPERTY_BUFFER]; +static PROPERTY req_id_property = { "$rid", sizeof("$rid") - 1, property_value, sizeof(property_value) }; +static PROPERTY retry_after_property = { "retry-after", sizeof("retry-after") - 1 , property_value2, sizeof(property_value2) }; +static VOID (*test_receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count) = NX_NULL; +static VOID (*test_connect_notify)(struct NXD_MQTT_CLIENT_STRUCT *client_ptr, UINT status, VOID *context) = NX_NULL; +static VOID *test_connect_notify_context = NX_NULL; +static VOID (*test_disconnect_notify)(struct NXD_MQTT_CLIENT_STRUCT *client_ptr) = NX_NULL; +static UCHAR iothub_hostname[32]; +static UCHAR iothub_device_id[32]; + +UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, + UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *, + NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *), + UINT keepalive, UINT clean_session, ULONG wait_option) +{ +UINT status = g__wrap__nxde_mqtt_client_secure_connect_status; + + printf("HIJACKED: %s\n", __func__); + if (status) + { + return(status); + } + + tx_thread_suspend(&(iot.nx_azure_iot_ip_ptr -> nx_ip_thread)); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + client_ptr -> nxd_mqtt_client_packet_identifier = 1; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_FALSE; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &client_ptr -> nxd_mqtt_client_socket; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + client_ptr -> nxd_mqtt_connect_notify(client_ptr, NXD_MQTT_SUCCESS, client_ptr -> nxd_mqtt_connect_context); + test_connect_notify = client_ptr -> nxd_mqtt_connect_notify; + test_connect_notify_context = client_ptr -> nxd_mqtt_connect_context; + test_disconnect_notify = client_ptr -> nxd_mqtt_disconnect_notify; + + return(status); +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ +UINT status = g__wrap__nxde_dns_host_by_name_get_status; + + printf("HIJACKED: %s\n", __func__); + if (status) + { + return(status); + } + + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NX_DNS_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_subscribe(NXD_MQTT_CLIENT *client_ptr, CHAR *topic_name, + UINT topic_name_length, UINT QoS) +{ + printf("HIJACKED: %s\n", __func__); + return(g__wrap__nxde_mqtt_client_subscribe_status); +} + +UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr) +{ +UINT status = g__wrap__nxde_mqtt_client_disconnect_status; + + printf("HIJACKED: %s\n", __func__); + if (status) + { + return(status); + } + + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + return(status); +} + +UINT __wrap__nxd_mqtt_client_publish_packet_send(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + USHORT packet_id, UINT QoS, ULONG wait_option) +{ +INT topic_name_length; +UINT message_length; +UCHAR *buffer_ptr; +UCHAR *topic_ptr; +UINT status = g__wrap__nxd_mqtt_client_publish_packet_send_status; + + printf("HIJACKED: %s\n", __func__); + + if (status) + { + return(status); + } + + buffer_ptr = packet_ptr -> nx_packet_prepend_ptr; + topic_name_length = (buffer_ptr[5] << 8) | (buffer_ptr[6]); + message_length = packet_ptr -> nx_packet_length - (9 + topic_name_length); + topic_ptr = &buffer_ptr[7]; + + /* Check if it is query or register request */ + if (strstr((CHAR *)topic_ptr, "operationId=") != NULL) + { + assert_memory_equal(topic_ptr, expected_query_topic_start, strlen(expected_query_topic_start)); + assert_int_equal(sscanf((CHAR *)&topic_ptr[strlen(expected_query_topic_start)], "%u", &g_req_id), 1); + } + else + { + assert_memory_equal(topic_ptr, expected_register_topic_start, strlen(expected_register_topic_start)); + assert_int_equal(sscanf((CHAR *)&topic_ptr[strlen(expected_register_topic_start)], "%u", &g_req_id), 1); + } + + if (iot_prov_client.nx_azure_iot_provisioning_client_registration_payload) + { + assert_int_equal(message_length, strlen(expected_message_with_custom_payload)); + assert_memory_equal(&buffer_ptr[9 + topic_name_length], + expected_message_with_custom_payload, message_length); + } + else + { + assert_int_equal(message_length, strlen(expected_message)); + assert_memory_equal(&buffer_ptr[9 + topic_name_length], expected_message, message_length); + } + + assert_int_equal(QoS, 1); + + /* packet ownership taken and released */ + nx_packet_release(packet_ptr); + + return(status); +} + +UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr, + VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count)) +{ + printf("HIJACKED: %s\n", __func__); + test_receive_notify = receive_notify; + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __real__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option); +UINT __wrap__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_append_index == g_total_append) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_append++; + return __real__nx_packet_data_append(packet_ptr, data_start, data_size, pool_ptr, wait_option); +} + +UINT __real_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context); +UINT __wrap_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_allocation_index == g_total_allocation) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_allocation++; + return __real_nx_azure_iot_buffer_allocate(nx_azure_iot_ptr, buffer_pptr, buffer_size, buffer_context); +} + +static UINT mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, UCHAR control_header, UINT length, UINT wait_option) +{ +UCHAR fixed_header[5]; +UCHAR *byte = fixed_header; +UINT count = 0; +UINT ret; + + *byte = control_header; + byte++; + + do + { + if (length & 0xFFFFFF80) + { + *(byte + count) = (UCHAR)((length & 0x7F) | 0x80); + } + else + { + *(byte + count) = length & 0x7F; + } + length = length >> 7; + + count++; + } while (length != 0); + + ret = __real__nx_packet_data_append(packet_ptr, fixed_header, count + 1, + client_ptr -> nxd_mqtt_client_packet_pool_ptr, wait_option); + + return(ret); +} + +static VOID on_complete_callback(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr, UINT status) +{ + g_done = 1; +} + +static VOID construct_provisioning_service_response(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr, + NX_PACKET **packet_pptr, + const UCHAR *topic, ULONG topic_len, + PROPERTY *properties, UINT property_count, + const UCHAR *message_payload_ptr, ULONG message_payload_length) +{ +NX_PACKET *packet_ptr; +ULONG total_length; +ULONG topic_length = topic_len; +UCHAR bytes[2]; +UINT i; + + assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + for (i = 0; i < property_count; i++) + { + topic_length += properties[i].name_length + properties[i].value_length + 2; /* '=' and '&' */ + } + + if (property_count) + { + topic_length--; /* Reduce by one since last '&' is not needed. */ + } + total_length = topic_length + 2 + 2 + message_payload_length; /* Two bytes for fixed topic_length field + and two bytes for packet id. */ + + /* Set fixed header. */ + assert_int_equal(mqtt_client_set_fixed_header(&(prov_client_ptr -> nx_azure_iot_provisioning_client_resource.resource_mqtt), packet_ptr, + (UCHAR)((MQTT_CONTROL_PACKET_TYPE_PUBLISH << 4) | MQTT_PUBLISH_QOS_LEVEL_1), + total_length, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic length. */ + bytes[0] = (topic_length >> 8) & 0xFF; + bytes[1] = topic_length & 0xFF; + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)topic, topic_len, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + for (i = 0; i < property_count; i++) + { + if (i != 0) + { + assert_int_equal(__real__nx_packet_data_append(packet_ptr, "&", 1, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + assert_int_equal(__real__nx_packet_data_append(packet_ptr, properties[i].name, properties[i].name_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(__real__nx_packet_data_append(packet_ptr, "=", 1, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(__real__nx_packet_data_append(packet_ptr, properties[i].value, properties[i].value_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + + /* Set packet ID. The value does not matter. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set message payload. */ + if (message_payload_length > 0) + { + assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)message_payload_ptr, message_payload_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + + *packet_pptr = packet_ptr; +} + + +static VOID generate_response(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr, + const UCHAR *topic, ULONG topic_length, + const UCHAR *message_payload_ptr, ULONG message_payload_length, + UINT retry_after) +{ +PROPERTY response_properties[2] = { retry_after_property, req_id_property }; +NX_PACKET *packet_ptr; + + /* Check if client expecting response */ + if (g_req_id == 0) + { + return; + } + + response_properties[1].value_length = snprintf(response_properties[1].value, + response_properties[1].value_length, "%u", g_req_id); + response_properties[0].value_length = snprintf(response_properties[0].value, + response_properties[0].value_length, "%u", retry_after); + /* Put Provisioning response packet to MQTT receive queue. */ + construct_provisioning_service_response(prov_client_ptr, + &packet_ptr, topic, topic_length, + response_properties, + sizeof(response_properties)/sizeof(response_properties[0]), + message_payload_ptr, message_payload_length); + + prov_client_ptr -> nx_azure_iot_provisioning_client_resource.resource_mqtt.message_receive_queue_head = packet_ptr; + prov_client_ptr -> nx_azure_iot_provisioning_client_resource.resource_mqtt.message_receive_queue_depth = 1; + + /* Expected callback function to be set. */ + assert_ptr_not_equal(test_receive_notify, NX_NULL); + + /* Simulate callback from MQTT layer. */ + tx_mutex_get(prov_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr, NX_WAIT_FOREVER); + test_receive_notify(&prov_client_ptr -> nx_azure_iot_provisioning_client_resource.resource_mqtt, 1); + tx_mutex_put(prov_client_ptr -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr); + + /* response generated for this req_id */ + g_req_id = 0; +} + +static VOID generate_good_response(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr) +{ + if (g_req_id == 0) + { + return; + } + + if (g_assigned_response_after == 0) + { + generate_response(prov_client_ptr, + PROVISIONING_SERVICE_REPONSE_TOPIC, + sizeof(PROVISIONING_SERVICE_REPONSE_TOPIC) - 1, + assigned_hub_response, sizeof(assigned_hub_response) - 1, 0); + } + else + { + generate_response(prov_client_ptr, + PROVISIONING_SERVICE_REPONSE_TOPIC, + sizeof(PROVISIONING_SERVICE_REPONSE_TOPIC) - 1, + assigning_hub_response, sizeof(assigning_hub_response) - 1, 3); + g_assigned_response_after--; + } +} + +static VOID generate_good_response_with_throttle(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr) +{ + if (g_req_id == 0) + { + return; + } + + if (g_assigned_response_after == 0) + { + generate_response(prov_client_ptr, + PROVISIONING_SERVICE_REPONSE_TOPIC, + sizeof(PROVISIONING_SERVICE_REPONSE_TOPIC) - 1, + assigned_hub_response, sizeof(assigned_hub_response) - 1, 0); + } + else + { + generate_response(prov_client_ptr, + PROVISIONING_SERVICE_REPONSE_THROTTLE_TOPIC, + sizeof(PROVISIONING_SERVICE_REPONSE_THROTTLE_TOPIC) - 1, + throttle_hub_response, sizeof(throttle_hub_response) - 1, 31); + g_assigned_response_after--; + } +} + +static VOID generate_bad_response(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr) +{ + generate_response(prov_client_ptr, + PROVISIONING_SERVICE_REPONSE_BAD_TOPIC, + sizeof(PROVISIONING_SERVICE_REPONSE_BAD_TOPIC) - 1, " ", 1, 0); +} + +static VOID generate_failure_response(NX_AZURE_IOT_PROVISIONING_CLIENT *prov_client_ptr) +{ + generate_response(prov_client_ptr, + PROVISIONING_SERVICE_REPONSE_200_TOPIC, + sizeof(PROVISIONING_SERVICE_REPONSE_200_TOPIC) - 1, + failure_hub_response, sizeof(failure_hub_response) - 1, 0); +} + +static VOID reset_global_state() +{ + /* reset global state */ + g__wrap__nxde_mqtt_client_secure_connect_status = 0; + g__wrap__nxde_mqtt_client_subscribe_status = 0; + g__wrap__nxde_mqtt_client_disconnect_status = 0; + g__wrap__nxd_mqtt_client_publish_packet_send_status = 0; + g__wrap__nxde_dns_host_by_name_get_status = 0; + g_done = 0; + g_req_id = 0; + g_assigned_response_after = 0; + g_failed_append_index = (UINT)-1; + g_total_append = 0; + g_failed_allocation_index = (UINT)-1; + g_total_allocation = 0; +} + +/* Hook execute before all tests. */ +static VOID test_suit_begin() +{ + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, + (UCHAR *)_nx_azure_iot_root_cert, + (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", + g_ip_ptr, g_pool_ptr, g_dns_ptr, + (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), + DEMO_CLOUD_THREAD_PRIORITY, unix_time_get), + NX_AZURE_IOT_SUCCESS); +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_suit_end() +{ + + /* SUCCESS: iot is deleted. */ + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); +} + +/* Hook executed before every test */ +static VOID test_begin() +{ + reset_global_state(); + + /* Record number of available packet before test */ + g_available_packet = g_pool_ptr -> nx_packet_pool_available; +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_end() +{ + + /* Check if all the packet are released */ + assert_int_equal(g_pool_ptr -> nx_packet_pool_available, g_available_packet); +} + +/** + * Test provisioning client initialization with invalid parameter + * + **/ +static VOID test_nx_azure_iot_provisioning_client_initialize_invalid_arguments() +{ + assert_int_not_equal(nx_azure_iot_provisioning_client_initialize(NX_NULL, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, NX_NULL, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + + assert_int_not_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + NX_NULL, 0, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + NX_NULL, 0, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + NX_NULL, 0, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + + assert_int_not_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + "", 0, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + "", 0, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + "", 0, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client set device cert with invalid parameter + * + **/ +static VOID test_nx_azure_iot_provisioning_client_device_cert_set_invalid_arguments() +{ + assert_int_not_equal(nx_azure_iot_provisioning_client_device_cert_set(NX_NULL, + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client set symmetric key with invalid parameter + * + **/ +static VOID test_nx_azure_iot_provisioning_client_symmetric_key_set_invalid_arguments() +{ + assert_int_not_equal(nx_azure_iot_provisioning_client_symmetric_key_set(NX_NULL, + symmetric_key, strlen(symmetric_key)), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_provisioning_client_symmetric_key_set(&iot_prov_client, + NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client register with invalid parameter + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_invalid_arguments() +{ + assert_int_not_equal(nx_azure_iot_provisioning_client_register(NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client callback set with invalid parameter + * + **/ +static VOID test_nx_azure_iot_provisioning_client_completion_callback_set_invalid_arguments() +{ + assert_int_not_equal(nx_azure_iot_provisioning_client_completion_callback_set(NX_NULL, on_complete_callback), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client deinitialization with invalid parameter + * + **/ +static VOID test_nx_azure_iot_provisioning_client_deinitialize_invalid_arguments() +{ + assert_int_not_equal(nx_azure_iot_provisioning_client_deinitialize(NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration payload set with invalid parameter + * + **/ +static VOID test_nx_azure_iot_provisioning_client_registration_payload_set_invalid_arguments() +{ + assert_int_not_equal(nx_azure_iot_provisioning_client_registration_payload_set(NX_NULL, NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client initialization + * + **/ +static VOID test_nx_azure_iot_provisioning_client_init_success() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration without initialization + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_without_initialization_fail() +{ + printf("test starts =>: %s\n", __func__); + assert_int_not_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration fails, if dns failed + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_dns_failed() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + g__wrap__nxde_dns_host_by_name_get_status = NX_NOT_SUCCESSFUL; + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration fails, if subscribe fails + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_subscribe_failed() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + g__wrap__nxde_mqtt_client_subscribe_status = NX_NOT_SUCCESSFUL; + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration fails, if publish to service fails + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_send_failed() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + g__wrap__nxd_mqtt_client_publish_packet_send_status = NX_NOT_SUCCESSFUL; + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration fails, if mqtt client disconnect while waiting for response + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_receive_failed() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + + /* Expected callback function to be set. */ + assert_ptr_not_equal(test_connect_notify, NX_NULL); + while (!g_done) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + + if (g_req_id != 0) + { + /* Generate disconnect */ + test_connect_notify(&iot_prov_client.nx_azure_iot_provisioning_client_resource.resource_mqtt, + NXD_MQTT_CONNECT_FAILURE, test_connect_notify_context); + } + } + + assert_int_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_DISCONNECTED); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); + +} + +/** + * Test provisioning client registration fails, if bad response received by client + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_receive_bad_response_failed() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + generate_bad_response(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration fails, if bad JSON response received by client + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_receive_invalid_json_failed() +{ + printf("test starts =>: %s\n", __func__); + + for (INT index = 0; index < sizeof(invalid_response_data_set)/sizeof(invalid_response_data_set[0]); index++) + { + reset_global_state(); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + + while (!g_done) + { + generate_response(&iot_prov_client, + PROVISIONING_SERVICE_REPONSE_TOPIC, + sizeof(PROVISIONING_SERVICE_REPONSE_TOPIC) - 1, + invalid_response_data_set[index], strlen(invalid_response_data_set[index]), 3); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); + } +} + +/** + * Test provisioning client registration succeeds + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_success() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_symmetric_key_set(&iot_prov_client, + symmetric_key, strlen(symmetric_key)), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + generate_good_response(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration failed with failure response + * + **/ +VOID test_nx_azure_iot_provisioning_client_register_failure_failed() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_symmetric_key_set(&iot_prov_client, + symmetric_key, strlen(symmetric_key)), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + generate_failure_response(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration with payload succeeds + * + **/ +VOID test_nx_azure_iot_provisioning_client_register_with_payload_success() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_symmetric_key_set(&iot_prov_client, + symmetric_key, strlen(symmetric_key)), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_registration_payload_set(&iot_prov_client, + CUSTOM_PAYLOAD, sizeof(CUSTOM_PAYLOAD) - 1), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + generate_good_response(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration fails with allocation fail + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_allocation_fail_failure() +{ +UINT total_allocation_in_success_case; +UINT status; + + printf("test starts =>: %s\n", __func__); + + test_nx_azure_iot_provisioning_client_register_success(); + total_allocation_in_success_case = g_total_allocation; + + for (INT index = 0; index < total_allocation_in_success_case; index++) + { + reset_global_state(); + g_failed_allocation_index = index; + + status = nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert); + + if (status) + { + continue; + } + + status = nx_azure_iot_provisioning_client_symmetric_key_set(&iot_prov_client, + symmetric_key, strlen(symmetric_key)); + if (status) + { + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); + continue; + } + + assert_int_equal(nx_azure_iot_provisioning_client_registration_payload_set(&iot_prov_client, + CUSTOM_PAYLOAD, + sizeof(CUSTOM_PAYLOAD) - 1), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + status = nx_azure_iot_provisioning_client_register(&iot_prov_client, 0); + if (status != NX_AZURE_IOT_PENDING) + { + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); + continue; + } + + while (!g_done) + { + generate_good_response(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); + } +} + +/** + * Test provisioning client registration fails with append data + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_append_data_fail_failure() +{ +UINT total_append_in_success_case; +UINT status; + + printf("test starts =>: %s\n", __func__); + + test_nx_azure_iot_provisioning_client_register_success(); + total_append_in_success_case = g_total_append; + + for (INT index = 0; index < total_append_in_success_case; index++) + { + reset_global_state(); + g_failed_append_index = index; + + status = nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert); + + if (status) + { + continue; + } + + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + status = nx_azure_iot_provisioning_client_register(&iot_prov_client, 0); + if (status != NX_AZURE_IOT_PENDING) + { + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); + continue; + } + + while (!g_done) + { + generate_good_response(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); + } +} + +/** + * Test provisioning client registration succeeds, when throttled by service. + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_with_throttle_response_success() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + g_assigned_response_after = 3; + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + generate_good_response_with_throttle(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration succeeds, when throttled by service after assigning . + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_with_throttle_response_2_success() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + g_assigned_response_after = 3; + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + if (g_assigned_response_after == 3) + { + generate_good_response(&iot_prov_client); + } + else + { + generate_good_response_with_throttle(&iot_prov_client); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration succeeds, when multiple request required. + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_with_multiple_response_success() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + g_assigned_response_after = 3; + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + generate_good_response(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration blocking fails, if dns failed + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_dns_blocking_failed() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + g__wrap__nxde_dns_host_by_name_get_status = NX_NOT_SUCCESSFUL; + + assert_int_not_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration blocking fails, if subscribe fails + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_subscribe_blocking_failed() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + g__wrap__nxde_mqtt_client_subscribe_status = NX_NOT_SUCCESSFUL; + + assert_int_not_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration blocking fails, if publish to service fails + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_send_blocking_failed() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + g__wrap__nxd_mqtt_client_publish_packet_send_status = NX_NOT_SUCCESSFUL; + + assert_int_not_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration blocking fails, if mqtt client disconnect while waiting for response + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_receive_blocking_failed() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, TEST_DEFAULT_WAIT_TIME), + NX_AZURE_IOT_PENDING); + + /* Expected callback function to be set. */ + assert_ptr_not_equal(test_connect_notify, NX_NULL); + while (!g_done) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + + if (g_reg_id != 0) + { + /* Generate disconnect */ + test_connect_notify(&iot_prov_client.nx_azure_iot_provisioning_client_resource.resource_mqtt, + NXD_MQTT_CONNECT_FAILURE, test_connect_notify_context); + } + } + + assert_int_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_DISCONNECTED); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); + +} + +/** + * Test provisioning client registration blocking fails, if bad response received by client + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_receive_bad_response_blocking_failed() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, TEST_DEFAULT_WAIT_TIME), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + generate_bad_response(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration blocking fails, if bad JSON response received by client + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_receive_invalid_json_blocking_failed() +{ + printf("test starts =>: %s\n", __func__); + + for (INT index = 0; index < sizeof(invalid_response_data_set)/sizeof(invalid_response_data_set[0]); index++) + { + reset_global_state(); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, TEST_DEFAULT_WAIT_TIME), + NX_AZURE_IOT_PENDING); + + while (!g_done) + { + generate_response(&iot_prov_client, + PROVISIONING_SERVICE_REPONSE_TOPIC, + sizeof(PROVISIONING_SERVICE_REPONSE_TOPIC) - 1, + invalid_response_data_set[index], strlen(invalid_response_data_set[index]), 3); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_not_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); + } +} + +/** + * Test provisioning client registration blocking succeeds + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_blocking_success() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, TEST_DEFAULT_WAIT_TIME), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + generate_good_response(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration blocking succeeds, when multiple request required. + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_with_multiple_response_blocking_success() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + g_assigned_response_after = 3; + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, TEST_DEFAULT_WAIT_TIME), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + generate_good_response(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client registration fails, if mqtt client disconnect while waiting for response + * + **/ +static VOID test_nx_azure_iot_provisioning_client_register_disconnect_failed() +{ + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, 0), + NX_AZURE_IOT_PENDING); + + /* Expected callback function to be set. */ + assert_ptr_not_equal(test_connect_notify, NX_NULL); + while (!g_done) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + + if (g_reg_id != 0) + { + /* Generate disconnect */ + test_disconnect_notify(&iot_prov_client.nx_azure_iot_provisioning_client_resource.resource_mqtt); + } + } + + assert_int_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_DISCONNECTED); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); + +} + +/** + * Test provisioning client iothub device get fails if invalid arguments passed. + * + **/ +static VOID test_nx_azure_iot_provisioning_client_iothub_device_info_invalid_arguments_failed() +{ +UINT iothub_hostname_len = 0; +UINT device_id_len = 0; + + printf("test starts =>: %s\n", __func__); + assert_int_not_equal(nx_azure_iot_provisioning_client_iothub_device_info_get(NX_NULL, + iothub_hostname, &iothub_hostname_len, + iothub_device_id, &device_id_len), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_provisioning_client_iothub_device_info_get(&iot_prov_client, + NX_NULL, &iothub_hostname_len, + iothub_device_id, &device_id_len), + NX_AZURE_IOT_SUCCESS); + + + assert_int_not_equal(nx_azure_iot_provisioning_client_iothub_device_info_get(&iot_prov_client, + iothub_hostname, &iothub_hostname_len, + NX_NULL, &device_id_len), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client iothub device get fails if buffers are too small. + * + **/ +static VOID test_nx_azure_iot_provisioning_client_iothub_device_info_invalid_state_failed() +{ +UINT iothub_hostname_len = sizeof(iothub_hostname); +UINT device_id_len = sizeof(iothub_device_id); + + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, TEST_DEFAULT_WAIT_TIME), + NX_AZURE_IOT_PENDING); + assert_int_not_equal(nx_azure_iot_provisioning_client_iothub_device_info_get(&iot_prov_client, + iothub_hostname, &iothub_hostname_len, + iothub_device_id, &device_id_len), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client iothub device get fails if buffers are too small. + * + **/ +static VOID test_nx_azure_iot_provisioning_client_iothub_device_info_oom_failed() +{ +UINT iothub_hostname_len = 0; +UINT device_id_len = 0; + + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, TEST_DEFAULT_WAIT_TIME), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + generate_good_response(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_provisioning_client_iothub_device_info_get(&iot_prov_client, + iothub_hostname, &iothub_hostname_len, + iothub_device_id, &device_id_len), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test provisioning client iothub device get succeeds. + * + **/ +static VOID test_nx_azure_iot_provisioning_client_iothub_device_info_success() +{ +UINT iothub_hostname_len = sizeof(iothub_hostname); +UINT device_id_len = sizeof(iothub_device_id); + + printf("test starts =>: %s\n", __func__); + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + g_endpoint, sizeof(g_endpoint) - 1, + g_id_scope, sizeof(g_id_scope) - 1, + g_reg_id, sizeof(g_reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_completion_callback_set(&iot_prov_client, + on_complete_callback), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_provisioning_client_register(&iot_prov_client, TEST_DEFAULT_WAIT_TIME), + NX_AZURE_IOT_PENDING); + while (!g_done) + { + generate_good_response(&iot_prov_client); + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(iot_prov_client.nx_azure_iot_provisioning_client_result, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_iothub_device_info_get(&iot_prov_client, + iothub_hostname, &iothub_hostname_len, + iothub_device_id, &device_id_len), + NX_AZURE_IOT_SUCCESS); + assert_memory_equal(iothub_hostname, assigned_hub_name, strlen(assigned_hub_name)); + assert_memory_equal(iothub_device_id, assigned_device_id, strlen(assigned_device_id)); + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); +} + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ + NX_AZURE_TEST_FN tests[] = { test_nx_azure_iot_provisioning_client_initialize_invalid_arguments, + test_nx_azure_iot_provisioning_client_device_cert_set_invalid_arguments, + test_nx_azure_iot_provisioning_client_symmetric_key_set_invalid_arguments, + test_nx_azure_iot_provisioning_client_register_invalid_arguments, + test_nx_azure_iot_provisioning_client_completion_callback_set_invalid_arguments, + test_nx_azure_iot_provisioning_client_deinitialize_invalid_arguments, + test_nx_azure_iot_provisioning_client_registration_payload_set_invalid_arguments, + test_nx_azure_iot_provisioning_client_register_without_initialization_fail, + test_nx_azure_iot_provisioning_client_init_success, + test_nx_azure_iot_provisioning_client_register_dns_failed, + test_nx_azure_iot_provisioning_client_register_subscribe_failed, + test_nx_azure_iot_provisioning_client_register_send_failed, + test_nx_azure_iot_provisioning_client_register_receive_failed, + test_nx_azure_iot_provisioning_client_register_receive_bad_response_failed, + test_nx_azure_iot_provisioning_client_register_receive_invalid_json_failed, + test_nx_azure_iot_provisioning_client_register_allocation_fail_failure, + test_nx_azure_iot_provisioning_client_register_append_data_fail_failure, + test_nx_azure_iot_provisioning_client_register_success, + test_nx_azure_iot_provisioning_client_register_failure_failed, + test_nx_azure_iot_provisioning_client_register_with_payload_success, + test_nx_azure_iot_provisioning_client_register_with_throttle_response_success, + test_nx_azure_iot_provisioning_client_register_with_throttle_response_2_success, + test_nx_azure_iot_provisioning_client_register_with_multiple_response_success, + test_nx_azure_iot_provisioning_client_register_dns_blocking_failed, + test_nx_azure_iot_provisioning_client_register_subscribe_blocking_failed, + test_nx_azure_iot_provisioning_client_register_send_blocking_failed, + test_nx_azure_iot_provisioning_client_register_receive_blocking_failed, + test_nx_azure_iot_provisioning_client_register_receive_bad_response_blocking_failed, + test_nx_azure_iot_provisioning_client_register_receive_invalid_json_blocking_failed, + test_nx_azure_iot_provisioning_client_register_blocking_success, + test_nx_azure_iot_provisioning_client_register_with_multiple_response_blocking_success, + test_nx_azure_iot_provisioning_client_register_disconnect_failed, + test_nx_azure_iot_provisioning_client_iothub_device_info_invalid_arguments_failed, + test_nx_azure_iot_provisioning_client_iothub_device_info_invalid_state_failed, + test_nx_azure_iot_provisioning_client_iothub_device_info_oom_failed, + test_nx_azure_iot_provisioning_client_iothub_device_info_success }; + INT number_of_tests = sizeof(tests)/sizeof(tests[0]); + g_ip_ptr = ip_ptr; + g_pool_ptr = pool_ptr; + g_dns_ptr = dns_ptr; + + test_suit_begin(); + + printf("Number of tests %d\r\n", number_of_tests); + for (INT index = 0; index < number_of_tests; index++) + { + test_begin(); + tests[index](); + test_end(); + } + + test_suit_end(); +} diff --git a/test/regression/azure_iot/main.c b/test/regression/azure_iot/main.c new file mode 100644 index 00000000..34678b4e --- /dev/null +++ b/test/regression/azure_iot/main.c @@ -0,0 +1,382 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include "nx_api.h" +#include "nx_azure_iot.h" +#ifndef DEMO_DHCP_DISABLE +#include "nxd_dhcp_client.h" +#endif /* DEMO_DHCP_DISABLE */ +#include "nxd_dns.h" +#include "nx_secure_tls_api.h" +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +/* Include the demo. */ +extern VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)); + +/* Define the helper thread for running Azure SDK on ThreadX (THREADX IoT Platform). */ +#ifndef DEMO_HELPER_STACK_SIZE +#define DEMO_HELPER_STACK_SIZE (2048) +#endif /* DEMO_HELPER_STACK_SIZE */ + +#ifndef DEMO_HELPER_THREAD_PRIORITY +#define DEMO_HELPER_THREAD_PRIORITY (4) +#endif /* DEMO_HELPER_THREAD_PRIORITY */ + +/* Define user configurable symbols. */ +#ifndef DEMO_IP_STACK_SIZE +#define DEMO_IP_STACK_SIZE (2048) +#endif /* DEMO_IP_STACK_SIZE */ + +#ifndef DEMO_PACKET_COUNT +#define DEMO_PACKET_COUNT (32) +#endif /* DEMO_PACKET_COUNT */ + +#ifndef DEMO_PACKET_SIZE +#define DEMO_PACKET_SIZE (1536) +#endif /* DEMO_PACKET_SIZE */ + +#define DEMO_POOL_SIZE ((DEMO_PACKET_SIZE + sizeof(NX_PACKET)) * DEMO_PACKET_COUNT) + +#ifndef DEMO_ARP_CACHE_SIZE +#define DEMO_ARP_CACHE_SIZE (512) +#endif /* DEMO_ARP_CACHE_SIZE */ + +#ifndef DEMO_IP_THREAD_PRIORITY +#define DEMO_IP_THREAD_PRIORITY (1) +#endif /* DEMO_IP_THREAD_PRIORITY */ + +#ifdef DEMO_DHCP_DISABLE +#ifndef DEMO_IPV4_ADDRESS +/*#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33)*/ +#error "SYMBOL DEMO_IPV4_ADDRESS must be defined. This symbol specifies the IP address of device. " +#endif /* DEMO_IPV4_ADDRESS */ + +#ifndef DEMO_IPV4_MASK +/*#define DEMO_IPV4_MASK 0xFFFFFF00UL*/ +#error "SYMBOL DEMO_IPV4_MASK must be defined. This symbol specifies the IP address mask of device. " +#endif /* DEMO_IPV4_MASK */ + +#ifndef DEMO_GATEWAY_ADDRESS +/*#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1)*/ +#error "SYMBOL DEMO_GATEWAY_ADDRESS must be defined. This symbol specifies the gateway address for routing. " +#endif /* DEMO_GATEWAY_ADDRESS */ + +#ifndef DEMO_DNS_SERVER_ADDRESS +/*#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1)*/ +#error "SYMBOL DEMO_DNS_SERVER_ADDRESS must be defined. This symbol specifies the dns server address for routing. " +#endif /* DEMO_DNS_SERVER_ADDRESS */ +#else +#define DEMO_IPV4_ADDRESS IP_ADDRESS(0, 0, 0, 0) +#define DEMO_IPV4_MASK IP_ADDRESS(0, 0, 0, 0) +#endif /* DEMO_DHCP_DISABLE */ + +#ifndef NETWORK_DRIVER +#define NETWORK_DRIVER _nx_pcap_network_driver +#endif /* NETWORK_DRIVER */ + + +static TX_THREAD demo_helper_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DNS dns_0; +#ifndef DEMO_DHCP_DISABLE +static NX_DHCP dhcp_0; +#endif /* DEMO_DHCP_DISABLE */ + + +/* Define the stack/cache for ThreadX. */ +static ULONG demo_ip_stack[DEMO_IP_STACK_SIZE / sizeof(ULONG)]; +#ifndef DEMO_POOL_STACK_USER +static ULONG demo_pool_stack[DEMO_POOL_SIZE / sizeof(ULONG)]; +static ULONG demo_pool_stack_size = sizeof(demo_pool_stack); +#else +extern ULONG demo_pool_stack[]; +extern ULONG demo_pool_stack_size; +#endif +static ULONG demo_arp_cache_area[DEMO_ARP_CACHE_SIZE / sizeof(ULONG)]; +static ULONG demo_helper_thread_stack[DEMO_HELPER_STACK_SIZE / sizeof(ULONG)]; + +/* Define the prototypes for demo thread. */ +static void demo_helper_thread_entry(ULONG parameter); +static void test_entry(void **state); + +#ifndef DEMO_DHCP_DISABLE +static void dhcp_wait(); +#endif /* DEMO_DHCP_DISABLE */ + +static UINT dns_create(); + +static UINT unix_time_get(ULONG *unix_time); + +/* Include the platform IP driver. */ +extern void NETWORK_DRIVER(NX_IP_DRIVER*); + +int g_argc = 0; +char **g_argv = NULL; + +/* Define main entry point. */ +int main(int argc, char **argv) +{ + + /* Initialize random seed. */ + srand(time(0)); + + /* Save arguments passed from command line. */ + g_argc = argc; + g_argv = argv; + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + +/* Define what the initial system looks like. */ +void tx_application_define(void *first_unused_memory) +{ + +UINT status; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", DEMO_PACKET_SIZE, + (UCHAR *)demo_pool_stack , demo_pool_stack_size); + + /* Check for pool creation error. */ + if (status) + { + printf("nx_packet_pool_create fail: %u\r\n", status); + return; + } + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", + DEMO_IPV4_ADDRESS, DEMO_IPV4_MASK, + &pool_0, NETWORK_DRIVER, + (UCHAR*)demo_ip_stack, sizeof(demo_ip_stack), + DEMO_IP_THREAD_PRIORITY); + + /* Check for IP create errors. */ + if (status) + { + printf("nx_ip_create fail: %u\r\n", status); + return; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (VOID *)demo_arp_cache_area, sizeof(demo_arp_cache_area)); + + /* Check for ARP enable errors. */ + if (status) + { + printf("nx_arp_enable fail: %u\r\n", status); + return; + } + + /* Enable ICMP traffic. */ + status = nx_icmp_enable(&ip_0); + + /* Check for ICMP enable errors. */ + if (status) + { + printf("nx_icmp_enable fail: %u\r\n", status); + return; + } + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&ip_0); + + /* Check for TCP enable errors. */ + if (status) + { + printf("nx_tcp_enable fail: %u\r\n", status); + return; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + + /* Check for UDP enable errors. */ + if (status) + { + printf("nx_udp_enable fail: %u\r\n", status); + return; + } + + /* Initialize TLS. */ + nx_secure_tls_initialize(); + + /* Create demo helper thread. */ + status = tx_thread_create(&demo_helper_thread, "Demo Thread", + demo_helper_thread_entry, 0, + demo_helper_thread_stack, DEMO_HELPER_STACK_SIZE, + DEMO_HELPER_THREAD_PRIORITY, DEMO_HELPER_THREAD_PRIORITY, + TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Check status. */ + if (status) + { + printf("Demo helper thread creation fail: %u\r\n", status); + return; + } +} + +/* Define demo helper thread entry. */ +void demo_helper_thread_entry(ULONG parameter) +{ + const struct CMUnitTest tests[] = + { + cmocka_unit_test(test_entry), + }; + + setbuf(stdout, NULL); + exit(cmocka_run_group_tests(tests, NULL, NULL)); +} + +static void log_callback(az_log_classification classification, UCHAR *msg, UINT msg_len) +{ + if (classification == AZ_LOG_IOT_AZURERTOS) + { + printf("%.*s", msg_len, (CHAR *)msg); + } +} + +static void test_entry(void **state) +{ +UINT status; +ULONG ip_address = 0; +ULONG network_mask = 0; +ULONG gateway_address = 0; + +#ifndef DEMO_DHCP_DISABLE + dhcp_wait(); +#else + nx_ip_gateway_address_set(&ip_0, DEMO_GATEWAY_ADDRESS); +#endif /* DEMO_DHCP_DISABLE */ + + /* Get IP address and gateway address. */ + nx_ip_address_get(&ip_0, &ip_address, &network_mask); + nx_ip_gateway_address_get(&ip_0, &gateway_address); + + /* Output IP address and gateway address. */ + printf("IP address: %lu.%lu.%lu.%lu\r\n", + (ip_address >> 24), + (ip_address >> 16 & 0xFF), + (ip_address >> 8 & 0xFF), + (ip_address & 0xFF)); + printf("Mask: %lu.%lu.%lu.%lu\r\n", + (network_mask >> 24), + (network_mask >> 16 & 0xFF), + (network_mask >> 8 & 0xFF), + (network_mask & 0xFF)); + printf("Gateway: %lu.%lu.%lu.%lu\r\n", + (gateway_address >> 24), + (gateway_address >> 16 & 0xFF), + (gateway_address >> 8 & 0xFF), + (gateway_address & 0xFF)); + + /* Create DNS. */ + status = dns_create(); + + /* Check for DNS create errors. */ + if (status) + { + printf("dns_create fail: %u\r\n", status); + return; + } + + nx_azure_iot_log_init(log_callback); + + /* Start demo. */ + demo_entry(&ip_0, &pool_0, &dns_0, unix_time_get); +} + +#ifndef DEMO_DHCP_DISABLE +static void dhcp_wait() +{ +ULONG actual_status; + + printf("DHCP In Progress...\r\n"); + + /* Create the DHCP instance. */ + nx_dhcp_create(&dhcp_0, &ip_0, "DHCP Client"); + + /* Start the DHCP Client. */ + nx_dhcp_start(&dhcp_0); + + /* Wait util address is solved. */ + nx_ip_status_check(&ip_0, NX_IP_ADDRESS_RESOLVED, &actual_status, NX_WAIT_FOREVER); +} +#endif /* DEMO_DHCP_DISABLE */ + +static UINT dns_create() +{ + +UINT status; +ULONG dns_server_address[3]; +UINT dns_server_address_size = 12; + + /* Create a DNS instance for the Client. Note this function will create + the DNS Client packet pool for creating DNS message packets intended + for querying its DNS server. */ + status = nx_dns_create(&dns_0, &ip_0, (UCHAR *)"DNS Client"); + if (status) + { + return(status); + } + + /* Is the DNS client configured for the host application to create the packet pool? */ +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Yes, use the packet pool created above which has appropriate payload size + for DNS messages. */ + status = nx_dns_packet_pool_set(&dns_0, ip_0.nx_ip_default_packet_pool); + if (status) + { + nx_dns_delete(&dns_0); + return(status); + } +#endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */ + +#ifndef DEMO_DHCP_DISABLE + /* Retrieve DNS server address. */ + nx_dhcp_interface_user_option_retrieve(&dhcp_0, 0, NX_DHCP_OPTION_DNS_SVR, (UCHAR *)(dns_server_address), + &dns_server_address_size); +#else + dns_server_address[0] = DEMO_DNS_SERVER_ADDRESS; +#endif /* DEMO_DHCP_DISABLE */ + + /* Add an IPv4 server address to the Client list. */ + status = nx_dns_server_add(&dns_0, dns_server_address[0]); + if (status) + { + nx_dns_delete(&dns_0); + return(status); + } + + /* Output DNS Server address. */ + printf("DNS Server address: %lu.%lu.%lu.%lu\r\n", + (dns_server_address[0] >> 24), + (dns_server_address[0] >> 16 & 0xFF), + (dns_server_address[0] >> 8 & 0xFF), + (dns_server_address[0] & 0xFF)); + + return(NX_SUCCESS); +} + +static UINT unix_time_get(ULONG *unix_time) +{ + + *unix_time = (ULONG)time(NULL); + + return(NX_SUCCESS); +} diff --git a/test/regression/azure_iot/nx_azure_iot_adu_agent_unit_test.c b/test/regression/azure_iot/nx_azure_iot_adu_agent_unit_test.c new file mode 100644 index 00000000..c527736c --- /dev/null +++ b/test/regression/azure_iot/nx_azure_iot_adu_agent_unit_test.c @@ -0,0 +1,1806 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "azure/core/az_span.h" +#include "nx_api.h" +#include "nx_packet.h" +#include "nx_azure_iot_adu_agent.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +#ifndef MAXIMUM_PAYLOAD_LENGTH +#define MAXIMUM_PAYLOAD_LENGTH 10240 +#endif /* MAXIMUM_PAYLOAD_LENGTH */ + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, sizeof(s) - 1 + +#define MQTT_CLIENT_GET(c) ((c) -> nx_azure_iot_hub_client_resource.resource_mqtt) +#define TX_MUTEX_GET(c) ((c) -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr) + +/* Device properties. */ +#define SAMPLE_DEVICE_MANUFACTURER "Contoso" +#define SAMPLE_DEVICE_MODEL "IoTDevice" +#define SAMPLE_DEVICE_INSTALLED_CRITERIA "6.1.0" +#define SAMPLE_DEVICE_INSTALLED_CRITERIA_NEW "7.0.0" + +#define SAMPLE_LEAF_DEVICE_MANUFACTURER "Contoso" +#define SAMPLE_LEAF_DEVICE_MODEL "IoTDevice-Leaf" +#define SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA "1.0.0" + +#define SAMPLE_LEAF2_DEVICE_MANUFACTURER "Contoso" +#define SAMPLE_LEAF2_DEVICE_MODEL "IoTDevice-Leaf2" +#define SAMPLE_LEAF2_DEVICE_INSTALLED_CRITERIA "1.0.0" + +typedef VOID (*NX_AZURE_TEST_FN)(); + +static ULONG network_bytes_generate_stack[DEMO_HELPER_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD network_bytes_generate_thread; + +static const CHAR *g_expected_message = NX_NULL; +static UINT g_expected_message_index = 0; +static const UCHAR g_hostname[] = "unit-test.iot-azure.com"; +static const UCHAR g_device_id[] = "unit_test_device"; +static const UCHAR g_pnp_model_id[] = "pnp_model_id_unit_test"; +static const UCHAR g_symmetric_key[] = "6CLK6It9jOiABpFVu11CQDv9O49ebAneK3KbsvaoU1o="; +static const CHAR reported_property_success_topic[] = "$iothub/twin/res/204/?$rid=%d&$version=6"; +static UINT reported_property_success_topic_count; + +/* Startup message, such as: "{\"deviceUpdate\":{\"__t\":\"c\",\"agent\":{\"deviceProperties\":{\"manufacturer\":\"Contoso\",\"model\":\"IoTDevice\",\"contractModelId\":\"dtmi:azure:iot:deviceUpdateContractModel;2\",\"aduVer\":\"AzureRTOS;agent/6.2.0\"},\"compatPropertyNames\":\"manufacturer,model\"}}}" */ +static const UCHAR g_adu_agent_reported_property_startup1[] = "{\"deviceUpdate\":{\"__t\":\"c\",\"agent\":{\"deviceProperties\":{\"manufacturer\":\"Contoso\",\"model\":\"IoTDevice\",\"contractModelId\":\"dtmi:azure:iot:deviceUpdateContractModel;2\",\"aduVer\":\"AzureRTOS;agent/"; +static const UCHAR g_adu_agent_reported_property_startup2[] = "\"},\"compatPropertyNames\":\"manufacturer,model\"}}}"; +static UCHAR g_adu_agent_reported_property_startup[300]; + +static const CHAR g_adu_agent_new_udpate_topic[] = "$iothub/twin/PATCH/properties/desired/?$version=6"; +static const UCHAR g_adu_agent_new_udpate_1[] = "{\"deviceUpdate\":{\"service\":{\"workflow\":{\"action\":3,\"id\":\"25ed0df8-4e9a-42d8-bde6-cf78c1c1555c\"},\"updateManifest\":\"{\\\"manifestVersion\\\":\\\"4\\\",\\\"updateId\\\":{\\\"provider\\\":\\\"Contoso\\\",\\\"name\\\":\\\"IoTDevice\\\",\\\"version\\\":\\\"8.0.0\\\"},\\\"compatibility\\\":[{\\\"manufacturer\\\":\\\"Contoso\\\",\\\"model\\\":\\\"IoTDevice\\\"}],\\\"instructions\\\":{\\\"steps\\\":[{\\\"handler\\\":\\\"microsoft/swupdate:1\\\",\\\"files\\\":[\\\"f54c62cc342281d4c\\\"],\\\"handlerProperties\\\":{\\\"installedCriteria\\\":\\\"7.0.0\\\"}}]},\\\"files\\\":{\\\"f54c62cc342281d4c\\\":{\\\"fileName\\\":\\\"firmware_7.0.0.bin\\\",\\\"sizeInBytes\\\":1978,\\\"hashes\\\":{\\\"sha256\\\":\\\"qr+xRWnfo/POaFNv+KVddBsJngGxCiSQ25WEW8t4dLc=\\\"}}},\\\"createdDateTime\\\":\\\"2022-11-09T10:42:02.5542967Z\\\"}\",\"updateManifestSignature\":\"eyJhbGciOiJSUzI1NiIsInNqd2siOiJleUpoYkdjaU9pSlNVekkxTmlJc0ltdHBaQ0k2SWtGRVZTNHlNREEzTURJdVVpSjkuZXlKcmRIa2lPaUpTVTBFaUxDSnVJam9pYkV4bWMwdHZPRmwwWW1Oak1sRXpUalV3VlhSTVNXWlhVVXhXVTBGRlltTm9LMFl2WTJVM1V6Rlpja3BvV0U5VGNucFRaa051VEhCVmFYRlFWSGMwZWxndmRHbEJja0ZGZFhrM1JFRmxWVzVGU0VWamVEZE9hM2QzZVRVdk9IcExaV3AyWTBWWWNFRktMMlV6UWt0SE5FVTBiMjVtU0ZGRmNFOXplSGRQUzBWbFJ6QkhkamwzVjB3emVsUmpUblprUzFoUFJGaEdNMVZRWlVveGIwZGlVRkZ0Y3pKNmJVTktlRUppZEZOSldVbDBiWFpwWTNneVpXdGtWbnBYUm5jdmRrdFVUblZMYXpob2NVczNTRkptYWs5VlMzVkxXSGxqSzNsSVVVa3dZVVpDY2pKNmEyc3plR2d4ZEVWUFN6azRWMHBtZUdKamFsQnpSRTgyWjNwWmVtdFlla05OZW1Fd1R6QkhhV0pDWjB4QlZGUTVUV1k0V1ZCd1dVY3lhblpQWVVSVmIwTlJiakpWWTFWU1RtUnNPR2hLWW5scWJscHZNa3B5SzFVNE5IbDFjVTlyTjBZMFdubFRiMEoyTkdKWVNrZ3lXbEpTV2tab0wzVlRiSE5XT1hkU2JWbG9XWEoyT1RGRVdtbHhhemhJVWpaRVUyeHVabTVsZFRJNFJsUm9SVzF0YjNOVlRUTnJNbGxNYzBKak5FSnZkWEIwTTNsaFNEaFpia3BVTnpSMU16TjFlakU1TDAxNlZIVnFTMmMzVkdGcE1USXJXR0owYmxwRU9XcFVSMkY1U25Sc2FFWmxWeXRJUXpVM1FYUkJSbHBvY1ZsM2VVZHJXQ3M0TTBGaFVGaGFOR0V4VHpoMU1qTk9WVWQxTWtGd04yOU5NVTR3ZVVKS0swbHNUM29pTENKbElqb2lRVkZCUWlJc0ltRnNaeUk2SWxKVE1qVTJJaXdpYTJsa0lqb2lRVVJWTGpJeE1EWXdPUzVTTGxNaWZRLlJLS2VBZE02dGFjdWZpSVU3eTV2S3dsNFpQLURMNnEteHlrTndEdkljZFpIaTBIa2RIZ1V2WnoyZzZCTmpLS21WTU92dXp6TjhEczhybXo1dnMwT1RJN2tYUG1YeDZFLUYyUXVoUXNxT3J5LS1aN2J3TW5LYTNkZk1sbkthWU9PdURtV252RWMyR0hWdVVTSzREbmw0TE9vTTQxOVlMNThWTDAtSEthU18xYmNOUDhXYjVZR08xZXh1RmpiVGtIZkNIU0duVThJeUFjczlGTjhUT3JETHZpVEtwcWtvM3RiSUwxZE1TN3NhLWJkZExUVWp6TnVLTmFpNnpIWTdSanZGbjhjUDN6R2xjQnN1aVQ0XzVVaDZ0M05rZW1UdV9tZjdtZUFLLTBTMTAzMFpSNnNTR281azgtTE1sX0ZaUmh4djNFZFNtR2RBUTNlMDVMRzNnVVAyNzhTQWVzWHhNQUlHWmcxUFE3aEpoZGZHdmVGanJNdkdTSVFEM09wRnEtZHREcEFXbUo2Zm5sZFA1UWxYek5tQkJTMlZRQUtXZU9BYjh0Yjl5aVhsemhtT1dLRjF4SzlseHpYUG9GNmllOFRUWlJ4T0hxTjNiSkVISkVoQmVLclh6YkViV2tFNm4zTEoxbkd5M1htUlVFcER0Umdpa0tBUzZybFhFT0VneXNjIn0.eyJzaGEyNTYiOiJ1MTVFa25xNDBvcUV4Z25yZVRyaVFVZ25COW5qcGFnU3JsNlVQNDJ1YWw4PSJ9.TOtLVW-wgMFUzonOn5Os5_bY6hjpeW3MW1votMDuc1jTlrAS9xpLLEFbJJhlaFQdKWjpoWNPS9HnwjgWVQhGh_-PrvVB5CUegKkJZfCY_xlJGPrs2ydYeVqHKbY4bX37Uw3uCaHYI6021unkLjywV_eXVIJ0tT4DKXrMcmPED_isI63rTIUDe0tBUwGtyNu_PobMOE-6MZRZ3tDXYe7xKSvKJVg-nhKsG6-mdE9r44nvTA3I-SIpwp1PJMjzNWmXBXZNaJISs-K7O0LK1X0i4muO1F42qMYqP41xbYGtaof92LksfZTk7KhSgfXbj4-K6VslrGvTYf2oRNCrZXoDyGa9aQuI8gOdSDVSyV1nOafSgBseV9QqxxYXZoDq2SAx87c8mOKAYFjUevZ1FRqEeNQA5eiv-EysbCrknGVG7ueGUVj8bGeFB1-90OOY2AlJQoSvwR_Fc2MNBpPbr6ZIhy9Tg_UXPn1xSs8skG8Oq-R1wm0ghXDR7-yDNtTAZ2f6\",\"fileUrls\":{\"f54c62cc342281d4c\":\"http://jackyztest--jackyztest.b.nlu.dl.adu.microsoft.com/southeastasia/jackyztest--jackyztest/6c1f3eadc320465694af478f67b41dd1/firmware_7.0.0.bin\"}},\"__t\":\"c\"},\"$version\":6}"; +static const UCHAR g_adu_agent_new_udpate_2[] = "{\"deviceUpdate\":{\"__t\":\"c\",\"service\":{\"workflow\":{\"action\":3,\"id\":\"3c192285-1bce-4d57-9486-07991fc74fb0\"},\"updateManifest\":\"{\\\"manifestVersion\\\":\\\"5\\\",\\\"updateId\\\":{\\\"provider\\\":\\\"Contoso\\\",\\\"name\\\":\\\"IoTDevice\\\",\\\"version\\\":\\\"12.1.1\\\"},\\\"compatibility\\\":[{\\\"manufacturer\\\":\\\"Contoso\\\",\\\"model\\\":\\\"IoTDevice\\\"}],\\\"instructions\\\":{\\\"steps\\\":[{\\\"handler\\\":\\\"microsoft/swupdate:1\\\",\\\"files\\\":[\\\"f1d70776744216017\\\"],\\\"handlerProperties\\\":{\\\"installedCriteria\\\":\\\"12.1.1\\\"}}]},\\\"files\\\":{\\\"f1d70776744216017\\\":{\\\"fileName\\\":\\\"firmware_12.1.1.bin\\\",\\\"sizeInBytes\\\":16,\\\"hashes\\\":{\\\"sha256\\\":\\\"Fqv5r0ZD/x6ok0aRqJERX2JuW36O+GOxn0/r7aBJkOs=\\\"}}},\\\"createdDateTime\\\":\\\"2023-03-27T08:01:26.6316Z\\\"}\",\"updateManifestSignature\":\"eyJhbGciOiJSUzI1NiIsInNqd2siOiJleUpoYkdjaU9pSlNVekkxTmlJc0ltdHBaQ0k2SWtGRVZTNHlNREEzTURJdVVpSjkuZXlKcmRIa2lPaUpTVTBFaUxDSnVJam9pYmt0bVdVdEVSREF4VERoSldVaExTekV2WVhGTEwwMXBOWEpaUVdKd1RHcEVUM2g2VEZBelpHTmFLM0ZwWVZGRk5WZFhjazlZWTFndlZUaGFPR1l6ZDNseFJXRkVOVFpWYkRsYVowWnZNamN4TUhkd1lpOVlPRWRHTW5oQmQzbHhkMWR2YlV4SVltWnNNazlxYVU1R1ZtNW5ObXRIT1RZdlRVOXZjR2xQWXpsS1IwVkpiMjVXUkRoQ2NHeFJWRTV2TUM5UGVFcFNZVXBzWjNwMVdtbE9ZVFpLY2paT2NraDNaMmRDYVU1V05GcFlWa3hWT1ZCbGN6ZHhOVTFwTDI5ak1FZHFTbFF5V0dSd2RGVnZOVnBHUjNSV1REZENjREF5VEZseFZuVnFVblZsYkRsUlJHMVdjMUoxSzBoeWVEUmlibFpvY1dWWFNrc3pVazVDYWtsVmIxTmxVWFJaWkNzdlVUTXpaREkxVkVobmVGaHFhbkpLSzI5c01DOHJXREp6Vmk5QlZFUnlVaXRUTlRSaGJHRklhMXBuWldWcWRrOVBXVE13Ym1KNFJHZHpSVVpuTldnelVXTkhOR2gxVEU5elRXbzJWemg1Y1c5UU1VTmxPV1V3YzFVdlUzYzFXWHBCUW5SYWNWaFROVFE0YWtaelVHSmplbTF1UXpaVWFrTlFaVkprZFZsWlFXVk1ZekZDVm1OamIyTkVWRzVaWnpaMmNYcElNbUp5WWk5bE5GSm1SRzQ0WVN0aFQxRkdSWFZ6TTNCVmVqRmFNR1JJYUV4aVpHMUpkMkZMTjFCTksxRm5aVTlCWWt4dVVuTjJUamh4ZEVKM2IwWnZhbXBNVm10VWFHbENVQzl6T0ZOV2JXWkdOekpGTVRWeU9GSTVXRVZvV2xkMVpWZ3pVbllpTENKbElqb2lRVkZCUWlJc0ltRnNaeUk2SWxKVE1qVTJJaXdpYTJsa0lqb2lRVVJWTGpJeU1EVXdNeTVTTGxNaWZRLnlCblhub1FiTHZudHV4N3djaFh6a3lwX2ZLbGF2ZzhCMnJlQV9vNzFwWnlnd0x6RV9NM2xDM2tna1NQUHRvMEZkclFuWDZqS1lkdG1MUXVJVDVPdkdmR0d5MmIyTDJOa1VVZDZnSGs4SF9zTlFfS0ZEYkdFUWREczZGeHFGYkxrRHp6cktreXczSmxLWWRKUXJaLTFDTlZWc0FmSVVfb013YjYzQ2E5VEdrNWFqNlNMVWE1V1BWLW5Td2VQRHAzQ2YyV0ZCa09jdC1IMGtLTDlJeTI0Q01uT1IwVmVwYUlGZmk4anFDRVlwX1lrcUw3Z1VNRTFWT1ZGczFRTnFRZ0pLVDZDRnRjU3lGcFVVOXRITlgxWnhYdE1jcTNMR3M2Yk9NUjlvTXV5bDVfUE5OLXlWNTVJSFFNb3hXZkl3V1QwZTdXcGFsdzJJSW5LLUptWkVjYURPYkQyaWI1ZDZUTlduVnJXQ2JHaHRjejducG1fbTVMSlJkc1JUcC1DYWlSRkEtV3daQzRfSW9nTDZZMXFzb3lRb1kwTU04OFNhdl91b1p6VGYtenZZR0hJcGdhb1pnN1pzTGU0SGNSYzFSZGhNcUREWEw3UE9iX2ktbmVoNUEzV1pRczVkNGNmak5iRHI1c2I3QWdEMnZENGZFRXg0TmxpcE9nWWVESGNvRTRxIn0.eyJzaGEyNTYiOiJ3RkFVS0xXVmNxanMrZWNoRmJEWnVDQ2QyK2dRWkd4RmVad2FGNHlCR3pRPSJ9.FGPzrtKewHlWi-AQBgMKpeg4piX1PP3OZ-kHkviUi6MlKfwBSiLGVH1CszROLfvaJQAfsePAK_uCnGsQMXAsksi2Ci4jXeHZVnwtRwZk2bR8l-k-VG1v-fNDB43G2mThBQFabNwfzctqxTfpsD-7LEN4tAqKRf03DeMPMEfYukhwmehPRA5Nx0qwEzHaIdRic405bYN4yq-ZSMnfY-_x0ZzT52txlUt261pr-rWUeNRBnU67TXs3MKugXxK6kbL5b4W1JHVIxldGfXcCWB6UpXzEqugJbpGWluL4ILUIrGfzGhQxo_1k2umNhlDss8HnOe4UQByv7AoUiYUmx4TvuyZT3umvWHHtExsl1TO4EvhQ__iPpdUOTdoBQ1MK_NeOXzUtSDBvJEMRjybcUrB7FbpWnP49IGNLL1wpk2pwOa7N_Ez8sF8-EUjRjIH9dEmrJp3M4xwMkHl7h1zC7GKJ2ckZxqzuNLF7I1udfMY8ajhHVIVLzUcyNFIVUCg8ZSx1\",\"fileUrls\":{\"f1d70776744216017\":\"http://azurertos-adu--azurertos-adu.b.nlu.dl.adu.microsoft.com/eastus/azurertos-adu--azurertos-adu/3e80714356924d1e9f1975bafb7a6cd4/firmware_12.1.1.bin\"}}},\"$version\":6}"; + +/* Two steps/firmware. */ +static const UCHAR g_adu_agent_new_update_3[] = "{\"deviceUpdate\":{\"service\":{\"workflow\":{\"action\":3,\"id\":\"6b831565-bd1c-4b84-995a-f2ab4e6a4bb1\"},\"updateManifest\":\"{\\\"manifestVersion\\\":\\\"5\\\",\\\"updateId\\\":{\\\"provider\\\":\\\"Contoso\\\",\\\"name\\\":\\\"IoTDevice\\\",\\\"version\\\":\\\"7.0.1\\\"},\\\"compatibility\\\":[{\\\"manufacturer\\\":\\\"Contoso\\\",\\\"model\\\":\\\"IoTDevice\\\"}],\\\"instructions\\\":{\\\"steps\\\":[{\\\"type\\\":\\\"reference\\\",\\\"detachedManifestFileId\\\":\\\"f0df8c0e22a1b60c1\\\"},{\\\"handler\\\":\\\"microsoft/swupdate:1\\\",\\\"files\\\":[\\\"fba3f0b3def43a3a4\\\"],\\\"handlerProperties\\\":{\\\"installedCriteria\\\":\\\"7.0.1\\\"}}]},\\\"files\\\":{\\\"fba3f0b3def43a3a4\\\":{\\\"fileName\\\":\\\"firmware_7.0.1.bin\\\",\\\"sizeInBytes\\\":1978,\\\"hashes\\\":{\\\"sha256\\\":\\\"qr+xRWnfo/POaFNv+KVddBsJngGxCiSQ25WEW8t4dLc=\\\"}},\\\"f0df8c0e22a1b60c1\\\":{\\\"fileName\\\":\\\"contoso.iotdevice-leaf.7.0.1.updatemanifest5.json\\\",\\\"sizeInBytes\\\":601,\\\"hashes\\\":{\\\"sha256\\\":\\\"fP+yIYtGfsxMkL1iRS+olh+iXBebXYEapROyG6+nBjE=\\\"}}},\\\"createdDateTime\\\":\\\"2022-12-19T05:25:47.9977098Z\\\"}\",\"updateManifestSignature\":\"eyJhbGciOiJSUzI1NiIsInNqd2siOiJleUpoYkdjaU9pSlNVekkxTmlJc0ltdHBaQ0k2SWtGRVZTNHlNREEzTURJdVVpSjkuZXlKcmRIa2lPaUpTVTBFaUxDSnVJam9pYkV4bWMwdHZPRmwwWW1Oak1sRXpUalV3VlhSTVNXWlhVVXhXVTBGRlltTm9LMFl2WTJVM1V6Rlpja3BvV0U5VGNucFRaa051VEhCVmFYRlFWSGMwZWxndmRHbEJja0ZGZFhrM1JFRmxWVzVGU0VWamVEZE9hM2QzZVRVdk9IcExaV3AyWTBWWWNFRktMMlV6UWt0SE5FVTBiMjVtU0ZGRmNFOXplSGRQUzBWbFJ6QkhkamwzVjB3emVsUmpUblprUzFoUFJGaEdNMVZRWlVveGIwZGlVRkZ0Y3pKNmJVTktlRUppZEZOSldVbDBiWFpwWTNneVpXdGtWbnBYUm5jdmRrdFVUblZMYXpob2NVczNTRkptYWs5VlMzVkxXSGxqSzNsSVVVa3dZVVpDY2pKNmEyc3plR2d4ZEVWUFN6azRWMHBtZUdKamFsQnpSRTgyWjNwWmVtdFlla05OZW1Fd1R6QkhhV0pDWjB4QlZGUTVUV1k0V1ZCd1dVY3lhblpQWVVSVmIwTlJiakpWWTFWU1RtUnNPR2hLWW5scWJscHZNa3B5SzFVNE5IbDFjVTlyTjBZMFdubFRiMEoyTkdKWVNrZ3lXbEpTV2tab0wzVlRiSE5XT1hkU2JWbG9XWEoyT1RGRVdtbHhhemhJVWpaRVUyeHVabTVsZFRJNFJsUm9SVzF0YjNOVlRUTnJNbGxNYzBKak5FSnZkWEIwTTNsaFNEaFpia3BVTnpSMU16TjFlakU1TDAxNlZIVnFTMmMzVkdGcE1USXJXR0owYmxwRU9XcFVSMkY1U25Sc2FFWmxWeXRJUXpVM1FYUkJSbHBvY1ZsM2VVZHJXQ3M0TTBGaFVGaGFOR0V4VHpoMU1qTk9WVWQxTWtGd04yOU5NVTR3ZVVKS0swbHNUM29pTENKbElqb2lRVkZCUWlJc0ltRnNaeUk2SWxKVE1qVTJJaXdpYTJsa0lqb2lRVVJWTGpJeE1EWXdPUzVTTGxNaWZRLlJLS2VBZE02dGFjdWZpSVU3eTV2S3dsNFpQLURMNnEteHlrTndEdkljZFpIaTBIa2RIZ1V2WnoyZzZCTmpLS21WTU92dXp6TjhEczhybXo1dnMwT1RJN2tYUG1YeDZFLUYyUXVoUXNxT3J5LS1aN2J3TW5LYTNkZk1sbkthWU9PdURtV252RWMyR0hWdVVTSzREbmw0TE9vTTQxOVlMNThWTDAtSEthU18xYmNOUDhXYjVZR08xZXh1RmpiVGtIZkNIU0duVThJeUFjczlGTjhUT3JETHZpVEtwcWtvM3RiSUwxZE1TN3NhLWJkZExUVWp6TnVLTmFpNnpIWTdSanZGbjhjUDN6R2xjQnN1aVQ0XzVVaDZ0M05rZW1UdV9tZjdtZUFLLTBTMTAzMFpSNnNTR281azgtTE1sX0ZaUmh4djNFZFNtR2RBUTNlMDVMRzNnVVAyNzhTQWVzWHhNQUlHWmcxUFE3aEpoZGZHdmVGanJNdkdTSVFEM09wRnEtZHREcEFXbUo2Zm5sZFA1UWxYek5tQkJTMlZRQUtXZU9BYjh0Yjl5aVhsemhtT1dLRjF4SzlseHpYUG9GNmllOFRUWlJ4T0hxTjNiSkVISkVoQmVLclh6YkViV2tFNm4zTEoxbkd5M1htUlVFcER0Umdpa0tBUzZybFhFT0VneXNjIn0.eyJzaGEyNTYiOiIwcHRkQXFDV1B4NXdqWk5wOXg4ZnJGWTNlR0RjdEhCQjZWZTV4eHExZlI0PSJ9.VAKBz0jsx_PGXCL174k1xoHQsFqavxlvX_B1CUFUYjDgU7fLR_fah5JOHIGLYYvCmycX4zdCOayG8e5Hbqy1lFTGDMCPuyvEcKgFm5eBs4H8jMC3-LBg1pvsIgIPnw46RxrRQCOLBUFItu-hrbcGcXN0_blVsDfFEVZdkP64Pt1No-Az-hvRUv2UUeiq1OwFuVIMfm-fK2177DG8Mfw_ZTk3CMNn0aeo3eFVVLy4xfHiXqD3-7jah_HcLLuiaKLBM-XfIrm5Q5fuZ4pHnKlJNFKgW2ykIh274kcdVw_D0bfgxeOaCj0SftmsoCxnLUzLAfxDlqdY-yw6O-gTski81TrCMH5X-Ykd9TkZDyMZN08jp_V3jSX29us-MNHf_5fqKM07H4pCk7sGwQTaq7WmIfwyOC7M7Ea7N65IErBS_ejNsyu9-R9XOFROWyN_hqHxj1zvbubgOU-UBEaYwSgWb4gqFFzhlxVfAAElQDRTa1T_4FFs1-edKdifURz9hGKc\",\"fileUrls\":{\"fba3f0b3def43a3a4\":\"http://azurertos-adu--azurertos-adu.b.nlu.dl.adu.microsoft.com/eastus/azurertos-adu--azurertos-adu/a58ae7c5286e499486bd841373abd884/firmware_7.0.1.bin\",\"f0df8c0e22a1b60c1\":\"http://azurertos-adu--azurertos-adu.b.nlu.dl.adu.microsoft.com/eastus/azurertos-adu--azurertos-adu/72e4076e2dea427b9c24c76765f35371/contoso.iotdevice-leaf.7.0.1.updatemanifest5.json\",\"fa0feb4ccadb5c2fe\":\"http://azurertos-adu--azurertos-adu.b.nlu.dl.adu.microsoft.com/eastus/azurertos-adu--azurertos-adu/ba2e3429b1814c03bb4cfd72587dac54/leaf_firmware_7.0.2.bin\"}},\"__t\":\"c\"},\"$version\":6}"; + +/* Null file url. */ +static const UCHAR g_adu_agent_new_update_4[] = "{\"deviceUpdate\":{\"service\":{\"workflow\":{\"action\":3,\"id\":\"6b831565-bd1c-4b84-995a-f2ab4e6a4bb1\"},\"updateManifest\":\"{\\\"manifestVersion\\\":\\\"5\\\",\\\"updateId\\\":{\\\"provider\\\":\\\"Contoso\\\",\\\"name\\\":\\\"IoTDevice\\\",\\\"version\\\":\\\"7.0.1\\\"},\\\"compatibility\\\":[{\\\"manufacturer\\\":\\\"Contoso\\\",\\\"model\\\":\\\"IoTDevice\\\"}],\\\"instructions\\\":{\\\"steps\\\":[{\\\"type\\\":\\\"reference\\\",\\\"detachedManifestFileId\\\":\\\"f0df8c0e22a1b60c1\\\"},{\\\"handler\\\":\\\"microsoft/swupdate:1\\\",\\\"files\\\":[\\\"fba3f0b3def43a3a4\\\"],\\\"handlerProperties\\\":{\\\"installedCriteria\\\":\\\"7.0.1\\\"}}]},\\\"files\\\":{\\\"fba3f0b3def43a3a4\\\":{\\\"fileName\\\":\\\"firmware_7.0.1.bin\\\",\\\"sizeInBytes\\\":1978,\\\"hashes\\\":{\\\"sha256\\\":\\\"qr+xRWnfo/POaFNv+KVddBsJngGxCiSQ25WEW8t4dLc=\\\"}},\\\"f0df8c0e22a1b60c1\\\":{\\\"fileName\\\":\\\"contoso.iotdevice-leaf.7.0.1.updatemanifest5.json\\\",\\\"sizeInBytes\\\":601,\\\"hashes\\\":{\\\"sha256\\\":\\\"fP+yIYtGfsxMkL1iRS+olh+iXBebXYEapROyG6+nBjE=\\\"}}},\\\"createdDateTime\\\":\\\"2022-12-19T05:25:47.9977098Z\\\"}\",\"updateManifestSignature\":\"eyJhbGciOiJSUzI1NiIsInNqd2siOiJleUpoYkdjaU9pSlNVekkxTmlJc0ltdHBaQ0k2SWtGRVZTNHlNREEzTURJdVVpSjkuZXlKcmRIa2lPaUpTVTBFaUxDSnVJam9pYkV4bWMwdHZPRmwwWW1Oak1sRXpUalV3VlhSTVNXWlhVVXhXVTBGRlltTm9LMFl2WTJVM1V6Rlpja3BvV0U5VGNucFRaa051VEhCVmFYRlFWSGMwZWxndmRHbEJja0ZGZFhrM1JFRmxWVzVGU0VWamVEZE9hM2QzZVRVdk9IcExaV3AyWTBWWWNFRktMMlV6UWt0SE5FVTBiMjVtU0ZGRmNFOXplSGRQUzBWbFJ6QkhkamwzVjB3emVsUmpUblprUzFoUFJGaEdNMVZRWlVveGIwZGlVRkZ0Y3pKNmJVTktlRUppZEZOSldVbDBiWFpwWTNneVpXdGtWbnBYUm5jdmRrdFVUblZMYXpob2NVczNTRkptYWs5VlMzVkxXSGxqSzNsSVVVa3dZVVpDY2pKNmEyc3plR2d4ZEVWUFN6azRWMHBtZUdKamFsQnpSRTgyWjNwWmVtdFlla05OZW1Fd1R6QkhhV0pDWjB4QlZGUTVUV1k0V1ZCd1dVY3lhblpQWVVSVmIwTlJiakpWWTFWU1RtUnNPR2hLWW5scWJscHZNa3B5SzFVNE5IbDFjVTlyTjBZMFdubFRiMEoyTkdKWVNrZ3lXbEpTV2tab0wzVlRiSE5XT1hkU2JWbG9XWEoyT1RGRVdtbHhhemhJVWpaRVUyeHVabTVsZFRJNFJsUm9SVzF0YjNOVlRUTnJNbGxNYzBKak5FSnZkWEIwTTNsaFNEaFpia3BVTnpSMU16TjFlakU1TDAxNlZIVnFTMmMzVkdGcE1USXJXR0owYmxwRU9XcFVSMkY1U25Sc2FFWmxWeXRJUXpVM1FYUkJSbHBvY1ZsM2VVZHJXQ3M0TTBGaFVGaGFOR0V4VHpoMU1qTk9WVWQxTWtGd04yOU5NVTR3ZVVKS0swbHNUM29pTENKbElqb2lRVkZCUWlJc0ltRnNaeUk2SWxKVE1qVTJJaXdpYTJsa0lqb2lRVVJWTGpJeE1EWXdPUzVTTGxNaWZRLlJLS2VBZE02dGFjdWZpSVU3eTV2S3dsNFpQLURMNnEteHlrTndEdkljZFpIaTBIa2RIZ1V2WnoyZzZCTmpLS21WTU92dXp6TjhEczhybXo1dnMwT1RJN2tYUG1YeDZFLUYyUXVoUXNxT3J5LS1aN2J3TW5LYTNkZk1sbkthWU9PdURtV252RWMyR0hWdVVTSzREbmw0TE9vTTQxOVlMNThWTDAtSEthU18xYmNOUDhXYjVZR08xZXh1RmpiVGtIZkNIU0duVThJeUFjczlGTjhUT3JETHZpVEtwcWtvM3RiSUwxZE1TN3NhLWJkZExUVWp6TnVLTmFpNnpIWTdSanZGbjhjUDN6R2xjQnN1aVQ0XzVVaDZ0M05rZW1UdV9tZjdtZUFLLTBTMTAzMFpSNnNTR281azgtTE1sX0ZaUmh4djNFZFNtR2RBUTNlMDVMRzNnVVAyNzhTQWVzWHhNQUlHWmcxUFE3aEpoZGZHdmVGanJNdkdTSVFEM09wRnEtZHREcEFXbUo2Zm5sZFA1UWxYek5tQkJTMlZRQUtXZU9BYjh0Yjl5aVhsemhtT1dLRjF4SzlseHpYUG9GNmllOFRUWlJ4T0hxTjNiSkVISkVoQmVLclh6YkViV2tFNm4zTEoxbkd5M1htUlVFcER0Umdpa0tBUzZybFhFT0VneXNjIn0.eyJzaGEyNTYiOiIwcHRkQXFDV1B4NXdqWk5wOXg4ZnJGWTNlR0RjdEhCQjZWZTV4eHExZlI0PSJ9.VAKBz0jsx_PGXCL174k1xoHQsFqavxlvX_B1CUFUYjDgU7fLR_fah5JOHIGLYYvCmycX4zdCOayG8e5Hbqy1lFTGDMCPuyvEcKgFm5eBs4H8jMC3-LBg1pvsIgIPnw46RxrRQCOLBUFItu-hrbcGcXN0_blVsDfFEVZdkP64Pt1No-Az-hvRUv2UUeiq1OwFuVIMfm-fK2177DG8Mfw_ZTk3CMNn0aeo3eFVVLy4xfHiXqD3-7jah_HcLLuiaKLBM-XfIrm5Q5fuZ4pHnKlJNFKgW2ykIh274kcdVw_D0bfgxeOaCj0SftmsoCxnLUzLAfxDlqdY-yw6O-gTski81TrCMH5X-Ykd9TkZDyMZN08jp_V3jSX29us-MNHf_5fqKM07H4pCk7sGwQTaq7WmIfwyOC7M7Ea7N65IErBS_ejNsyu9-R9XOFROWyN_hqHxj1zvbubgOU-UBEaYwSgWb4gqFFzhlxVfAAElQDRTa1T_4FFs1-edKdifURz9hGKc\",\"fileUrls\":{\"f352dcaace6710428\":null,\"fba3f0b3def43a3a4\":\"http://azurertos-adu--azurertos-adu.b.nlu.dl.adu.microsoft.com/eastus/azurertos-adu--azurertos-adu/a58ae7c5286e499486bd841373abd884/firmware_7.0.1.bin\",\"f0df8c0e22a1b60c1\":\"http://azurertos-adu--azurertos-adu.b.nlu.dl.adu.microsoft.com/eastus/azurertos-adu--azurertos-adu/72e4076e2dea427b9c24c76765f35371/contoso.iotdevice-leaf.7.0.1.updatemanifest5.json\",\"fa0feb4ccadb5c2fe\":\"http://azurertos-adu--azurertos-adu.b.nlu.dl.adu.microsoft.com/eastus/azurertos-adu--azurertos-adu/ba2e3429b1814c03bb4cfd72587dac54/leaf_firmware_7.0.2.bin\",\"fd253bec341ca4d00\":null}},\"__t\":\"c\"},\"$version\":6}"; + +static const UCHAR *g_adu_agent_new_udpate = g_adu_agent_new_udpate_1; +static UINT g_adu_agent_new_udpate_size = sizeof(g_adu_agent_new_udpate_1); +static const CHAR g_adu_agent_cancel_udpate_topic[] = "$iothub/twin/PATCH/properties/desired/?$version=7"; +static const UCHAR g_adu_agent_cancel_update[] = "{\"deviceUpdate\":{\"service\":{\"workflow\":{\"action\":255,\t\"id\":\"nodeployment\"}},\"__t\":\"c\"},\"$version\":6}"; +static const UCHAR g_adu_agent_cancel_response[] = "{\"deviceUpdate\":{\"__t\":\"c\",\"agent\":{\"state\":0,\"workflow\":{\"action\":255,\"id\":\"nodeployment\"}}}}"; + +static const UCHAR g_adu_agent_proxy_manifest[] = "{\"updateManifest\":\"{\\\"manifestVersion\\\":\\\"5\\\",\\\"updateId\\\":{\\\"provider\\\":\\\"Contoso\\\",\\\"name\\\":\\\"IoTDevice-Leaf\\\",\\\"version\\\":\\\"7.0.1\\\"},\\\"compatibility\\\":[{\\\"manufacturer\\\":\\\"Contoso\\\",\\\"model\\\":\\\"IoTDevice-Leaf\\\"}],\\\"instructions\\\":{\\\"steps\\\":[{\\\"handler\\\":\\\"microsoft/swupdate:1\\\",\\\"files\\\":[\\\"fa0feb4ccadb5c2fe\\\"],\\\"handlerProperties\\\":{\\\"installedCriteria\\\":\\\"7.0.2\\\"}}]},\\\"files\\\":{\\\"fa0feb4ccadb5c2fe\\\":{\\\"fileName\\\":\\\"leaf_firmware_7.0.2.bin\\\",\\\"sizeInBytes\\\":1978,\\\"hashes\\\":{\\\"sha256\\\":\\\"qr+xRWnfo/POaFNv+KVddBsJngGxCiSQ25WEW8t4dLc=\\\"}}},\\\"createdDateTime\\\":\\\"2022-12-19T05:25:47.922477Z\\\"}\"}"; + +unsigned char g_adu_agent_firmware[] = { + 0x23, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x49, 0x6f, 0x54, 0x20, + 0x48, 0x75, 0x62, 0x20, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x20, + 0x28, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x53, 0x68, 0x65, 0x6c, 0x6c, 0x29, + 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x54, 0x4d, 0x33, + 0x32, 0x4c, 0x34, 0x53, 0x35, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, + 0x70, 0x73, 0x31, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, + 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x53, 0x54, 0x4d, 0x34, 0x32, 0x4c, 0x34, 0x53, 0x35, 0x20, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x20, 0x55, 0x73, 0x65, 0x72, + 0x20, 0x63, 0x61, 0x6e, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x20, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x74, 0x6f, 0x20, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x74, 0x68, 0x72, 0x65, 0x65, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x20, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, + 0x74, 0x2e, 0x20, 0x4e, 0x6f, 0x74, 0x65, 0x3a, 0x20, 0x74, 0x68, 0x65, + 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x69, 0x72, + 0x6d, 0x77, 0x61, 0x72, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2e, 0x20, 0x59, 0x6f, 0x75, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x61, + 0x6c, 0x73, 0x6f, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x2a, 0x2a, 0x21, + 0x3f, 0x2a, 0x2a, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x68, 0x65, 0x6c, 0x70, + 0x2e, 0x20, 0x0a, 0x0a, 0x23, 0x23, 0x20, 0x31, 0x2e, 0x20, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, + 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x68, 0x6f, 0x73, 0x74, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x2e, 0x0a, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x74, 0x68, + 0x20, 0x6f, 0x66, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x20, 0x66, 0x69, 0x72, + 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, + 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x20, 0x2a, 0x2a, 0x66, + 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x32, 0x2e, 0x30, 0x2e, + 0x30, 0x2e, 0x62, 0x69, 0x6e, 0x2a, 0x2a, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x20, 0x2a, 0x2a, 0x53, + 0x54, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, + 0x6f, 0x6e, 0x69, 0x63, 0x73, 0x2e, 0x53, 0x54, 0x4d, 0x33, 0x32, 0x4c, + 0x34, 0x53, 0x35, 0x2e, 0x32, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, + 0x2e, 0x6a, 0x73, 0x6f, 0x6e, 0x2a, 0x2a, 0x20, 0x77, 0x69, 0x6c, 0x6c, + 0x20, 0x62, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x64, 0x20, 0x69, 0x6e, 0x20, 0x2a, 0x2a, 0x53, 0x54, 0x4d, 0x69, 0x63, + 0x72, 0x6f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, + 0x73, 0x2e, 0x53, 0x54, 0x4d, 0x33, 0x32, 0x4c, 0x34, 0x53, 0x35, 0x2e, + 0x32, 0x2e, 0x30, 0x2e, 0x30, 0x2a, 0x2a, 0x20, 0x66, 0x6f, 0x6c, 0x64, + 0x65, 0x72, 0x2e, 0x0a, 0x60, 0x60, 0x60, 0x0a, 0x50, 0x53, 0x20, 0x3e, + 0x20, 0x2e, 0x5c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x54, 0x4d, + 0x33, 0x32, 0x4c, 0x34, 0x53, 0x35, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x2e, 0x70, 0x73, 0x31, 0x0a, 0x0a, 0x63, 0x6d, 0x64, 0x6c, 0x65, 0x74, + 0x20, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x54, 0x4d, 0x33, 0x32, + 0x4c, 0x34, 0x53, 0x35, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, + 0x73, 0x31, 0x20, 0x61, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x20, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x0a, 0x53, 0x75, + 0x70, 0x70, 0x6c, 0x79, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, + 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, + 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x73, 0x3a, 0x0a, 0x28, 0x54, 0x79, 0x70, 0x65, 0x20, + 0x21, 0x3f, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x48, 0x65, 0x6c, 0x70, 0x2e, + 0x29, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x32, + 0x2e, 0x30, 0x2e, 0x30, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x61, 0x74, + 0x68, 0x3a, 0x20, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, + 0x32, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x62, 0x69, 0x6e, 0x0a, 0x60, 0x60, + 0x60, 0x0a, 0x0a, 0x23, 0x23, 0x20, 0x32, 0x2e, 0x20, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x6d, + 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, + 0x68, 0x6f, 0x73, 0x74, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x20, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x0a, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, + 0x6f, 0x66, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x20, 0x66, 0x69, 0x72, 0x6d, + 0x77, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x74, + 0x68, 0x20, 0x6f, 0x66, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x20, 0x66, 0x69, + 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x6e, + 0x20, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x20, 0x2a, 0x2a, + 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x32, 0x2e, 0x30, + 0x2e, 0x30, 0x2e, 0x62, 0x69, 0x6e, 0x2a, 0x2a, 0x2c, 0x20, 0x2a, 0x2a, + 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, + 0x65, 0x5f, 0x32, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x62, 0x69, 0x6e, 0x2a, + 0x2a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, + 0x73, 0x74, 0x20, 0x2a, 0x2a, 0x53, 0x54, 0x4d, 0x69, 0x63, 0x72, 0x6f, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x73, 0x2e, + 0x53, 0x54, 0x4d, 0x33, 0x32, 0x4c, 0x34, 0x53, 0x35, 0x2e, 0x32, 0x2e, + 0x30, 0x2e, 0x30, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x6d, 0x61, + 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x2e, 0x6a, 0x73, 0x6f, 0x6e, 0x2a, + 0x2a, 0x2c, 0x20, 0x2a, 0x2a, 0x53, 0x54, 0x4d, 0x69, 0x63, 0x72, 0x6f, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x73, 0x2e, + 0x53, 0x54, 0x4d, 0x33, 0x32, 0x4c, 0x34, 0x53, 0x35, 0x2d, 0x4c, 0x65, + 0x61, 0x66, 0x2e, 0x32, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x2e, + 0x6a, 0x73, 0x6f, 0x6e, 0x2a, 0x2a, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, + 0x62, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x69, 0x6e, 0x20, 0x2a, 0x2a, 0x53, 0x54, 0x4d, 0x69, 0x63, 0x72, + 0x6f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e, 0x69, 0x63, 0x73, + 0x2e, 0x53, 0x54, 0x4d, 0x33, 0x32, 0x4c, 0x34, 0x53, 0x35, 0x2e, 0x32, + 0x2e, 0x30, 0x2e, 0x30, 0x2a, 0x2a, 0x20, 0x66, 0x6f, 0x6c, 0x64, 0x65, + 0x72, 0x2e, 0x0a, 0x60, 0x60, 0x60, 0x0a, 0x50, 0x53, 0x20, 0x3e, 0x20, + 0x2e, 0x5c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x54, 0x4d, 0x33, + 0x32, 0x4c, 0x34, 0x53, 0x35, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, + 0x70, 0x73, 0x31, 0x0a, 0x0a, 0x63, 0x6d, 0x64, 0x6c, 0x65, 0x74, 0x20, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x54, 0x4d, 0x33, 0x32, 0x4c, + 0x34, 0x53, 0x35, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x73, + 0x31, 0x20, 0x61, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x20, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x0a, 0x53, 0x75, 0x70, + 0x70, 0x6c, 0x79, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x3a, 0x0a, 0x28, 0x54, 0x79, 0x70, 0x65, 0x20, 0x21, + 0x3f, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x48, 0x65, 0x6c, 0x70, 0x2e, 0x29, + 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x32, 0x2e, + 0x30, 0x2e, 0x30, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, + 0x3a, 0x20, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x32, + 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x62, 0x69, 0x6e, 0x0a, 0x4c, 0x65, 0x61, + 0x66, 0x50, 0x61, 0x74, 0x68, 0x3a, 0x20, 0x2e, 0x2f, 0x6c, 0x65, 0x61, + 0x66, 0x5f, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x32, + 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x62, 0x69, 0x6e, 0x0a, 0x60, 0x60, 0x60, + 0x0a, 0x0a, 0x23, 0x23, 0x20, 0x33, 0x2e, 0x20, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x6d, 0x61, + 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6c, + 0x65, 0x61, 0x66, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x0a, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x2c, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x6f, 0x66, 0x20, 0x6c, 0x65, + 0x61, 0x66, 0x20, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2c, + 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, + 0x72, 0x65, 0x20, 0x2a, 0x2a, 0x6c, 0x65, 0x61, 0x66, 0x5f, 0x66, 0x69, + 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x32, 0x2e, 0x30, 0x2e, 0x30, + 0x2e, 0x62, 0x69, 0x6e, 0x2a, 0x2a, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, + 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x20, 0x2a, 0x2a, 0x53, 0x54, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, + 0x6e, 0x69, 0x63, 0x73, 0x2e, 0x53, 0x54, 0x4d, 0x33, 0x32, 0x4c, 0x34, + 0x53, 0x35, 0x2e, 0x32, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x2e, + 0x6a, 0x73, 0x6f, 0x6e, 0x2a, 0x2a, 0x2c, 0x20, 0x2a, 0x2a, 0x53, 0x54, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, + 0x6e, 0x69, 0x63, 0x73, 0x2e, 0x53, 0x54, 0x4d, 0x33, 0x32, 0x4c, 0x34, + 0x53, 0x35, 0x2d, 0x4c, 0x65, 0x61, 0x66, 0x2e, 0x32, 0x2e, 0x30, 0x2e, + 0x30, 0x2e, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x6d, 0x61, 0x6e, 0x69, + 0x66, 0x65, 0x73, 0x74, 0x2e, 0x6a, 0x73, 0x6f, 0x6e, 0x2a, 0x2a, 0x20, + 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x2a, 0x2a, 0x53, + 0x54, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, + 0x6f, 0x6e, 0x69, 0x63, 0x73, 0x2e, 0x53, 0x54, 0x4d, 0x33, 0x32, 0x4c, + 0x34, 0x53, 0x35, 0x2e, 0x32, 0x2e, 0x30, 0x2e, 0x30, 0x2a, 0x2a, 0x20, + 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x2e, 0x0a, 0x60, 0x60, 0x60, 0x0a, + 0x50, 0x53, 0x20, 0x3e, 0x20, 0x2e, 0x5c, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x53, 0x54, 0x4d, 0x33, 0x32, 0x4c, 0x34, 0x53, 0x35, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x73, 0x31, 0x0a, 0x0a, 0x63, 0x6d, + 0x64, 0x6c, 0x65, 0x74, 0x20, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x54, 0x4d, 0x33, 0x32, 0x4c, 0x34, 0x53, 0x35, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x2e, 0x70, 0x73, 0x31, 0x20, 0x61, 0x74, 0x20, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x31, 0x0a, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x3a, 0x0a, 0x28, 0x54, + 0x79, 0x70, 0x65, 0x20, 0x21, 0x3f, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x48, + 0x65, 0x6c, 0x70, 0x2e, 0x29, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x3a, 0x20, 0x32, 0x2e, 0x30, 0x2e, 0x30, 0x0a, 0x48, 0x6f, 0x73, + 0x74, 0x50, 0x61, 0x74, 0x68, 0x3a, 0x0a, 0x4c, 0x65, 0x61, 0x66, 0x50, + 0x61, 0x74, 0x68, 0x3a, 0x20, 0x2e, 0x2f, 0x6c, 0x65, 0x61, 0x66, 0x5f, + 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x32, 0x2e, 0x30, + 0x2e, 0x30, 0x2e, 0x62, 0x69, 0x6e, 0x0a, 0x60, 0x60, 0x60 +}; +unsigned int g_adu_agent_firmware_size = 1978; + +static const UCHAR g_adu_agent_response_proxy_preprocess_error[] = "{\"deviceUpdate\":{\"__t\":\"c\",\"agent\":{\"state\":255,\"workflow\":{\"action\":3,\"id\":\"6b831565-bd1c-4b84-995a-f2ab4e6a4bb1\"},\"lastInstallResult\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\",\"stepResults\":{\"step_0\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\"},\"step_1\":{\"resultCode\":200,\"extendedResultCode\":0,\"resultDetails\":\"\"}}}}}}"; +static const UCHAR g_adu_agent_response_proxy_write_error[] = "{\"deviceUpdate\":{\"__t\":\"c\",\"agent\":{\"state\":255,\"workflow\":{\"action\":3,\"id\":\"6b831565-bd1c-4b84-995a-f2ab4e6a4bb1\"},\"lastInstallResult\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\",\"stepResults\":{\"step_0\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\"},\"step_1\":{\"resultCode\":200,\"extendedResultCode\":0,\"resultDetails\":\"\"}}}}}}"; +static const UCHAR g_adu_agent_response_proxy_install_error[] = "{\"deviceUpdate\":{\"__t\":\"c\",\"agent\":{\"state\":255,\"workflow\":{\"action\":3,\"id\":\"6b831565-bd1c-4b84-995a-f2ab4e6a4bb1\"},\"lastInstallResult\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\",\"stepResults\":{\"step_0\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\"},\"step_1\":{\"resultCode\":200,\"extendedResultCode\":0,\"resultDetails\":\"\"}}}}}}"; +static const UCHAR g_adu_agent_response_proxy_apply_error[] = "{\"deviceUpdate\":{\"__t\":\"c\",\"agent\":{\"state\":255,\"workflow\":{\"action\":3,\"id\":\"6b831565-bd1c-4b84-995a-f2ab4e6a4bb1\"},\"lastInstallResult\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\",\"stepResults\":{\"step_0\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\"},\"step_1\":{\"resultCode\":600,\"extendedResultCode\":0,\"resultDetails\":\"\"}}}}}}"; + +static const UCHAR g_adu_agent_response_preprocess_error[] = "{\"deviceUpdate\":{\"__t\":\"c\",\"agent\":{\"state\":255,\"workflow\":{\"action\":3,\"id\":\"6b831565-bd1c-4b84-995a-f2ab4e6a4bb1\"},\"lastInstallResult\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\",\"stepResults\":{\"step_0\":{\"resultCode\":600,\"extendedResultCode\":0,\"resultDetails\":\"\"},\"step_1\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\"}}}}}}"; +static const UCHAR g_adu_agent_response_write_error[] = "{\"deviceUpdate\":{\"__t\":\"c\",\"agent\":{\"state\":255,\"workflow\":{\"action\":3,\"id\":\"6b831565-bd1c-4b84-995a-f2ab4e6a4bb1\"},\"lastInstallResult\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\",\"stepResults\":{\"step_0\":{\"resultCode\":600,\"extendedResultCode\":0,\"resultDetails\":\"\"},\"step_1\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\"}}}}}}"; +static const UCHAR g_adu_agent_response_install_error[] = "{\"deviceUpdate\":{\"__t\":\"c\",\"agent\":{\"state\":255,\"workflow\":{\"action\":3,\"id\":\"6b831565-bd1c-4b84-995a-f2ab4e6a4bb1\"},\"lastInstallResult\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\",\"stepResults\":{\"step_0\":{\"resultCode\":600,\"extendedResultCode\":0,\"resultDetails\":\"\"},\"step_1\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\"}}}}}}"; +static const UCHAR g_adu_agent_response_apply_error[] = "{\"deviceUpdate\":{\"__t\":\"c\",\"agent\":{\"state\":255,\"workflow\":{\"action\":3,\"id\":\"6b831565-bd1c-4b84-995a-f2ab4e6a4bb1\"},\"lastInstallResult\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\",\"stepResults\":{\"step_0\":{\"resultCode\":700,\"extendedResultCode\":0,\"resultDetails\":\"\"},\"step_1\":{\"resultCode\":0,\"extendedResultCode\":0,\"resultDetails\":\"\"}}}}}}"; + +static const UCHAR g_adu_agent_response_success[] = "{\"deviceUpdate\":{\"__t\":\"c\",\"agent\":{\"state\":0,\"workflow\":{\"action\":3,\"id\":\"6b831565-bd1c-4b84-995a-f2ab4e6a4bb1\"},\"installedUpdateId\":\"{\\\"provider\\\":\\\"Contoso\\\",\\\"name\\\":\\\"IoTDevice\\\",\\\"version\\\":\\\"7.0.1\\\"}\",\"lastInstallResult\":{\"resultCode\":700,\"extendedResultCode\":0,\"resultDetails\":\"\",\"stepResults\":{\"step_0\":{\"resultCode\":700,\"extendedResultCode\":0,\"resultDetails\":\"\"},\"step_1\":{\"resultCode\":700,\"extendedResultCode\":0,\"resultDetails\":\"\"}}}}}}"; + + +static UINT g_version = 10; + +static UINT g_total_append = 0; +static UINT g_failed_append_index = 0; +static UINT g_total_allocation = 0; +static UINT g_failed_allocation_index = -1; +static NX_IP* g_ip_ptr; +static NX_PACKET_POOL* g_pool_ptr; +static NX_DNS* g_dns_ptr; +static ULONG g_available_packet; +static UINT generate_test_property_send_response_bytes = NX_FALSE; +static UINT generate_test_properties_new_update = NX_FALSE; +static UINT handle_agent_update_received_notify = NX_FALSE; + +static UINT g_update_received_count = 0; +static UINT g_update_applied_count = 0; + +static UINT g_adu_agent_driver_preprocess_fail = NX_FALSE; +static UINT g_adu_agent_driver_write_fail = NX_FALSE; +static UINT g_adu_agent_driver_install_fail = NX_FALSE; +static UINT g_adu_agent_driver_apply_fail = NX_FALSE; + +static UINT g_adu_agent_proxy_driver_preprocess_fail = NX_FALSE; +static UINT g_adu_agent_proxy_driver_write_fail = NX_FALSE; +static UINT g_adu_agent_proxy_driver_install_fail = NX_FALSE; +static UINT g_adu_agent_proxy_driver_apply_fail = NX_FALSE; + +static UINT g_ingore_manifest_verification = NX_FALSE; + +/* HTTP data type. */ +#define HTTP_DATA_TYPE_PROXY_MANIFEST 1 +#define HTTP_DATA_TYPE_FIRMWARE 2 + +static UINT g_adu_agent_http_data_type = 0; + +static UCHAR g_adu_metadata[6*1024]; + +extern UINT _nxd_mqtt_client_append_message(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, CHAR *message, + UINT length, ULONG wait_option); +extern UINT _nxd_mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + UCHAR control_header, UINT length, UINT wait_option); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iothub_client; +static NX_AZURE_IOT_ADU_AGENT adu_agent; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +static UCHAR message_payload[MAXIMUM_PAYLOAD_LENGTH]; +static UCHAR result_buffer[MAXIMUM_PAYLOAD_LENGTH]; +static UCHAR packet_buffer[MAXIMUM_PAYLOAD_LENGTH]; +static VOID (*test_receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count) = NX_NULL; + +UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr, + VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count)) +{ + printf("HIJACKED: %s\n", __func__); + test_receive_notify = receive_notify; + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_subscribe(NXD_MQTT_CLIENT *client_ptr, UINT op, + CHAR *topic_name, UINT topic_name_length, + USHORT *packet_id_ptr, UINT QoS) +{ + printf("HIJACKED: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_properties_subscribe_ack = NX_TRUE; + + return((UINT)mock()); +} + +UINT __real__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option); +UINT __wrap__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_append_index == g_total_append) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_append++; + return __real__nx_packet_data_append(packet_ptr, data_start, data_size, pool_ptr, wait_option); +} + +UINT __real_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context); +UINT __wrap_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_allocation_index == g_total_allocation) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_allocation++; + return __real_nx_azure_iot_buffer_allocate(nx_azure_iot_ptr, buffer_pptr, buffer_size, buffer_context); +} + +UINT __wrap__nxd_mqtt_client_publish_packet_send(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + USHORT packet_id, UINT QoS, ULONG wait_option) +{ +UINT topic_name_length; +UINT message_length; +UCHAR *buffer_ptr; + + printf("HIJACKED: %s\n", __func__); + tx_mutex_put(client_ptr -> nxd_mqtt_client_mutex_ptr); + + if ((g_expected_message) && (g_expected_message_index == 0)) + { + buffer_ptr = packet_ptr -> nx_packet_prepend_ptr; + topic_name_length = (buffer_ptr[5] << 8) | (buffer_ptr[6]); + message_length = packet_ptr -> nx_packet_length - (7 + topic_name_length); + assert_memory_equal(&buffer_ptr[7 + topic_name_length], g_expected_message, message_length); + } + + if (g_expected_message_index) + { + g_expected_message_index--; + } + + /* packet ownership taken and released */ + nx_packet_release(packet_ptr); + + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, + UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *, + NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *), + UINT keepalive, UINT clean_session, ULONG wait_option) +{ +az_span source = az_span_create(client_ptr -> nxd_mqtt_client_username, + (INT)client_ptr -> nxd_mqtt_client_username_length); +az_span target = az_span_create((UCHAR *)g_pnp_model_id, sizeof(g_pnp_model_id) - 1); + + printf("HIJACKED: %s\n", __func__); + + /* Check username and client Id to contain modelId and device */ + assert_memory_equal(client_ptr -> nxd_mqtt_client_id, g_device_id, sizeof(g_device_id) - 1); + assert_int_not_equal(az_span_find(source, target), -1); + + tx_thread_suspend(&(iot.nx_azure_iot_ip_ptr -> nx_ip_thread)); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + client_ptr -> nxd_mqtt_client_packet_identifier = 1; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_FALSE; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &client_ptr -> nxd_mqtt_client_socket; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr) +{ + printf("HIJACKED: %s\n", __func__); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ + printf("HIJACKED: %s\n", __func__); + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NX_DNS_SUCCESS); +} + +UINT __wrap__nxe_web_http_client_connect(NX_WEB_HTTP_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_SUCCESS); +} + +UINT __wrap__nxe_web_http_client_request_send(NX_WEB_HTTP_CLIENT *client_ptr, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_SUCCESS); +} + +UINT __wrap__nxe_web_http_client_response_body_get(NX_WEB_HTTP_CLIENT *client_ptr, NX_PACKET **packet_ptr, ULONG wait_option) +{ +NX_PACKET *data_packet; +UCHAR fake_binary[] = "test binary data"; + + printf("HIJACKED: %s\n", __func__); + + assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &data_packet, 0, NX_NO_WAIT), NX_AZURE_IOT_SUCCESS); + if (g_adu_agent_http_data_type == HTTP_DATA_TYPE_PROXY_MANIFEST) + { + assert_int_equal(__real__nx_packet_data_append(data_packet, (VOID *)g_adu_agent_proxy_manifest, sizeof(g_adu_agent_proxy_manifest) - 1, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + else if (g_adu_agent_http_data_type == HTTP_DATA_TYPE_FIRMWARE) + { + assert_int_equal(__real__nx_packet_data_append(data_packet, (VOID *)g_adu_agent_firmware, g_adu_agent_firmware_size, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + else + { + assert_int_equal(__real__nx_packet_data_append(data_packet, fake_binary, sizeof(fake_binary) - 1, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + + *packet_ptr = data_packet; + + return(NX_WEB_HTTP_GET_DONE); +} + +static UINT mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, UCHAR control_header, UINT length, UINT wait_option) +{ +UCHAR fixed_header[5]; +UCHAR *byte = fixed_header; +UINT count = 0; +UINT ret; + + *byte = control_header; + byte++; + + do + { + if (length & 0xFFFFFF80) + { + *(byte + count) = (UCHAR)((length & 0x7F) | 0x80); + } + else + { + *(byte + count) = length & 0x7F; + } + length = length >> 7; + + count++; + } while (length != 0); + + ret = __real__nx_packet_data_append(packet_ptr, fixed_header, count + 1, + client_ptr -> nxd_mqtt_client_packet_pool_ptr, wait_option); + + return(ret); +} + +static VOID construct_command_message(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, + const UCHAR *topic, ULONG topic_len, + const UCHAR *message_payload_ptr, ULONG message_payload_length, + NX_PACKET **packet_pptr) +{ +NX_PACKET *packet_ptr; +ULONG total_length; +ULONG topic_length = topic_len; +UCHAR bytes[2]; +UINT i; + + assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + total_length = topic_length + 2 + 2 + message_payload_length; /* Two bytes for fixed topic_length field + and two bytes for packet id. */ + + /* Set fixed header. */ + assert_int_equal(mqtt_client_set_fixed_header(&(MQTT_CLIENT_GET(iothub_client_ptr)), packet_ptr, + (UCHAR)((MQTT_CONTROL_PACKET_TYPE_PUBLISH << 4) | MQTT_PUBLISH_QOS_LEVEL_1), + total_length, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic length. */ + bytes[0] = (topic_length >> 8) & 0xFF; + bytes[1] = topic_length & 0xFF; + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)topic, topic_len, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + /* Set packet ID. The value does not matter. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set message payload. */ + if (message_payload_length > 0) + { + assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)message_payload_ptr, message_payload_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + + *packet_pptr = packet_ptr; +} + +#if 0 +extern UINT nx_azure_iot_adu_agent_component_properties_process(VOID *reader_ptr, + ULONG version, + VOID *args); + +static VOID inject_new_update(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr) +{ +NX_AZURE_IOT_JSON_READER reader_ptr; + + nx_azure_iot_json_reader_with_buffer_init(&reader_ptr, g_adu_agent_service_metedata, sizeof(g_adu_agent_service_metedata) - 1); + + nx_azure_iot_json_reader_next_token(&reader_ptr); + + nx_azure_iot_json_reader_next_token(&reader_ptr); + + nx_azure_iot_adu_agent_component_properties_process(&reader_ptr, g_version, &adu_agent); +} +#endif + +static UCHAR topic_buffer[100]; +static VOID generate_test_property_send_response(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr) +{ +NX_PACKET *packet_ptr; +UINT topic_size; + + printf("Bytes : %s\n", __func__); + + topic_size = snprintf(topic_buffer, sizeof(topic_buffer), reported_property_success_topic, reported_property_success_topic_count); + construct_command_message(iothub_client_ptr, topic_buffer, + topic_size, "", 0, &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(iothub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(iothub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(iothub_client_ptr)); +} + +static VOID generate_test_property_new_update_send(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr) +{ +NX_PACKET *packet_ptr; +UINT topic_size; + + printf("Bytes : %s\n", __func__); + + topic_size = snprintf(topic_buffer, sizeof(topic_buffer), reported_property_success_topic, reported_property_success_topic_count); + construct_command_message(iothub_client_ptr, + g_adu_agent_new_udpate_topic, + sizeof(g_adu_agent_new_udpate_topic) - 1, + g_adu_agent_new_udpate, + g_adu_agent_new_udpate_size - 1, + &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(iothub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(iothub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(iothub_client_ptr)); +} + +static VOID generate_test_property_cancel_update_send(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr) +{ +NX_PACKET *packet_ptr; +UINT topic_size; + + printf("Bytes : %s\n", __func__); + + topic_size = snprintf(topic_buffer, sizeof(topic_buffer), reported_property_success_topic, reported_property_success_topic_count); + construct_command_message(iothub_client_ptr, + g_adu_agent_cancel_udpate_topic, + sizeof(g_adu_agent_cancel_udpate_topic) - 1, + g_adu_agent_cancel_update, + sizeof(g_adu_agent_cancel_update) - 1, + &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(iothub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(iothub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(iothub_client_ptr)); +} + +/* Generate network received bytes */ +static VOID network_bytes_generate_entry(ULONG args) +{ + while (NX_TRUE) + { + if (generate_test_property_send_response_bytes) + { + generate_test_property_send_response_bytes = NX_FALSE; + generate_test_property_send_response(&iothub_client); + } + + if (generate_test_properties_new_update) + { + generate_test_properties_new_update = NX_FALSE; + generate_test_property_new_update_send(&iothub_client); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } +} + +static VOID on_receive_callback(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, VOID *arg) +{ + *((UINT *)arg) = 1; +} + +static VOID reported_property_cb(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, + UINT request_id, UINT response_status, + ULONG version, VOID *args) +{ + *((UINT *)args) = response_status; +} + +static VOID reset_global_state() +{ + /* reset global state */ + g_failed_append_index = (UINT)-1; + g_total_append = 0; + g_failed_allocation_index = (UINT)-1; + g_total_allocation = 0; + generate_test_property_send_response_bytes = NX_FALSE; + generate_test_properties_new_update = NX_FALSE; +} + +/* Hook execute before all tests. */ +static VOID test_suit_begin() +{ + assert_int_equal(tx_thread_create(&network_bytes_generate_thread, + "UintTestNetworkBytesGenerator", + network_bytes_generate_entry, 0, + network_bytes_generate_stack, + DEMO_HELPER_STACK_SIZE, + DEMO_HELPER_THREAD_PRIORITY + 1, + DEMO_HELPER_THREAD_PRIORITY + 1, + TX_NO_TIME_SLICE, TX_AUTO_START), + NX_AZURE_IOT_SUCCESS); + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, + (UCHAR *)_nx_azure_iot_root_cert, + (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", + g_ip_ptr, g_pool_ptr, g_dns_ptr, + (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), + DEMO_CLOUD_THREAD_PRIORITY, unix_time_get), + NX_AZURE_IOT_SUCCESS); + + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&iothub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&iothub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); + + /* Set symmetric key credentials */ + assert_int_equal(nx_azure_iot_hub_client_symmetric_key_set(&iothub_client, + g_symmetric_key, + sizeof(g_symmetric_key) - 1), + NX_AZURE_IOT_SUCCESS); + + will_return_always(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + + /* Connect IoTHub client */ + assert_int_equal(nx_azure_iot_hub_client_connect(&iothub_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + /* Enable properties. */ + assert_int_equal(nx_azure_iot_hub_client_properties_enable(&iothub_client), + NX_AZURE_IOT_SUCCESS); +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_suit_end() +{ + assert_int_equal(nx_azure_iot_hub_client_disconnect(&iothub_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iothub_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_delete(&iot), + NX_AZURE_IOT_SUCCESS); +} + +/* Hook executed before every test */ +static VOID test_begin() +{ + reset_global_state(); + + /* Record number of available packet before test */ + g_available_packet = g_pool_ptr -> nx_packet_pool_available; +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_end() +{ + /* Check if all the packet are released */ + assert_int_equal(g_pool_ptr -> nx_packet_pool_available, g_available_packet); +} + +static void nx_azure_iot_adu_agent_driver(NX_AZURE_IOT_ADU_AGENT_DRIVER *driver_req_ptr) +{ + + /* Default to successful return. */ + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_SUCCESS; + + /* Process according to the driver request type. */ + switch (driver_req_ptr -> nx_azure_iot_adu_agent_driver_command) + { + + case NX_AZURE_IOT_ADU_AGENT_DRIVER_INITIALIZE: + { + + /* Process initialize requests. */ + break; + } + + case NX_AZURE_IOT_ADU_AGENT_DRIVER_PREPROCESS: + { + + /* Process firmware preprocess requests before writing firmware. + Such as: erase the flash at once to improve the speed. */ + if (g_adu_agent_driver_preprocess_fail) + { + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_FAILURE; + } + + else if ((memcmp(driver_req_ptr -> nx_azure_iot_adu_agent_driver_firmware_sha256, "qr+xRWnfo/POaFNv+KVddBsJngGxCiSQ25WEW8t4dLc=", driver_req_ptr -> nx_azure_iot_adu_agent_driver_firmware_sha256_length) != 0) && + (memcmp(driver_req_ptr -> nx_azure_iot_adu_agent_driver_firmware_sha256, "Fqv5r0ZD/x6ok0aRqJERX2JuW36O+GOxn0/r7aBJkOs=", driver_req_ptr -> nx_azure_iot_adu_agent_driver_firmware_sha256_length) != 0)) /* For update 2. */ + { + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_FAILURE; + } + + break; + } + + case NX_AZURE_IOT_ADU_AGENT_DRIVER_WRITE: + { + + /* Process firmware write requests. */ + + /* Write firmware contents. + 1. This function must support figure out which bank it should write to. + 2. Write firmware contents into new bank. + 3. Decrypt and authenticate the firmware itself if needed. + */ + if (g_adu_agent_driver_write_fail) + { + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_FAILURE; + } + + break; + } + + case NX_AZURE_IOT_ADU_AGENT_DRIVER_INSTALL: + { + + /* Set the new firmware for next boot. */ + if (g_adu_agent_driver_install_fail) + { + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_FAILURE; + } + + break; + } + + case NX_AZURE_IOT_ADU_AGENT_DRIVER_APPLY: + { + + /* Apply the new firmware, and reboot device from that.*/ + if (g_adu_agent_driver_apply_fail) + { + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_FAILURE; + } + + break; + } + default: + { + + /* Invalid driver request. */ + + /* Default to successful return. */ + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_FAILURE; + } + } +} + +#if (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1) +static void nx_azure_iot_adu_agent_proxy_driver(NX_AZURE_IOT_ADU_AGENT_DRIVER *driver_req_ptr) +{ + + /* Default to successful return. */ + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_SUCCESS; + + /* Process according to the driver request type. */ + switch (driver_req_ptr -> nx_azure_iot_adu_agent_driver_command) + { + + case NX_AZURE_IOT_ADU_AGENT_DRIVER_INITIALIZE: + { + + /* Process initialize requests. */ + break; + } + + case NX_AZURE_IOT_ADU_AGENT_DRIVER_PREPROCESS: + { + + /* Process firmware preprocess requests before writing firmware. + Such as: erase the flash at once to improve the speed. */ + if (g_adu_agent_proxy_driver_preprocess_fail) + { + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_FAILURE; + } + + else if (memcmp(driver_req_ptr -> nx_azure_iot_adu_agent_driver_firmware_sha256, "qr+xRWnfo/POaFNv+KVddBsJngGxCiSQ25WEW8t4dLc=", driver_req_ptr -> nx_azure_iot_adu_agent_driver_firmware_sha256_length) != 0) + { + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_FAILURE; + } + + break; + } + + case NX_AZURE_IOT_ADU_AGENT_DRIVER_WRITE: + { + + /* Process firmware write requests. */ + + /* Write firmware contents. + 1. This function must support figure out which bank it should write to. + 2. Write firmware contents into new bank. + 3. Decrypt and authenticate the firmware itself if needed. + */ + if (g_adu_agent_proxy_driver_write_fail) + { + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_FAILURE; + } + + break; + } + + case NX_AZURE_IOT_ADU_AGENT_DRIVER_INSTALL: + { + + /* Set the new firmware for next boot. */ + if (g_adu_agent_proxy_driver_install_fail) + { + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_FAILURE; + } + + break; + } + + case NX_AZURE_IOT_ADU_AGENT_DRIVER_APPLY: + { + + /* Apply the new firmware, and reboot device from that.*/ + if (g_adu_agent_proxy_driver_apply_fail) + { + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_FAILURE; + } + + break; + } + default: + { + + /* Invalid driver request. */ + + /* Default to successful return. */ + driver_req_ptr -> nx_azure_iot_adu_agent_driver_status = NX_AZURE_IOT_FAILURE; + } + } +} +#endif /* (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1) */ + +static void adu_agent_update_notify(NX_AZURE_IOT_ADU_AGENT *adu_agent_ptr, + UINT update_state, + UCHAR *provider, UINT provider_length, + UCHAR *name, UINT name_length, + UCHAR *version, UINT version_length) +{ + + if (update_state == NX_AZURE_IOT_ADU_AGENT_UPDATE_RECEIVED) + { + + g_update_received_count++; + + if(handle_agent_update_received_notify) + { + /* Received new update. */ + printf("Received new update: Provider: %.*s; Name: %.*s, Version: %.*s\r\n", + provider_length, provider, name_length, name, version_length, version); + + /* Start to download and install update immediately for testing. */ + nx_azure_iot_adu_agent_update_download_and_install(adu_agent_ptr); + } + } + else if(update_state == NX_AZURE_IOT_ADU_AGENT_UPDATE_INSTALLED) + { + g_update_applied_count++; + + /* Start to apply update immediately for testing. */ + nx_azure_iot_adu_agent_update_apply(adu_agent_ptr); + } +} + +/** + * Test invalid argument failure. + * + **/ +static VOID test_nx_azure_iot_adu_agent_invalid_argument_fail() +{ +NX_AZURE_IOT_JSON_WRITER writer; +NX_AZURE_IOT_JSON_READER reader; +const UCHAR *component_name; +UINT length; + + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_adu_agent_start(NX_NULL, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_start(&adu_agent, + NX_NULL, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + NX_NULL, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, 0, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + NX_NULL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, 0, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + NX_NULL, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + NX_NULL), + NX_AZURE_IOT_SUCCESS); + +#if (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1) + + assert_int_not_equal(nx_azure_iot_adu_agent_proxy_update_add(NX_NULL, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MANUFACTURER, sizeof(SAMPLE_LEAF_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MODEL, sizeof(SAMPLE_LEAF_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA) - 1, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_proxy_update_add(&adu_agent, + NX_NULL, sizeof(SAMPLE_LEAF_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MODEL, sizeof(SAMPLE_LEAF_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA) - 1, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_proxy_update_add(&adu_agent, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MANUFACTURER, 0, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MODEL, sizeof(SAMPLE_LEAF_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA) - 1, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_proxy_update_add(&adu_agent, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MANUFACTURER, sizeof(SAMPLE_LEAF_DEVICE_MANUFACTURER) - 1, + NX_NULL, sizeof(SAMPLE_LEAF_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA) - 1, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_proxy_update_add(&adu_agent, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MANUFACTURER, sizeof(SAMPLE_LEAF_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MODEL, 0, + (const UCHAR *)SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA) - 1, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + + assert_int_not_equal(nx_azure_iot_adu_agent_proxy_update_add(&adu_agent, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MANUFACTURER, sizeof(SAMPLE_LEAF_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MODEL, sizeof(SAMPLE_LEAF_DEVICE_MODEL) - 1, + NX_NULL, sizeof(SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA) - 1, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_proxy_update_add(&adu_agent, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MANUFACTURER, sizeof(SAMPLE_LEAF_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MODEL, sizeof(SAMPLE_LEAF_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA) - 1, + NX_NULL), + NX_AZURE_IOT_SUCCESS); + +#endif /* (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1) */ + + assert_int_not_equal(nx_azure_iot_adu_agent_stop(NX_NULL), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_update_download_and_install(NX_NULL), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_update_apply(NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful adu agent start. + * + **/ +static VOID test_nx_azure_iot_adu_agent_start_success() +{ +NX_AZURE_IOT_JSON_WRITER writer; +UINT request_id; +UINT response_status; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + reported_property_success_topic_count = 1; + generate_test_property_send_response_bytes = NX_TRUE; + + /* Build startup message. */ + snprintf(g_adu_agent_reported_property_startup, + sizeof(g_adu_agent_reported_property_startup), + "%s%d.%d.%d%s", + (const char *)g_adu_agent_reported_property_startup1, + NETXDUO_MAJOR_VERSION, + NETXDUO_MINOR_VERSION, + NETXDUO_PATCH_VERSION, + (const char *)g_adu_agent_reported_property_startup2); + g_expected_message = g_adu_agent_reported_property_startup; + + assert_int_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + + /* Reset. */ + g_expected_message = NX_NULL; +} + +/** + * Test adu agent update apply fail. + * + **/ +static VOID test_nx_azure_iot_adu_agent_update_start_fail() +{ +NX_AZURE_IOT_JSON_WRITER writer; +UINT request_id; +UINT response_status; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_adu_agent_update_download_and_install(NX_NULL), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_adu_agent_update_apply(NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful adu agent stop. + * + **/ +static VOID test_nx_azure_iot_adu_agent_stop_success() +{ +NX_AZURE_IOT_JSON_WRITER writer; +UINT request_id; +UINT response_status; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + /* Stop ADU agent. */ + assert_int_equal(nx_azure_iot_adu_agent_stop(&adu_agent), + NX_AZURE_IOT_SUCCESS); + + /* Restart ADU agent. */ + reported_property_success_topic_count += 2; + generate_test_property_send_response_bytes = NX_TRUE; + + assert_int_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + /* Stop ADU agent again. */ + assert_int_equal(nx_azure_iot_adu_agent_stop(&adu_agent), + NX_AZURE_IOT_SUCCESS); +} + +#if (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1) +/** + * Test proxy add. + * + **/ +static VOID test_nx_azure_iot_adu_agent_proxy_add() +{ +NX_AZURE_IOT_JSON_WRITER writer; +UINT request_id; +UINT response_status; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + /* Restart ADU agent. */ + reported_property_success_topic_count += 2; + generate_test_property_send_response_bytes = NX_TRUE; + + assert_int_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_adu_agent_proxy_update_add(&adu_agent, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MANUFACTURER, sizeof(SAMPLE_LEAF_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MODEL, sizeof(SAMPLE_LEAF_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA) - 1, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_adu_agent_proxy_update_add(&adu_agent, + (const UCHAR *)SAMPLE_LEAF2_DEVICE_MANUFACTURER, sizeof(SAMPLE_LEAF2_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_LEAF2_DEVICE_MODEL, sizeof(SAMPLE_LEAF2_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_LEAF2_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_LEAF2_DEVICE_INSTALLED_CRITERIA) - 1, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_NO_MORE_ENTRIES); + + /* Stop ADU agent again. */ + assert_int_equal(nx_azure_iot_adu_agent_stop(&adu_agent), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test step result. + * + **/ +static VOID test_nx_azure_iot_adu_agent_step_result() +{ +NX_AZURE_IOT_JSON_WRITER writer; +UINT request_id; +UINT response_status; +ULONG version; +NX_PACKET *packet_ptr; +UINT i; + + printf("test starts =>: %s\n", __func__); + + for (i = 0; i < 9; i++) + { + + /* Restart ADU agent. */ + reported_property_success_topic_count += 2; + generate_test_property_send_response_bytes = NX_TRUE; + handle_agent_update_received_notify = NX_TRUE; + + assert_int_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_adu_agent_proxy_update_add(&adu_agent, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MANUFACTURER, sizeof(SAMPLE_LEAF_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MODEL, sizeof(SAMPLE_LEAF_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA) - 1, + nx_azure_iot_adu_agent_proxy_driver), + NX_AZURE_IOT_SUCCESS); + + adu_agent.nx_azure_iot_adu_agent_crypto.method_rsa_metadata = g_adu_metadata; + adu_agent.nx_azure_iot_adu_agent_crypto.method_rsa_metadata_size = sizeof(g_adu_metadata); + + /* Set the expected message and check the third mesage (reported state message). */ + if (i == 0) + { + g_adu_agent_proxy_driver_preprocess_fail = NX_TRUE; + g_expected_message = g_adu_agent_response_proxy_preprocess_error; + } + else if (i == 1) + { + g_adu_agent_proxy_driver_write_fail = NX_TRUE; + g_expected_message = g_adu_agent_response_proxy_write_error; + } + else if (i == 2) + { + g_adu_agent_proxy_driver_install_fail = NX_TRUE; + g_expected_message = g_adu_agent_response_proxy_write_error; + } + else if (i == 3) + { + g_adu_agent_driver_preprocess_fail = NX_TRUE; + g_expected_message = g_adu_agent_response_preprocess_error; + } + else if (i == 4) + { + g_adu_agent_driver_write_fail = NX_TRUE; + g_expected_message = g_adu_agent_response_write_error; + } + else if (i == 5) + { + g_adu_agent_driver_install_fail = NX_TRUE; + g_expected_message = g_adu_agent_response_write_error; + } + else if (i == 6) + { + g_adu_agent_proxy_driver_apply_fail = NX_TRUE; + g_expected_message = g_adu_agent_response_proxy_apply_error; + } + else if (i == 7) + { + g_adu_agent_driver_apply_fail = NX_TRUE; + g_expected_message = g_adu_agent_response_apply_error; + } + else + { + g_expected_message = g_adu_agent_response_success; + } + + g_expected_message_index = 2; + reported_property_success_topic_count += 6; + + /* Inject the new update message. */ + g_adu_agent_new_udpate = g_adu_agent_new_update_3; + g_adu_agent_new_udpate_size = sizeof(g_adu_agent_new_update_3); + generate_test_property_new_update_send(&iothub_client); + + tx_thread_sleep(100); + + assert_int_equal(nx_azure_iot_hub_client_writable_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + /* Receive proxy manifest. */ + g_adu_agent_http_data_type = HTTP_DATA_TYPE_PROXY_MANIFEST; + nx_cloud_module_event_set(&(adu_agent.nx_azure_iot_adu_agent_cloud_module), NX_AZURE_IOT_ADU_AGENT_HTTP_RECEIVE_EVENT); + tx_thread_sleep(100); + + if (i != 0) + { + + /* Receive proxy firmware. */ + g_adu_agent_http_data_type = HTTP_DATA_TYPE_FIRMWARE; + nx_cloud_module_event_set(&(adu_agent.nx_azure_iot_adu_agent_cloud_module), NX_AZURE_IOT_ADU_AGENT_HTTP_RECEIVE_EVENT); + tx_thread_sleep(100); + } + + if (i >= 4) + { + + /* Receive firmware. */ + g_adu_agent_http_data_type = HTTP_DATA_TYPE_FIRMWARE; + nx_cloud_module_event_set(&(adu_agent.nx_azure_iot_adu_agent_cloud_module), NX_AZURE_IOT_ADU_AGENT_HTTP_RECEIVE_EVENT); + tx_thread_sleep(100); + } + + /* Stop ADU agent. */ + assert_int_equal(nx_azure_iot_adu_agent_stop(&adu_agent), + NX_AZURE_IOT_SUCCESS); + + /* Reset */ + g_adu_agent_proxy_driver_preprocess_fail = NX_FALSE; + g_adu_agent_proxy_driver_write_fail = NX_FALSE; + g_adu_agent_proxy_driver_install_fail = NX_FALSE; + g_adu_agent_proxy_driver_apply_fail = NX_FALSE; + g_adu_agent_driver_preprocess_fail = NX_FALSE; + g_adu_agent_driver_write_fail = NX_FALSE; + g_adu_agent_driver_install_fail = NX_FALSE; + g_adu_agent_driver_apply_fail = NX_FALSE; + g_expected_message = NX_NULL; + } +} + + +/** + * Test null file url. + * + **/ +static VOID test_nx_azure_iot_adu_agent_null_file_url() +{ +NX_AZURE_IOT_JSON_WRITER writer; +UINT request_id; +UINT response_status; +ULONG version; +NX_PACKET *packet_ptr; + + printf("test starts =>: %s\n", __func__); + + /* Restart ADU agent. */ + reported_property_success_topic_count += 2; + generate_test_property_send_response_bytes = NX_TRUE; + handle_agent_update_received_notify = NX_TRUE; + + assert_int_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_adu_agent_proxy_update_add(&adu_agent, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MANUFACTURER, sizeof(SAMPLE_LEAF_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_MODEL, sizeof(SAMPLE_LEAF_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_LEAF_DEVICE_INSTALLED_CRITERIA) - 1, + nx_azure_iot_adu_agent_proxy_driver), + NX_AZURE_IOT_SUCCESS); + + adu_agent.nx_azure_iot_adu_agent_crypto.method_rsa_metadata = g_adu_metadata; + adu_agent.nx_azure_iot_adu_agent_crypto.method_rsa_metadata_size = sizeof(g_adu_metadata); + + g_expected_message = g_adu_agent_response_success; + g_expected_message_index = 2; + reported_property_success_topic_count += 6; + + /* Inject the new update message. */ + g_adu_agent_new_udpate = g_adu_agent_new_update_4; + g_adu_agent_new_udpate_size = sizeof(g_adu_agent_new_update_4); + generate_test_property_new_update_send(&iothub_client); + + tx_thread_sleep(100); + + assert_int_equal(nx_azure_iot_hub_client_writable_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + /* Receive proxy manifest. */ + g_adu_agent_http_data_type = HTTP_DATA_TYPE_PROXY_MANIFEST; + nx_cloud_module_event_set(&(adu_agent.nx_azure_iot_adu_agent_cloud_module), NX_AZURE_IOT_ADU_AGENT_HTTP_RECEIVE_EVENT); + tx_thread_sleep(100); + + /* Receive proxy firmware. */ + g_adu_agent_http_data_type = HTTP_DATA_TYPE_FIRMWARE; + nx_cloud_module_event_set(&(adu_agent.nx_azure_iot_adu_agent_cloud_module), NX_AZURE_IOT_ADU_AGENT_HTTP_RECEIVE_EVENT); + tx_thread_sleep(100); + + /* Receive firmware. */ + g_adu_agent_http_data_type = HTTP_DATA_TYPE_FIRMWARE; + nx_cloud_module_event_set(&(adu_agent.nx_azure_iot_adu_agent_cloud_module), NX_AZURE_IOT_ADU_AGENT_HTTP_RECEIVE_EVENT); + tx_thread_sleep(100); + + /* Stop ADU agent. */ + assert_int_equal(nx_azure_iot_adu_agent_stop(&adu_agent), + NX_AZURE_IOT_SUCCESS); + + g_expected_message = NX_NULL; +} +#endif /* (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1) */ + +/** + * Test notify. + * + **/ +static VOID test_nx_azure_iot_adu_agent_notify() +{ +NX_AZURE_IOT_JSON_WRITER writer; +UINT request_id; +UINT response_status; +ULONG version; +NX_PACKET *packet_ptr; + + printf("test starts =>: %s\n", __func__); + + /* Restart ADU agent. */ + reported_property_success_topic_count += 2; + generate_test_property_send_response_bytes = NX_TRUE; + g_update_received_count = 0; + + assert_int_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + adu_agent.nx_azure_iot_adu_agent_crypto.method_rsa_metadata = g_adu_metadata; + adu_agent.nx_azure_iot_adu_agent_crypto.method_rsa_metadata_size = sizeof(g_adu_metadata); + + g_adu_agent_new_udpate = g_adu_agent_new_udpate_1; + g_adu_agent_new_udpate_size = sizeof(g_adu_agent_new_udpate_1); + generate_test_property_new_update_send(&iothub_client); + + tx_thread_sleep(100); + + /* New update check. */ + assert_int_equal(g_update_received_count, 1); + + assert_int_equal(nx_azure_iot_hub_client_writable_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + /* Stop ADU agent. */ + assert_int_equal(nx_azure_iot_adu_agent_stop(&adu_agent), + NX_AZURE_IOT_SUCCESS); + + /* Restart ADU agent with same installed criteria. */ + reported_property_success_topic_count += 6; + generate_test_property_send_response_bytes = NX_TRUE; + + assert_int_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA_NEW, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA_NEW) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + adu_agent.nx_azure_iot_adu_agent_crypto.method_rsa_metadata = g_adu_metadata; + adu_agent.nx_azure_iot_adu_agent_crypto.method_rsa_metadata_size = sizeof(g_adu_metadata); + + reported_property_success_topic_count += 4; + + generate_test_property_new_update_send(&iothub_client); + + tx_thread_sleep(100); + + /* Same update check. */ + assert_int_equal(g_update_received_count, 1); + + assert_int_equal(nx_azure_iot_hub_client_writable_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + /* Stop ADU agent. */ + assert_int_equal(nx_azure_iot_adu_agent_stop(&adu_agent), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test update cancel. + * + **/ +static VOID test_nx_azure_iot_adu_agent_update_cancel() +{ +NX_AZURE_IOT_JSON_WRITER writer; +UINT request_id; +UINT response_status; +ULONG version; +NX_PACKET *packet_ptr; + + printf("test starts =>: %s\n", __func__); + + reported_property_success_topic_count += 2; + generate_test_property_send_response_bytes = NX_TRUE; + + assert_int_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + /* Set the expected message and check the second mesage. */ + g_expected_message = g_adu_agent_cancel_response; + g_expected_message_index++; + + reported_property_success_topic_count += 4; + + generate_test_property_cancel_update_send(&iothub_client); + + tx_thread_sleep(100); + + /* Reset. */ + g_expected_message = NX_NULL; + + assert_int_equal(nx_azure_iot_hub_client_writable_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + /* Stop ADU agent. */ + assert_int_equal(nx_azure_iot_adu_agent_stop(&adu_agent), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test install success. + * + **/ +static VOID test_nx_azure_iot_adu_agent_install() +{ +NX_AZURE_IOT_JSON_WRITER writer; +UINT request_id; +UINT response_status; +ULONG version; +NX_PACKET *packet_ptr; + + printf("test starts =>: %s\n", __func__); + + /* Restart ADU agent. */ + g_update_received_count = 0; + g_update_applied_count = 0; + reported_property_success_topic_count += 2; + generate_test_property_send_response_bytes = NX_TRUE; + handle_agent_update_received_notify = NX_TRUE; + + assert_int_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_SUCCESS); + + adu_agent.nx_azure_iot_adu_agent_crypto.method_rsa_metadata = g_adu_metadata; + adu_agent.nx_azure_iot_adu_agent_crypto.method_rsa_metadata_size = sizeof(g_adu_metadata); + + g_adu_agent_new_udpate = g_adu_agent_new_udpate_2; + g_adu_agent_new_udpate_size = sizeof(g_adu_agent_new_udpate_2); + generate_test_property_new_update_send(&iothub_client); + + tx_thread_sleep(100); + + /* New update check. */ + assert_int_equal(g_update_received_count, 1); + + assert_int_equal(nx_azure_iot_hub_client_writable_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + g_adu_agent_http_data_type = 0; + + nx_cloud_module_event_set(&(adu_agent.nx_azure_iot_adu_agent_cloud_module), NX_AZURE_IOT_ADU_AGENT_HTTP_RECEIVE_EVENT); + tx_thread_sleep(100); + + assert_int_equal(g_update_applied_count, 1); + + /* Stop ADU agent. */ + assert_int_equal(nx_azure_iot_adu_agent_stop(&adu_agent), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test adu agent start failure as pnp is not enabled. + * + **/ +static VOID test_nx_azure_iot_adu_agent_start_fail_with_no_pnp() +{ + + printf("test starts =>: %s\n", __func__); + + /* Clear model id. */ + iothub_client.iot_hub_client_core._internal.options.model_id = AZ_SPAN_EMPTY; + + assert_int_equal(nx_azure_iot_adu_agent_start(&adu_agent, + &iothub_client, + (const UCHAR *)SAMPLE_DEVICE_MANUFACTURER, sizeof(SAMPLE_DEVICE_MANUFACTURER) - 1, + (const UCHAR *)SAMPLE_DEVICE_MODEL, sizeof(SAMPLE_DEVICE_MODEL) - 1, + (const UCHAR *)SAMPLE_DEVICE_INSTALLED_CRITERIA, sizeof(SAMPLE_DEVICE_INSTALLED_CRITERIA) - 1, + adu_agent_update_notify, + nx_azure_iot_adu_agent_driver), + NX_AZURE_IOT_NOT_ENABLED); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&iothub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); +} + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ + NX_AZURE_TEST_FN tests[] = {test_nx_azure_iot_adu_agent_invalid_argument_fail, + test_nx_azure_iot_adu_agent_start_success, + test_nx_azure_iot_adu_agent_update_start_fail, + test_nx_azure_iot_adu_agent_stop_success, +#if (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1) + test_nx_azure_iot_adu_agent_proxy_add, + test_nx_azure_iot_adu_agent_step_result, + test_nx_azure_iot_adu_agent_null_file_url, +#endif /* (NX_AZURE_IOT_ADU_AGENT_PROXY_UPDATE_COUNT >= 1) */ + test_nx_azure_iot_adu_agent_notify, + test_nx_azure_iot_adu_agent_update_cancel, + test_nx_azure_iot_adu_agent_install, + test_nx_azure_iot_adu_agent_start_fail_with_no_pnp + }; + INT number_of_tests = sizeof(tests)/sizeof(tests[0]); + g_ip_ptr = ip_ptr; + g_pool_ptr = pool_ptr; + g_dns_ptr = dns_ptr; + + test_suit_begin(); + + printf("Number of tests %d\r\n", number_of_tests); + for (INT index = 0; index < number_of_tests; index++) + { + test_begin(); + tests[index](); + test_end(); + } + + test_suit_end(); +} diff --git a/test/regression/azure_iot/nx_azure_iot_json_reader_unit_test.c b/test/regression/azure_iot/nx_azure_iot_json_reader_unit_test.c new file mode 100644 index 00000000..d6ae7de3 --- /dev/null +++ b/test/regression/azure_iot/nx_azure_iot_json_reader_unit_test.c @@ -0,0 +1,467 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot.h" +#include "nx_azure_iot_ciphersuites.h" +#include "nx_azure_iot_json_reader.h" + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +typedef VOID (*NX_AZURE_TEST_FN)(); + +static NX_IP *g_ip_ptr; +static NX_PACKET_POOL *g_pool_ptr; +static NX_DNS *g_dns_ptr; +static ULONG g_available_packet; + +static const CHAR test_sample_json[] = "{\ +\"uint_id\":1,\ +\"int_value\":-56,\ +\"double_value\":1234,\ +\"bool_value1\":true,\ +\"bool_value2\":false,\ +\"description\":\"Unit test sample json\",\ +\"list_value\":[1,1,\"unit test\",null],\ +\"object_value\":{\"test\":true},\ +\"json_value\":{\"test2\":true}\ +}"; + +static UINT generate_test_sample_json(NX_PACKET *packet_ptr, UINT number_of_obj) +{ +UINT status; + + if (number_of_obj > 1) + { + if ((status = nx_packet_data_append(packet_ptr, STRING_UNSIGNED_ARGS("["), + packet_ptr -> nx_packet_pool_owner, NX_WAIT_FOREVER))) + { + return(status); + } + } + + + for (UINT index = 0; index < number_of_obj; index++) + { + if (index != 0) + { + if ((status = nx_packet_data_append(packet_ptr, STRING_UNSIGNED_ARGS(","), + packet_ptr -> nx_packet_pool_owner, NX_WAIT_FOREVER))) + { + return(status); + } + } + + if ((status = nx_packet_data_append(packet_ptr, STRING_UNSIGNED_ARGS(test_sample_json), + packet_ptr -> nx_packet_pool_owner, NX_WAIT_FOREVER))) + { + return(status); + } + } + + if (number_of_obj > 1) + { + if ((status = nx_packet_data_append(packet_ptr, STRING_UNSIGNED_ARGS("]"), + packet_ptr -> nx_packet_pool_owner, NX_WAIT_FOREVER))) + { + return(status); + } + } + + return(NX_AZURE_IOT_SUCCESS); +} + +static UINT read_test_sample_json(NX_AZURE_IOT_JSON_READER *reader_ptr, UINT number_of_obj) +{ +UINT status; +uint32_t uint_value; +int32_t int_value; +UINT bool_value; +double double_value; +UCHAR str_value[100]; +UINT bytes_copied; + + if (number_of_obj > 1) + { + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_type(reader_ptr) != NX_AZURE_IOT_READER_TOKEN_BEGIN_ARRAY) + { + return(NX_AZURE_IOT_FAILURE); + } + } + + + for (UINT index = 0; index < number_of_obj; index++) + { + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_type(reader_ptr) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT) + { + return(NX_AZURE_IOT_FAILURE); + } + + /* uint_id = 1 */ + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + !nx_azure_iot_json_reader_token_is_text_equal(reader_ptr, STRING_UNSIGNED_ARGS("uint_id")) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_uint32_get(reader_ptr, &uint_value) || + uint_value != 1) + { + return(NX_AZURE_IOT_FAILURE); + } + + /* int_value = 1 */ + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + !nx_azure_iot_json_reader_token_is_text_equal(reader_ptr, STRING_UNSIGNED_ARGS("int_value")) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_int32_get(reader_ptr, &int_value) || + int_value != -56) + { + return(NX_AZURE_IOT_FAILURE); + } + + /* double_value = 1234 */ + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + !nx_azure_iot_json_reader_token_is_text_equal(reader_ptr, STRING_UNSIGNED_ARGS("double_value")) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_double_get(reader_ptr, &double_value) || + double_value != 1234.0) + { + return(NX_AZURE_IOT_FAILURE); + } + + /* bool_value1 = true */ + bool_value = 0x11111111; + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + !nx_azure_iot_json_reader_token_is_text_equal(reader_ptr, STRING_UNSIGNED_ARGS("bool_value1")) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_bool_get(reader_ptr, &bool_value) || + (bool_value != NX_TRUE)) + { + return(NX_AZURE_IOT_FAILURE); + } + + /* bool_value2 = false */ + bool_value = 0x11111111; + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + !nx_azure_iot_json_reader_token_is_text_equal(reader_ptr, STRING_UNSIGNED_ARGS("bool_value2")) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_bool_get(reader_ptr, &bool_value) || + (bool_value != NX_FALSE)) + { + return(NX_AZURE_IOT_FAILURE); + } + + /* description = Unit test sample json */ + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + !nx_azure_iot_json_reader_token_is_text_equal(reader_ptr, STRING_UNSIGNED_ARGS("description")) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_string_get(reader_ptr, str_value, + sizeof(str_value), &bytes_copied) || + memcmp(str_value, STRING_UNSIGNED_ARGS("Unit test sample json") != 0)) + { + return(NX_AZURE_IOT_FAILURE); + } + + /* list_value = [1,1,\"unit test\",null] */ + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + !nx_azure_iot_json_reader_token_is_text_equal(reader_ptr, STRING_UNSIGNED_ARGS("list_value")) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_type(reader_ptr) != NX_AZURE_IOT_READER_TOKEN_BEGIN_ARRAY) + { + return(NX_AZURE_IOT_FAILURE); + } + + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_int32_get(reader_ptr, &int_value) || + int_value != 1 || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_next_token(reader_ptr)) + { + return(NX_AZURE_IOT_FAILURE); + } + + /* object_value:{"test":true} */ + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + !nx_azure_iot_json_reader_token_is_text_equal(reader_ptr, STRING_UNSIGNED_ARGS("object_value")) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_type(reader_ptr) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT || + nx_azure_iot_json_reader_skip_children(reader_ptr)) + { + return(NX_AZURE_IOT_FAILURE); + } + + /* object_value:{"test2":true} */ + bool_value = 0x11111111; + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + !nx_azure_iot_json_reader_token_is_text_equal(reader_ptr, STRING_UNSIGNED_ARGS("json_value")) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_type(reader_ptr) != NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT || + nx_azure_iot_json_reader_next_token(reader_ptr) || + !nx_azure_iot_json_reader_token_is_text_equal(reader_ptr, STRING_UNSIGNED_ARGS("test2")) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_bool_get(reader_ptr, &bool_value) || + (bool_value != NX_TRUE) || + nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_type(reader_ptr) != NX_AZURE_IOT_READER_TOKEN_END_OBJECT) + { + return(NX_AZURE_IOT_FAILURE); + } + + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_type(reader_ptr) != NX_AZURE_IOT_READER_TOKEN_END_OBJECT) + { + return(NX_AZURE_IOT_FAILURE); + } + } + + if (number_of_obj > 1) + { + if (nx_azure_iot_json_reader_next_token(reader_ptr) || + nx_azure_iot_json_reader_token_type(reader_ptr) != NX_AZURE_IOT_READER_TOKEN_END_ARRAY) + { + return(NX_AZURE_IOT_FAILURE); + } + } + + return(NX_AZURE_IOT_SUCCESS); +} + +/* Hook executed before every test */ +static VOID test_begin() +{ + /* Record number of available packet before test */ + g_available_packet = g_pool_ptr -> nx_packet_pool_available; +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_end() +{ + + /* Check if all the packet are released */ + assert_int_equal(g_pool_ptr -> nx_packet_pool_available, g_available_packet); +} + +/** + * Test json reader INVALID argument + * + **/ +static VOID test_nx_azure_iot_json_reader_invalid_argument_fail() +{ +NX_AZURE_IOT_JSON_READER reader; + + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_json_reader_with_buffer_init(NX_NULL, + NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_json_reader_with_buffer_init(&reader, + NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_reader_init(NX_NULL, NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_reader_init(&reader, NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_reader_deinit(NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_reader_next_token(NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_reader_skip_children(NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_reader_token_bool_get(NX_NULL, NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_reader_token_uint32_get(NX_NULL, NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_reader_token_int32_get(NX_NULL, NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_reader_token_double_get(NX_NULL, NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_reader_token_string_get(NX_NULL, + NX_NULL, 0, + NX_NULL), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_json_reader_token_is_text_equal(NX_NULL, NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_json_reader_token_type(NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test json reader empty payload + * + **/ +static VOID test_nx_azure_iot_json_reader_empty_fail() +{ +NX_AZURE_IOT_JSON_READER reader; +NX_PACKET *packet_ptr; + + printf("test starts =>: %s\n", __func__); + + assert_int_equal(nx_azure_iot_json_reader_with_buffer_init(&reader, + test_sample_json, + 0), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_json_reader_next_token(&reader), NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_deinit(&reader), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_allocate(g_pool_ptr, + &packet_ptr, 0, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, + packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_json_reader_next_token(&reader), NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_deinit(&reader), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test json reader static buffer + * + **/ +static VOID test_nx_azure_iot_json_reader_success() +{ +NX_AZURE_IOT_JSON_READER reader; + + printf("test starts =>: %s\n", __func__); + + assert_int_equal(nx_azure_iot_json_reader_with_buffer_init(&reader, + test_sample_json, + sizeof(test_sample_json) - 1), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(read_test_sample_json(&reader, 1), NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_json_reader_next_token(&reader), NX_AZURE_IOT_NOT_FOUND); + + assert_int_equal(nx_azure_iot_json_reader_deinit(&reader), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test json reader with nx_packet + * + **/ +static VOID test_nx_azure_iot_json_reader_with_nx_packet_success() +{ +NX_AZURE_IOT_JSON_READER reader; +NX_PACKET *packet_ptr; +UINT number_of_obj = ((g_pool_ptr -> nx_packet_pool_payload_size * NX_AZURE_IOT_READER_MAX_LIST) / + (sizeof(test_sample_json) - 1)) - 1; + + printf("test starts =>: %s\n", __func__); + + assert_int_equal(nx_packet_allocate(g_pool_ptr, + &packet_ptr, 0, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_sample_json(packet_ptr, number_of_obj), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, + packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(read_test_sample_json(&reader, number_of_obj), NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_json_reader_next_token(&reader), NX_AZURE_IOT_NOT_FOUND); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_deinit(&reader), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test json reader with OOM + * + **/ +static VOID test_nx_azure_iot_json_reader_with_oom_fail() +{ +NX_AZURE_IOT_JSON_READER reader; +NX_PACKET *packet_ptr; +UINT number_of_obj = ((g_pool_ptr -> nx_packet_pool_payload_size * NX_AZURE_IOT_READER_MAX_LIST) / + (sizeof(test_sample_json) - 1)) + 1; + + printf("test starts =>: %s\n", __func__); + + assert_int_equal(nx_packet_allocate(g_pool_ptr, + &packet_ptr, 0, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_sample_json(packet_ptr, number_of_obj), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_json_reader_init(&reader, + packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_deinit(&reader), + NX_AZURE_IOT_SUCCESS); +} + +VOID demo_entry(NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr, NX_DNS *dns_ptr, + UINT (*unix_time_callback)(ULONG *unix_time)) +{ +NX_AZURE_TEST_FN tests[] = { test_nx_azure_iot_json_reader_invalid_argument_fail, + test_nx_azure_iot_json_reader_empty_fail, + test_nx_azure_iot_json_reader_success, + test_nx_azure_iot_json_reader_with_nx_packet_success, + test_nx_azure_iot_json_reader_with_oom_fail }; +INT number_of_tests = sizeof(tests)/sizeof(tests[0]); + + printf("Number of tests %d\r\n", number_of_tests); + + g_ip_ptr = ip_ptr; + g_pool_ptr = pool_ptr; + g_dns_ptr = dns_ptr; + + for (INT index = 0; index < number_of_tests; index++) + { + test_begin(); + tests[index](); + test_end(); + } +} diff --git a/test/regression/azure_iot/nx_azure_iot_json_writer_unit_test.c b/test/regression/azure_iot/nx_azure_iot_json_writer_unit_test.c new file mode 100644 index 00000000..e56783e1 --- /dev/null +++ b/test/regression/azure_iot/nx_azure_iot_json_writer_unit_test.c @@ -0,0 +1,455 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot.h" +#include "nx_azure_iot_ciphersuites.h" +#include "nx_azure_iot_json_writer.h" + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + +#ifndef MAX_BUFFER_SIZE +#define MAX_BUFFER_SIZE 1500 * 11 +#endif /* MAX_BUFFER_SIZE */ + +#define DOUBLE_DECIMAL_PLACE_DIGITS 2 +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +typedef VOID (*NX_AZURE_TEST_FN)(); + +static const CHAR test_sample_json[] = "{\ +\"id\":1,\ +\"value\":1234,\ +\"description\":\"Unit test sample json\",\ +\"list_value\":[1,1,\"unit test\",null],\ +\"object_value\":{\"test\":true},\ +\"json_value\":{\"test2\":true}\ +}"; + +static NX_IP *g_ip_ptr; +static NX_PACKET_POOL *g_pool_ptr; +static NX_DNS *g_dns_ptr; +static ULONG g_available_packet; +static UCHAR g_scratch_buffer[MAX_BUFFER_SIZE]; + +static UINT generate_test_sample_json(NX_AZURE_IOT_JSON_WRITER *writer_ptr, UINT number_of_obj) +{ +UINT status; + + if ((status = nx_azure_iot_json_writer_append_begin_array(writer_ptr))) + { + return(status); + } + + for (UINT index = 0; index < number_of_obj; index++) + { + if ((status = nx_azure_iot_json_writer_append_begin_object(writer_ptr))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_property_with_int32_value(writer_ptr, + STRING_UNSIGNED_ARGS("id"), 1))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_property_with_double_value(writer_ptr, + STRING_UNSIGNED_ARGS("value"), + 1234.0, DOUBLE_DECIMAL_PLACE_DIGITS))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_property_with_string_value(writer_ptr, + STRING_UNSIGNED_ARGS("description"), + STRING_UNSIGNED_ARGS("Unit test sample json")))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_property_name(writer_ptr, STRING_UNSIGNED_ARGS("list_value")))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_begin_array(writer_ptr))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_int32(writer_ptr, 1))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_double(writer_ptr, 1.0, DOUBLE_DECIMAL_PLACE_DIGITS))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_string(writer_ptr, STRING_UNSIGNED_ARGS("unit test")))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_null(writer_ptr))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_end_array(writer_ptr))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_property_name(writer_ptr, STRING_UNSIGNED_ARGS("object_value")))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_begin_object(writer_ptr))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_property_with_bool_value(writer_ptr, STRING_UNSIGNED_ARGS("test"), 1))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_end_object(writer_ptr))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_property_name(writer_ptr, STRING_UNSIGNED_ARGS("json_value")))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_json_text(writer_ptr, STRING_UNSIGNED_ARGS("{\"test2\":true}")))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_end_object(writer_ptr))) + { + return(status); + } + } + + if ((status = nx_azure_iot_json_writer_append_end_array(writer_ptr))) + { + return(status); + } + + return(NX_AZURE_IOT_SUCCESS); +} + +static UINT copy_nx_packet_json_to_buffer(NX_AZURE_IOT_JSON_WRITER *writer_ptr, ULONG offset, + UCHAR *buffer, UINT buffer_size, ULONG *bytes_copied) +{ +NX_PACKET *packet_ptr = writer_ptr -> packet_ptr; +UINT status; + + *bytes_copied = 0; + if (packet_ptr == NX_NULL) + { + return(NX_AZURE_IOT_SUCCESS); + } + + if ((status = nx_packet_data_extract_offset(packet_ptr, offset, buffer, + buffer_size, bytes_copied))) + { + return(status); + } + + return(NX_AZURE_IOT_SUCCESS); +} + +/* Hook executed before every test */ +static VOID test_begin() +{ + memset(g_scratch_buffer, 0, sizeof(g_scratch_buffer)); + + /* Record number of available packet before test */ + g_available_packet = g_pool_ptr -> nx_packet_pool_available; +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_end() +{ + + /* Check if all the packet are released */ + assert_int_equal(g_pool_ptr -> nx_packet_pool_available, g_available_packet); +} + +/** + * Test json writer INVALID argument + * + **/ +static VOID test_nx_azure_iot_json_writer_invalid_argument_fail() +{ + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_json_writer_init(NX_NULL, + NX_NULL, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_with_buffer_init(NX_NULL, + NX_NULL, + 0), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_deinit(NX_NULL), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_property_with_int32_value(NX_NULL, + STRING_UNSIGNED_ARGS("fake"), + 1), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_property_with_double_value(NX_NULL, + STRING_UNSIGNED_ARGS("fake"), + 1, DOUBLE_DECIMAL_PLACE_DIGITS), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_property_with_bool_value(NX_NULL, + STRING_UNSIGNED_ARGS("fake"), + 1), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_property_with_string_value(NX_NULL, + STRING_UNSIGNED_ARGS("fake"), + STRING_UNSIGNED_ARGS("fake_value")), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_json_writer_get_bytes_used(NX_NULL), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_json_writer_append_string(NX_NULL, + STRING_UNSIGNED_ARGS("fake_value")), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_json_text(NX_NULL, + STRING_UNSIGNED_ARGS("fake_value")), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_property_name(NX_NULL, + STRING_UNSIGNED_ARGS("fake_value")), + NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_bool(NX_NULL, 1), NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_int32(NX_NULL, 1), NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_double(NX_NULL, + 1, DOUBLE_DECIMAL_PLACE_DIGITS), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_json_writer_append_null(NX_NULL), NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_begin_object(NX_NULL), NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_begin_array(NX_NULL), NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_end_object(NX_NULL), NX_AZURE_IOT_SUCCESS); + assert_int_not_equal(nx_azure_iot_json_writer_append_end_array(NX_NULL), NX_AZURE_IOT_SUCCESS); +} + +/** + * Test json writer static buffer + * + **/ +static VOID test_nx_azure_iot_json_writer_success() +{ +NX_AZURE_IOT_JSON_WRITER writer; + + printf("test starts =>: %s\n", __func__); + + assert_int_equal(nx_azure_iot_json_writer_with_buffer_init(&writer, + g_scratch_buffer, + sizeof(g_scratch_buffer)), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_sample_json(&writer, 1), NX_AZURE_IOT_SUCCESS); + + assert_memory_equal(g_scratch_buffer + 1, test_sample_json, sizeof(test_sample_json) - 1); + + assert_int_equal(nx_azure_iot_json_writer_deinit(&writer), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test json writer with nx_packet + * + **/ +static VOID test_nx_azure_iot_json_writer_with_nx_packet_success() +{ +NX_AZURE_IOT_JSON_WRITER writer; +NX_PACKET *packet_ptr; +ULONG bytes_copied; +UCHAR *start_ptr; + + printf("test starts =>: %s\n", __func__); + + for (INT number_of_obj = 1; number_of_obj <= 100; number_of_obj++) + { + assert_int_equal(nx_packet_allocate(g_pool_ptr, + &packet_ptr, 0, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_writer_init(&writer, + packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_sample_json(&writer, number_of_obj), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(copy_nx_packet_json_to_buffer(&writer, 0, + g_scratch_buffer, + sizeof(g_scratch_buffer), + &bytes_copied), + NX_AZURE_IOT_SUCCESS); + + start_ptr = g_scratch_buffer + 1; + for (INT index = 0; index < number_of_obj; index++) + { + assert_memory_equal(start_ptr, + test_sample_json, (sizeof(test_sample_json) - 1)); + start_ptr += sizeof(test_sample_json); + } + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_writer_deinit(&writer), + NX_AZURE_IOT_SUCCESS); + } +} + +/** + * Test json writer when reached out of memory + * + **/ +static VOID test_nx_azure_iot_json_writer_with_nx_packet_oom_fail() +{ +NX_AZURE_IOT_JSON_WRITER writer; +NX_PACKET *packet_ptr; +UINT number_of_obj = (g_pool_ptr -> nx_packet_pool_size / (sizeof(test_sample_json) - 1)) + 1; + + printf("test starts =>: %s\n", __func__); + + assert_int_equal(nx_packet_allocate(g_pool_ptr, + &packet_ptr, 0, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_writer_init(&writer, + packet_ptr, + NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(generate_test_sample_json(&writer, number_of_obj), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_writer_deinit(&writer), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test json writer with offset nx_packet + * + **/ +static VOID test_nx_azure_iot_json_writer_with_nx_packet_offset_success() +{ +NX_AZURE_IOT_JSON_WRITER writer; +NX_PACKET *packet_ptr; +ULONG bytes_copied; +UCHAR *start_ptr; +UINT number_of_obj = 60; + + printf("test starts =>: %s\n", __func__); + + for (INT offset = 1; offset <= (2 * g_pool_ptr -> nx_packet_pool_payload_size); offset++) + { + assert_int_equal(nx_packet_allocate(g_pool_ptr, + &packet_ptr, 0, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + /* append data till offset */ + assert_int_equal(nx_packet_data_append(packet_ptr, + g_scratch_buffer, + offset, g_pool_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_writer_init(&writer, + packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_sample_json(&writer, number_of_obj), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(copy_nx_packet_json_to_buffer(&writer, offset, + g_scratch_buffer, + sizeof(g_scratch_buffer), + &bytes_copied), + NX_AZURE_IOT_SUCCESS); + + start_ptr = g_scratch_buffer + 1; + for (INT index = 0; index < number_of_obj; index++) + { + assert_memory_equal(start_ptr, + test_sample_json, (sizeof(test_sample_json) - 1)); + start_ptr += sizeof(test_sample_json); + } + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_writer_deinit(&writer), + NX_AZURE_IOT_SUCCESS); + } +} + +VOID demo_entry(NX_IP *ip_ptr, NX_PACKET_POOL *pool_ptr, NX_DNS *dns_ptr, + UINT (*unix_time_callback)(ULONG *unix_time)) +{ +NX_AZURE_TEST_FN tests[] = { test_nx_azure_iot_json_writer_invalid_argument_fail, + test_nx_azure_iot_json_writer_success, + test_nx_azure_iot_json_writer_with_nx_packet_success, + test_nx_azure_iot_json_writer_with_nx_packet_oom_fail, + test_nx_azure_iot_json_writer_with_nx_packet_offset_success }; +INT number_of_tests = sizeof(tests)/sizeof(tests[0]); + + printf("Number of tests %d\r\n", number_of_tests); + + g_ip_ptr = ip_ptr; + g_pool_ptr = pool_ptr; + g_dns_ptr = dns_ptr; + + for (INT index = 0; index < number_of_tests; index++) + { + test_begin(); + tests[index](); + test_end(); + } +} diff --git a/test/regression/azure_iot/nx_azure_iot_pnp_client_command_unit_test.c b/test/regression/azure_iot/nx_azure_iot_pnp_client_command_unit_test.c new file mode 100644 index 00000000..e053749b --- /dev/null +++ b/test/regression/azure_iot/nx_azure_iot_pnp_client_command_unit_test.c @@ -0,0 +1,856 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "azure/core/az_span.h" +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +#ifndef MAXIMUM_PAYLOAD_LENGTH +#define MAXIMUM_PAYLOAD_LENGTH 10240 +#endif /* MAXIMUM_PAYLOAD_LENGTH */ + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, sizeof(s) - 1 + +#define MQTT_CLIENT_GET(c) ((c) -> nx_azure_iot_hub_client_resource.resource_mqtt) +#define TX_MUTEX_GET(c) ((c) -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr) + +typedef VOID (*NX_AZURE_TEST_FN)(); + +static ULONG network_bytes_generate_stack[DEMO_HELPER_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD network_bytes_generate_thread; + +static const UCHAR g_hostname[] = "unit-test.iot-azure.com"; +static const UCHAR g_device_id[] = "unit_test_device"; +static const UCHAR g_pnp_model_id[] = "pnp_model_id_unit_test"; +static const UCHAR g_symmetric_key[] = "6CLK6It9jOiABpFVu11CQDv9O49ebAneK3KbsvaoU1o="; +static const UCHAR g_test_component[] = "sample_test"; + +static const CHAR command_with_component_topic[] = "$iothub/methods/POST/sample_test*test_method/?$rid=1"; +static const CHAR command_topic[] = "$iothub/methods/POST/test_method/?$rid=1"; +static const CHAR test_command_payload[] = "{\"method\" : \"test_method\", \"parameter\": 1}"; +static const CHAR test_command_name[] = "test_method"; +static const CHAR test_request_id[] = "1"; +static const CHAR test_send_payload[] = "{\"return\" : \"OK\"}"; + +static UINT g_total_append = 0; +static UINT g_failed_append_index = 0; +static UINT g_total_allocation = 0; +static UINT g_failed_allocation_index = -1; +static NX_IP* g_ip_ptr; +static NX_PACKET_POOL* g_pool_ptr; +static NX_DNS* g_dns_ptr; +static ULONG g_available_packet; +static CHAR *g_expected_message; +static UINT g_generate_command_bytes = NX_FALSE; +static UINT g_generate_command_with_component_bytes = NX_FALSE; +static UINT g_generate_disconnect = NX_FALSE; + +extern UINT _nxd_mqtt_client_append_message(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, CHAR *message, + UINT length, ULONG wait_option); +extern UINT _nxd_mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + UCHAR control_header, UINT length, UINT wait_option); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iothub_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +static UCHAR message_payload[MAXIMUM_PAYLOAD_LENGTH]; +static UCHAR result_buffer[MAXIMUM_PAYLOAD_LENGTH]; +static VOID (*test_receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count) = NX_NULL; + +UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr, + VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count)) +{ + printf("HIJACKED: %s\n", __func__); + test_receive_notify = receive_notify; + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_subscribe(NXD_MQTT_CLIENT *client_ptr, UINT op, + CHAR *topic_name, UINT topic_name_length, + USHORT *packet_id_ptr, UINT QoS) +{ + printf("HIJACKED: %s\n", __func__); + + return((UINT)mock()); +} + +UINT __real__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option); +UINT __wrap__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_append_index == g_total_append) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_append++; + return __real__nx_packet_data_append(packet_ptr, data_start, data_size, pool_ptr, wait_option); +} + +UINT __real_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context); +UINT __wrap_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_allocation_index == g_total_allocation) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_allocation++; + return __real_nx_azure_iot_buffer_allocate(nx_azure_iot_ptr, buffer_pptr, buffer_size, buffer_context); +} + +UINT __wrap__nxd_mqtt_client_publish_packet_send(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + USHORT packet_id, UINT QoS, ULONG wait_option) +{ +UINT topic_name_length; +UINT message_length; +UCHAR *buffer_ptr; +UINT status = (UINT)mock(); + + printf("HIJACKED: %s\n", __func__); + tx_mutex_put(client_ptr -> nxd_mqtt_client_mutex_ptr); + + if (status) + { + return(status); + } + + buffer_ptr = packet_ptr -> nx_packet_prepend_ptr; + topic_name_length = (buffer_ptr[5] << 8) | (buffer_ptr[6]); + message_length = packet_ptr -> nx_packet_length - (7 + topic_name_length); + assert_memory_equal(&buffer_ptr[7 + topic_name_length], g_expected_message, message_length); + assert_int_equal(QoS, 0); + + /* packet ownership taken and released */ + nx_packet_release(packet_ptr); + + return(status); +} + +UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, + UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *, + NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *), + UINT keepalive, UINT clean_session, ULONG wait_option) +{ +az_span source = az_span_create(client_ptr -> nxd_mqtt_client_username, + (INT)client_ptr -> nxd_mqtt_client_username_length); +az_span target = az_span_create((UCHAR *)g_pnp_model_id, sizeof(g_pnp_model_id) - 1); + + printf("HIJACKED: %s\n", __func__); + + /* Check username and client Id to contain modelId and device */ + assert_memory_equal(client_ptr -> nxd_mqtt_client_id, g_device_id, sizeof(g_device_id) - 1); + assert_int_not_equal(az_span_find(source, target), -1); + + tx_thread_suspend(&(iot.nx_azure_iot_ip_ptr -> nx_ip_thread)); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + client_ptr -> nxd_mqtt_client_packet_identifier = 1; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_FALSE; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &client_ptr -> nxd_mqtt_client_socket; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr) +{ + printf("HIJACKED: %s\n", __func__); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ + printf("HIJACKED: %s\n", __func__); + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NX_DNS_SUCCESS); +} + +static UINT mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, UCHAR control_header, UINT length, UINT wait_option) +{ +UCHAR fixed_header[5]; +UCHAR *byte = fixed_header; +UINT count = 0; +UINT ret; + + *byte = control_header; + byte++; + + do + { + if (length & 0xFFFFFF80) + { + *(byte + count) = (UCHAR)((length & 0x7F) | 0x80); + } + else + { + *(byte + count) = length & 0x7F; + } + length = length >> 7; + + count++; + } while (length != 0); + + ret = __real__nx_packet_data_append(packet_ptr, fixed_header, count + 1, + client_ptr -> nxd_mqtt_client_packet_pool_ptr, wait_option); + + return(ret); +} + + +static VOID construct_command_message(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, + const UCHAR *topic, ULONG topic_len, + const UCHAR *message_payload_ptr, ULONG message_payload_length, + NX_PACKET **packet_pptr) +{ +NX_PACKET *packet_ptr; +ULONG total_length; +ULONG topic_length = topic_len; +UCHAR bytes[2]; +UINT i; + + assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + total_length = topic_length + 2 + 2 + message_payload_length; /* Two bytes for fixed topic_length field + and two bytes for packet id. */ + + /* Set fixed header. */ + assert_int_equal(mqtt_client_set_fixed_header(&(MQTT_CLIENT_GET(iothub_client_ptr)), packet_ptr, + (UCHAR)((MQTT_CONTROL_PACKET_TYPE_PUBLISH << 4) | MQTT_PUBLISH_QOS_LEVEL_1), + total_length, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic length. */ + bytes[0] = (topic_length >> 8) & 0xFF; + bytes[1] = topic_length & 0xFF; + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)topic, topic_len, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + /* Set packet ID. The value does not matter. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set message payload. */ + if (message_payload_length > 0) + { + assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)message_payload_ptr, message_payload_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + + *packet_pptr = packet_ptr; +} + +static VOID generate_component_command_message(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr) +{ +NX_PACKET *packet_ptr; + + construct_command_message(iothub_client_ptr, command_with_component_topic, sizeof(command_with_component_topic) - 1, + test_command_payload, sizeof(test_command_payload) - 1, + &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(iothub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(iothub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(iothub_client_ptr)); +} + +static VOID generate_command_message(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr) +{ +NX_PACKET *packet_ptr; + + construct_command_message(iothub_client_ptr, command_topic, sizeof(command_topic) - 1, + test_command_payload, sizeof(test_command_payload) - 1, + &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(iothub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(iothub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(iothub_client_ptr)); +} + +static VOID on_receive_callback(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, VOID *arg) +{ + *((UINT *)arg) = 1; +} + +/* Generate network received bytes */ +static VOID network_bytes_generate_entry(ULONG args) +{ + while (NX_TRUE) + { + if (g_generate_command_bytes) + { + g_generate_command_bytes = NX_FALSE; + generate_command_message(&iothub_client); + } + else if (g_generate_command_with_component_bytes) + { + g_generate_command_with_component_bytes = NX_FALSE; + generate_component_command_message(&iothub_client); + } + else if (g_generate_disconnect) + { + g_generate_disconnect = NX_FALSE; + nx_azure_iot_hub_client_disconnect(&iothub_client); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } +} + +static VOID reset_global_state() +{ + /* reset global state */ + g_failed_append_index = (UINT)-1; + g_total_append = 0; + g_failed_allocation_index = (UINT)-1; + g_total_allocation = 0; + g_expected_message = NX_NULL; +} + +/* Hook execute before all tests. */ +static VOID test_suit_begin() +{ + assert_int_equal(tx_thread_create(&network_bytes_generate_thread, + "UintTestNetworkBytesGenerator", + network_bytes_generate_entry, 0, + network_bytes_generate_stack, + DEMO_HELPER_STACK_SIZE, + DEMO_HELPER_THREAD_PRIORITY + 1, + DEMO_HELPER_THREAD_PRIORITY + 1, + TX_NO_TIME_SLICE, TX_AUTO_START), + NX_AZURE_IOT_SUCCESS); + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, + (UCHAR *)_nx_azure_iot_root_cert, + (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", + g_ip_ptr, g_pool_ptr, g_dns_ptr, + (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), + DEMO_CLOUD_THREAD_PRIORITY, unix_time_get), + NX_AZURE_IOT_SUCCESS); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&iothub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&iothub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); + + /* Set symmetric key credentials */ + assert_int_equal(nx_azure_iot_hub_client_symmetric_key_set(&iothub_client, + g_symmetric_key, + sizeof(g_symmetric_key) - 1), + NX_AZURE_IOT_SUCCESS); + + will_return_always(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + + /* Connect IoTHub client */ + assert_int_equal(nx_azure_iot_hub_client_connect(&iothub_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + /* Enable command. */ + assert_int_equal(nx_azure_iot_hub_client_command_enable(&iothub_client), + NX_AZURE_IOT_SUCCESS); +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_suit_end() +{ + assert_int_equal(nx_azure_iot_hub_client_disconnect(&iothub_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iothub_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_delete(&iot), + NX_AZURE_IOT_SUCCESS); +} + +/* Hook executed before every test */ +static VOID test_begin() +{ + reset_global_state(); + + /* Record number of available packet before test */ + g_available_packet = g_pool_ptr -> nx_packet_pool_available; +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_end() +{ + /* Check if all the packet are released */ + assert_int_equal(g_pool_ptr -> nx_packet_pool_available, g_available_packet); +} + +/** + * Test invalid argument failure. + * + **/ +static VOID test_nx_azure_iot_hub_client_invalid_argument_fail() +{ +const UCHAR *component_name_ptr; +USHORT component_name_length; +const UCHAR *pnp_command_name_ptr; +USHORT pnp_command_name_length; +VOID *context_ptr; +USHORT context_length; +NX_PACKET *packet_ptr; + + printf("test starts =>: %s\n", __func__); + assert_int_not_equal(nx_azure_iot_hub_client_command_message_receive(NX_NULL, + &component_name_ptr, + &component_name_length, + &pnp_command_name_ptr, + &pnp_command_name_length, + &context_ptr, &context_length, + &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_command_message_receive(&iothub_client, + &component_name_ptr, + &component_name_length, + NX_NULL, NX_NULL, + &context_ptr, &context_length, + &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_command_message_receive(&iothub_client, + &component_name_ptr, + &component_name_length, + &pnp_command_name_ptr, + &pnp_command_name_length, + NX_NULL, NX_NULL, + &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_command_message_receive(&iothub_client, + &component_name_ptr, + &component_name_length, + &pnp_command_name_ptr, + &pnp_command_name_length, + &context_ptr, &context_length, + NX_NULL, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_command_message_response(NX_NULL, 200, + context_ptr, + context_length, + NX_NULL, 0, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_command_message_response(&iothub_client, 200, + NX_NULL, 0, + NX_NULL, 0, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful pnp command. + * + **/ +static VOID test_nx_azure_iot_hub_client_command_success() +{ +const UCHAR *component_name_ptr; +USHORT component_name_length; +const UCHAR *pnp_command_name_ptr; +USHORT pnp_command_name_length; +VOID *context_ptr; +USHORT context_length; +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + printf("test starts =>: %s\n", __func__); + + generate_command_message(&iothub_client); + + assert_int_equal(nx_azure_iot_hub_client_command_message_receive(&iothub_client, + &component_name_ptr, + &component_name_length, + &pnp_command_name_ptr, + &pnp_command_name_length, + &context_ptr, &context_length, + &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(component_name_ptr, NX_NULL); + assert_memory_equal(pnp_command_name_ptr, test_command_name, sizeof(test_command_name) - 1); + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_memory_equal(result_buffer, test_command_payload, sizeof(test_command_payload) - 1); + + assert_int_equal(nx_packet_release(packet_ptr), NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful component pnp command. + * + **/ +static VOID test_nx_azure_iot_hub_client_component_command_success() +{ +const UCHAR *component_name_ptr; +USHORT component_name_length; +const UCHAR *pnp_command_name_ptr; +USHORT pnp_command_name_length; +VOID *context_ptr; +USHORT context_length; +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + printf("test starts =>: %s\n", __func__); + + generate_component_command_message(&iothub_client); + + assert_int_equal(nx_azure_iot_hub_client_command_message_receive(&iothub_client, + &component_name_ptr, + &component_name_length, + &pnp_command_name_ptr, + &pnp_command_name_length, + &context_ptr, &context_length, + &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_memory_equal(component_name_ptr, g_test_component, component_name_length); + assert_memory_equal(pnp_command_name_ptr, test_command_name, pnp_command_name_length); + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_memory_equal(result_buffer, test_command_payload, sizeof(test_command_payload) - 1); + + assert_int_equal(nx_packet_release(packet_ptr), NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful component pnp command. + * + **/ +static VOID test_nx_azure_iot_hub_client_component_command_blocking_success() +{ +const UCHAR *component_name_ptr; +USHORT component_name_length; +const UCHAR *pnp_command_name_ptr; +USHORT pnp_command_name_length; +VOID *context_ptr; +USHORT context_length; +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + printf("test starts =>: %s\n", __func__); + + g_generate_command_with_component_bytes = NX_TRUE; + assert_int_equal(nx_azure_iot_hub_client_command_message_receive(&iothub_client, + &component_name_ptr, + &component_name_length, + &pnp_command_name_ptr, + &pnp_command_name_length, + &context_ptr, &context_length, + &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_memory_equal(component_name_ptr, g_test_component, component_name_length); + assert_memory_equal(pnp_command_name_ptr, test_command_name, pnp_command_name_length); + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_memory_equal(result_buffer, test_command_payload, sizeof(test_command_payload) - 1); + + assert_int_equal(nx_packet_release(packet_ptr), NX_AZURE_IOT_SUCCESS); +} + +/** + * Test command receive succeeds with NX_NO_WAIT. + * + **/ +static VOID test_nx_azure_iot_hub_client_command_message_receive_no_blocking_success() +{ +const UCHAR *component_name_ptr; +USHORT component_name_length; +const UCHAR *pnp_command_name_ptr; +USHORT pnp_command_name_length; +VOID *context_ptr; +USHORT context_length; +NX_PACKET *packet_ptr; +ULONG bytes_copied; +UINT received = 0; + + printf("test starts =>: %s\n", __func__); + + assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iothub_client, + NX_AZURE_IOT_HUB_COMMAND, + on_receive_callback, + (VOID *)&received), + NX_AZURE_IOT_SUCCESS); + generate_component_command_message(&iothub_client); + + while (!received) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + } + + assert_int_equal(nx_azure_iot_hub_client_command_message_receive(&iothub_client, + &component_name_ptr, + &component_name_length, + &pnp_command_name_ptr, + &pnp_command_name_length, + &context_ptr, &context_length, + &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + assert_memory_equal(component_name_ptr, g_test_component, component_name_length); + assert_memory_equal(pnp_command_name_ptr, test_command_name, pnp_command_name_length); + assert_int_equal(nx_packet_data_extract_offset(packet_ptr, 0, result_buffer, + sizeof(result_buffer), &bytes_copied), + NX_AZURE_IOT_SUCCESS); + assert_memory_equal(result_buffer, test_command_payload, sizeof(test_command_payload) - 1); + + assert_int_equal(nx_packet_release(packet_ptr), NX_AZURE_IOT_SUCCESS); +} + +/** + * Test fail pnp command receive on disconnect. + * + **/ +static VOID test_nx_azure_iot_hub_client_command_blocking_disconnect_fail() +{ +const UCHAR *component_name_ptr; +USHORT component_name_length; +const UCHAR *pnp_command_name_ptr; +USHORT pnp_command_name_length; +VOID *context_ptr; +USHORT context_length; +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + printf("test starts =>: %s\n", __func__); + + g_generate_disconnect = NX_TRUE; + assert_int_not_equal(nx_azure_iot_hub_client_command_message_receive(&iothub_client, + &component_name_ptr, + &component_name_length, + &pnp_command_name_ptr, + &pnp_command_name_length, + &context_ptr, &context_length, + &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + /* Reconnect IoTHub client */ + assert_int_equal(nx_azure_iot_hub_client_connect(&iothub_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test command response send fail. + * + **/ +static VOID test_nx_azure_iot_hub_client_command_response_send_fail() +{ + printf("test starts =>: %s\n", __func__); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_NOT_SUCCESSFUL); + + assert_int_not_equal(nx_azure_iot_hub_client_command_message_response(&iothub_client, + 200, (VOID *)test_request_id, + sizeof(test_request_id) - 1, + (UCHAR *)test_send_payload, + sizeof(test_send_payload) - 1, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test command response succeeds. + * + **/ +static VOID test_nx_azure_iot_hub_client_command_response_success() +{ + printf("test starts =>: %s\n", __func__); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + g_expected_message = (CHAR *)test_send_payload; + + assert_int_equal(nx_azure_iot_hub_client_command_message_response(&iothub_client, + 200, (VOID *)test_request_id, + sizeof(test_request_id) - 1, + (UCHAR *)test_send_payload, + sizeof(test_send_payload) - 1, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test command response empty json succeeds. + * + **/ +static VOID test_nx_azure_iot_hub_client_command_response_empty_success() +{ + printf("test starts =>: %s\n", __func__); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + g_expected_message = (CHAR *)"{}"; + + assert_int_equal(nx_azure_iot_hub_client_command_message_response(&iothub_client, + 200, (VOID *)test_request_id, + sizeof(test_request_id) - 1, + NX_NULL, 0, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test command response oom fail. + * + **/ +static VOID test_nx_azure_iot_hub_client_command_response_oom_fail() +{ +UINT round = 0; + + printf("test starts =>: %s\n", __func__); + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + g_expected_message = (CHAR *)test_send_payload; + + while (NX_TRUE) + { + g_failed_append_index = g_total_append + round++; + if (nx_azure_iot_hub_client_command_message_response(&iothub_client, + 200, (VOID *)test_request_id, + sizeof(test_request_id) - 1, + (UCHAR *)test_send_payload, + sizeof(test_send_payload) - 1, + NX_WAIT_FOREVER) == NX_AZURE_IOT_SUCCESS) + { + break; + } + } + + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + g_expected_message = (CHAR *)"{}"; + round = 0; + while (NX_TRUE) + { + g_failed_append_index = g_total_append + round++; + if (nx_azure_iot_hub_client_command_message_response(&iothub_client, + 200, (VOID *)test_request_id, + sizeof(test_request_id) - 1, + NX_NULL, 0, + NX_WAIT_FOREVER) == NX_AZURE_IOT_SUCCESS) + { + break; + } + } +} + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ + NX_AZURE_TEST_FN tests[] = { test_nx_azure_iot_hub_client_invalid_argument_fail, + test_nx_azure_iot_hub_client_command_success, + test_nx_azure_iot_hub_client_component_command_success, + test_nx_azure_iot_hub_client_component_command_blocking_success, + test_nx_azure_iot_hub_client_command_message_receive_no_blocking_success, + test_nx_azure_iot_hub_client_command_blocking_disconnect_fail, + test_nx_azure_iot_hub_client_command_response_send_fail, + test_nx_azure_iot_hub_client_command_response_success, + test_nx_azure_iot_hub_client_command_response_empty_success, + test_nx_azure_iot_hub_client_command_response_oom_fail + }; + INT number_of_tests = sizeof(tests)/sizeof(tests[0]); + g_ip_ptr = ip_ptr; + g_pool_ptr = pool_ptr; + g_dns_ptr = dns_ptr; + + test_suit_begin(); + + printf("Number of tests %d\r\n", number_of_tests); + for (INT index = 0; index < number_of_tests; index++) + { + test_begin(); + tests[index](); + test_end(); + } + + test_suit_end(); +} diff --git a/test/regression/azure_iot/nx_azure_iot_pnp_client_properties_unit_test.c b/test/regression/azure_iot/nx_azure_iot_pnp_client_properties_unit_test.c new file mode 100644 index 00000000..6d241497 --- /dev/null +++ b/test/regression/azure_iot/nx_azure_iot_pnp_client_properties_unit_test.c @@ -0,0 +1,1777 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "azure/core/az_span.h" +#include "nx_api.h" +#include "nx_packet.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_hub_client_properties.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +#ifndef MAXIMUM_PAYLOAD_LENGTH +#define MAXIMUM_PAYLOAD_LENGTH 10240 +#endif /* MAXIMUM_PAYLOAD_LENGTH */ + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, sizeof(s) - 1 + +#define MQTT_CLIENT_GET(c) ((c) -> nx_azure_iot_hub_client_resource.resource_mqtt) +#define TX_MUTEX_GET(c) ((c) -> nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr) + +typedef VOID (*NX_AZURE_TEST_FN)(); + +static ULONG network_bytes_generate_stack[DEMO_HELPER_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD network_bytes_generate_thread; + +static const UCHAR g_hostname[] = "unit-test.iot-azure.com"; +static const UCHAR g_device_id[] = "unit_test_device"; +static const UCHAR g_pnp_model_id[] = "pnp_model_id_unit_test"; +static const UCHAR g_symmetric_key[] = "6CLK6It9jOiABpFVu11CQDv9O49ebAneK3KbsvaoU1o="; +static const UCHAR g_test_component[] = "sample_test"; +static const UCHAR g_test_reported_property_name[] = "test_temperature"; +static const int32_t g_test_reported_property_value = 22; +static const UCHAR g_test_reported_property_name_2[] = "test_temperature_2"; +static const int32_t g_test_reported_property_value_2 = 20; +static const UCHAR g_test_reported_property[] = "{\"test_temperature\":22}"; +static const UCHAR g_test_reported_property_with_component[] = "{\"sample_test\":{\"__t\":\"c\",\"test_temperature\":22}}"; +static const UCHAR g_test_reported_ack_description[] = "success"; +static const UCHAR g_test_reported_property_status_with_component[] = "{\"sample_test\":{" + "\"__t\":\"c\"," + "\"test_temperature\":{" + "\"ac\":200,\"av\":6,\"ad\":\"success\",\"value\":23" + "}" + "}" + "}"; +static const UCHAR g_test_reported_property_status[] = "{\"test_temperature\":{\"ac\":200,\"av\":6,\"ad\":\"success\",\"value\":23}}"; + +static const UCHAR reported_property_success_topic[] = "$iothub/twin/res/204/?$rid=1&$version=6"; +static const CHAR test_device_twin_reported_properties_throttled_response_topic[] = "$iothub/twin/res/429/?$rid=1"; +static const CHAR test_device_twin_document_response_topic[] = "$iothub/twin/res/201/?$rid=2"; +static const CHAR test_device_twin_document_response_payload[] = "{" + "\"desired\":{" + "\"sample_test\":{\"__t\":\"c\",\"test_temperature\":22,\"test_temperature1\":22}," + "\"test_temperature\":22," + "\"$version\":6" + "}," + "\"reported\":{" + "\"sample_test\":{\"__t\":\"c\",\"test_temperature\":22}," + "\"test_temperature\":22," + "\"$version\":7" + "}" +"}"; +static const CHAR test_device_twin_document_response_throttled_topic[] = "$iothub/twin/res/429/?$rid=2"; + +static const CHAR test_device_twin_desired_properties_response_topic[] = "$iothub/twin/PATCH/properties/desired/?$version=6"; +static const CHAR test_device_twin_desired_properties_response_payload[] = "{\"sample_test\":{" + "\"__t\":\"c\"," + "\"test_temperature\":22," + "\"test_temperature_2\":20" + "}," + "\"test_temperature\":22," + "\"test_temperature_2\":20," + "\"$version\":6" + "}"; + +static UINT g_total_append = 0; +static UINT g_failed_append_index = 0; +static UINT g_total_allocation = 0; +static UINT g_failed_allocation_index = -1; +static NX_IP* g_ip_ptr; +static NX_PACKET_POOL* g_pool_ptr; +static NX_DNS* g_dns_ptr; +static ULONG g_available_packet; +static const CHAR *g_expected_message; +static UINT generate_test_property_send_response_bytes = NX_FALSE; +static UINT generate_test_property_send_throttled_response_bytes = NX_FALSE; +static UINT generate_test_all_properties_bytes = NX_FALSE; +static UINT generate_test_all_properties__throttled_bytes = NX_FALSE; +static UINT generate_test_desired_properties_bytes = NX_FALSE; + +extern UINT _nxd_mqtt_client_append_message(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, CHAR *message, + UINT length, ULONG wait_option); +extern UINT _nxd_mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + UCHAR control_header, UINT length, UINT wait_option); +extern UINT nx_azure_iot_hub_client_component_add_internal(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, + const UCHAR *component_name_ptr, + UINT component_name_length, + UINT (*callback_ptr)(VOID *reader_ptr, + ULONG version, + VOID *args), + VOID *callback_args); +extern VOID nx_azure_iot_hub_client_properties_component_process(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, + NX_PACKET *packet_ptr, UINT message_type); + + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iothub_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +static UCHAR message_payload[MAXIMUM_PAYLOAD_LENGTH]; +static UCHAR result_buffer[MAXIMUM_PAYLOAD_LENGTH]; +static VOID (*test_receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count) = NX_NULL; +static UINT system_property_process(VOID *reader_ptr, + ULONG version, + VOID *args); + +UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_receive_notify_set(NXD_MQTT_CLIENT *client_ptr, + VOID (*receive_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count)) +{ + printf("HIJACKED: %s\n", __func__); + test_receive_notify = receive_notify; + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_subscribe(NXD_MQTT_CLIENT *client_ptr, UINT op, + CHAR *topic_name, UINT topic_name_length, + USHORT *packet_id_ptr, UINT QoS) +{ + printf("HIJACKED: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_properties_subscribe_ack = NX_TRUE; + + return((UINT)mock()); +} + +UINT __real__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option); +UINT __wrap__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_append_index == g_total_append) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_append++; + return __real__nx_packet_data_append(packet_ptr, data_start, data_size, pool_ptr, wait_option); +} + +UINT __real_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context); +UINT __wrap_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_allocation_index == g_total_allocation) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_allocation++; + return __real_nx_azure_iot_buffer_allocate(nx_azure_iot_ptr, buffer_pptr, buffer_size, buffer_context); +} + +UINT __wrap__nxd_mqtt_client_publish_packet_send(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + USHORT packet_id, UINT QoS, ULONG wait_option) +{ +UINT topic_name_length; +UINT message_length; +UCHAR *buffer_ptr; +UINT status = (UINT)mock(); + + printf("HIJACKED: %s\n", __func__); + tx_mutex_put(client_ptr -> nxd_mqtt_client_mutex_ptr); + + if (status) + { + return(status); + } + + buffer_ptr = packet_ptr -> nx_packet_prepend_ptr; + topic_name_length = (buffer_ptr[5] << 8) | (buffer_ptr[6]); + message_length = packet_ptr -> nx_packet_length - (7 + topic_name_length); + assert_memory_equal(&buffer_ptr[7 + topic_name_length], g_expected_message, message_length); + assert_int_equal(QoS, 0); + + /* packet ownership taken and released */ + nx_packet_release(packet_ptr); + + return(status); +} + +UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, + UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *, + NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *), + UINT keepalive, UINT clean_session, ULONG wait_option) +{ +az_span source = az_span_create(client_ptr -> nxd_mqtt_client_username, + (INT)client_ptr -> nxd_mqtt_client_username_length); +az_span target = az_span_create((UCHAR *)g_pnp_model_id, sizeof(g_pnp_model_id) - 1); + + printf("HIJACKED: %s\n", __func__); + + /* Check username and client Id to contain modelId and device */ + assert_memory_equal(client_ptr -> nxd_mqtt_client_id, g_device_id, sizeof(g_device_id) - 1); + assert_int_not_equal(az_span_find(source, target), -1); + + tx_thread_suspend(&(iot.nx_azure_iot_ip_ptr -> nx_ip_thread)); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + client_ptr -> nxd_mqtt_client_packet_identifier = 1; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_FALSE; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &client_ptr -> nxd_mqtt_client_socket; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr) +{ + printf("HIJACKED: %s\n", __func__); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ + printf("HIJACKED: %s\n", __func__); + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NX_DNS_SUCCESS); +} + +static UINT mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, UCHAR control_header, UINT length, UINT wait_option) +{ +UCHAR fixed_header[5]; +UCHAR *byte = fixed_header; +UINT count = 0; +UINT ret; + + *byte = control_header; + byte++; + + do + { + if (length & 0xFFFFFF80) + { + *(byte + count) = (UCHAR)((length & 0x7F) | 0x80); + } + else + { + *(byte + count) = length & 0x7F; + } + length = length >> 7; + + count++; + } while (length != 0); + + ret = __real__nx_packet_data_append(packet_ptr, fixed_header, count + 1, + client_ptr -> nxd_mqtt_client_packet_pool_ptr, wait_option); + + return(ret); +} + +static VOID construct_command_message(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, + const UCHAR *topic, ULONG topic_len, + const UCHAR *message_payload_ptr, ULONG message_payload_length, + NX_PACKET **packet_pptr) +{ +NX_PACKET *packet_ptr; +ULONG total_length; +ULONG topic_length = topic_len; +UCHAR bytes[2]; +UINT i; + + assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + total_length = topic_length + 2 + 2 + message_payload_length; /* Two bytes for fixed topic_length field + and two bytes for packet id. */ + + /* Set fixed header. */ + assert_int_equal(mqtt_client_set_fixed_header(&(MQTT_CLIENT_GET(iothub_client_ptr)), packet_ptr, + (UCHAR)((MQTT_CONTROL_PACKET_TYPE_PUBLISH << 4) | MQTT_PUBLISH_QOS_LEVEL_1), + total_length, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic length. */ + bytes[0] = (topic_length >> 8) & 0xFF; + bytes[1] = topic_length & 0xFF; + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set topic. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)topic, topic_len, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + /* Set packet ID. The value does not matter. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set message payload. */ + if (message_payload_length > 0) + { + assert_int_equal(__real__nx_packet_data_append(packet_ptr, (VOID *)message_payload_ptr, message_payload_length, + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + } + + *packet_pptr = packet_ptr; +} + +static VOID generate_test_property_send_response(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr) +{ +NX_PACKET *packet_ptr; + + printf("Bytes : %s\n", __func__); + construct_command_message(iothub_client_ptr, reported_property_success_topic, + sizeof(reported_property_success_topic) - 1, + "", 0, &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(iothub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(iothub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(iothub_client_ptr)); +} + +static VOID generate_test_property_send_throttled_response(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr) +{ +NX_PACKET *packet_ptr; + + printf("Bytes : %s\n", __func__); + construct_command_message(iothub_client_ptr, test_device_twin_reported_properties_throttled_response_topic, + sizeof(test_device_twin_reported_properties_throttled_response_topic) - 1, + "", 0, &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(iothub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(iothub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(iothub_client_ptr)); +} + +static VOID generate_test_all_properties(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr) +{ +NX_PACKET *packet_ptr; + + printf("Bytes : %s\n", __func__); + construct_command_message(iothub_client_ptr, test_device_twin_document_response_topic, + sizeof(test_device_twin_document_response_topic) - 1, + test_device_twin_document_response_payload, + sizeof(test_device_twin_document_response_payload) - 1, + &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(iothub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(iothub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(iothub_client_ptr)); +} + +static VOID generate_test_all_properties_throttled(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr) +{ +NX_PACKET *packet_ptr; + + printf("Bytes : %s\n", __func__); + construct_command_message(iothub_client_ptr, test_device_twin_document_response_throttled_topic, + sizeof(test_device_twin_document_response_throttled_topic) - 1, + "{}", sizeof("{}") - 1, + &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(iothub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(iothub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(iothub_client_ptr)); +} + +static VOID generate_test_desired_properties(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr) +{ +NX_PACKET *packet_ptr; + + printf("Bytes : %s\n", __func__); + construct_command_message(iothub_client_ptr, test_device_twin_desired_properties_response_topic, + sizeof(test_device_twin_desired_properties_response_topic) - 1, + test_device_twin_desired_properties_response_payload, + sizeof(test_device_twin_desired_properties_response_payload) - 1, + &packet_ptr); + + /* Simulate callback from MQTT layer. */ + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(iothub_client_ptr).message_receive_queue_depth = 1; + tx_mutex_get(TX_MUTEX_GET(iothub_client_ptr), NX_WAIT_FOREVER); + test_receive_notify(&(MQTT_CLIENT_GET(iothub_client_ptr)), 1); + tx_mutex_put(TX_MUTEX_GET(iothub_client_ptr)); +} + +static UINT generate_test_properties(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, + NX_PACKET *packet_ptr, + UINT use_component) +{ +UINT status; +NX_AZURE_IOT_JSON_WRITER json_writer; + + if ((status = nx_azure_iot_json_writer_init(&json_writer, packet_ptr, NX_WAIT_FOREVER))) + { + return(status); + } + if ((status = nx_azure_iot_json_writer_append_begin_object(&json_writer))) + { + return(status); + } + if (use_component) + { + if ((status = nx_azure_iot_hub_client_reported_properties_component_begin(iothub_client_ptr, + &json_writer, + STRING_UNSIGNED_ARGS(g_test_component)))) + { + return(status); + } + } + + if ((status = nx_azure_iot_json_writer_append_property_with_int32_value(&json_writer, + STRING_UNSIGNED_ARGS(g_test_reported_property_name), + 22))) + { + return(status); + } + + if (use_component) + { + if ((status = nx_azure_iot_hub_client_reported_properties_component_end(iothub_client_ptr, + &json_writer))) + { + return(status); + } + + g_expected_message = g_test_reported_property_with_component; + } + else + { + g_expected_message = g_test_reported_property; + } + + if ((status = nx_azure_iot_json_writer_append_end_object(&json_writer))) + { + return(status); + } + + return(status); +} + +static UINT generate_test_properties_with_status(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, + NX_PACKET *packet_ptr, + UINT use_component) +{ +UINT status; +NX_AZURE_IOT_JSON_WRITER json_writer; + + if ((status = nx_azure_iot_json_writer_init(&json_writer, packet_ptr, NX_WAIT_FOREVER))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_begin_object(&json_writer))) + { + return(status); + } + + if (use_component) + { + if ((status = nx_azure_iot_hub_client_reported_properties_component_begin(iothub_client_ptr, + &json_writer, + STRING_UNSIGNED_ARGS(g_test_component)))) + { + return(status); + } + } + + if ((status = nx_azure_iot_hub_client_reported_properties_status_begin(iothub_client_ptr, + &json_writer, + STRING_UNSIGNED_ARGS(g_test_reported_property_name), + 200, 6, + STRING_UNSIGNED_ARGS(g_test_reported_ack_description)))) + { + return(status); + } + + if ((status = nx_azure_iot_json_writer_append_int32(&json_writer, 23))) + { + return(status); + } + + if ((status = nx_azure_iot_hub_client_reported_properties_status_end(iothub_client_ptr, + &json_writer))) + { + return(status); + } + + if (use_component) + { + if ((status = nx_azure_iot_hub_client_reported_properties_component_end(iothub_client_ptr, + &json_writer))) + { + return(status); + } + + g_expected_message = g_test_reported_property_status_with_component; + } + else + { + g_expected_message = g_test_reported_property_status; + } + + if ((status = nx_azure_iot_json_writer_append_end_object(&json_writer))) + { + return(status); + } + + return(status); +} + +/* Generate network received bytes */ +static VOID network_bytes_generate_entry(ULONG args) +{ + while (NX_TRUE) + { + if (generate_test_property_send_response_bytes) + { + generate_test_property_send_response_bytes = NX_FALSE; + generate_test_property_send_response(&iothub_client); + } + + if (generate_test_property_send_throttled_response_bytes) + { + generate_test_property_send_throttled_response_bytes = NX_FALSE; + generate_test_property_send_throttled_response(&iothub_client); + } + + if (generate_test_all_properties_bytes) + { + generate_test_all_properties_bytes = NX_FALSE; + generate_test_all_properties(&iothub_client); + } + + if (generate_test_all_properties__throttled_bytes) + { + generate_test_all_properties__throttled_bytes = NX_FALSE; + generate_test_all_properties_throttled(&iothub_client); + } + + if (generate_test_desired_properties_bytes) + { + generate_test_desired_properties_bytes = NX_FALSE; + generate_test_desired_properties(&iothub_client); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } +} + +static VOID on_receive_callback(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, VOID *arg) +{ + *((UINT *)arg) = 1; +} + +static VOID reported_property_cb(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, + UINT request_id, UINT response_status, + ULONG version, VOID *args) +{ + *((UINT *)args) = response_status; +} + +static VOID validate_json_reader(NX_AZURE_IOT_JSON_READER *reader_ptr, const CHAR *expected_json) +{ +NX_AZURE_IOT_JSON_READER expected_json_reader; +UINT status; +UINT expected_status; + + assert_int_equal(nx_azure_iot_json_reader_with_buffer_init(&expected_json_reader, + (const UCHAR *)expected_json, + strlen(expected_json)), + NX_AZURE_IOT_SUCCESS); + + while (1) + { + status = nx_azure_iot_json_reader_next_token(reader_ptr); + expected_status = nx_azure_iot_json_reader_next_token(&expected_json_reader); + assert_int_equal(status, expected_status); + + if (expected_status) + { + break; + } + + assert_int_equal(nx_azure_iot_json_reader_token_type(reader_ptr), + nx_azure_iot_json_reader_token_type(&expected_json_reader)); + } +} + +static VOID reset_global_state() +{ + /* reset global state */ + g_failed_append_index = (UINT)-1; + g_total_append = 0; + g_failed_allocation_index = (UINT)-1; + g_total_allocation = 0; + g_expected_message = NX_NULL; + generate_test_property_send_response_bytes = NX_FALSE; +} + +/* Hook execute before all tests. */ +static VOID test_suit_begin() +{ + assert_int_equal(tx_thread_create(&network_bytes_generate_thread, + "UintTestNetworkBytesGenerator", + network_bytes_generate_entry, 0, + network_bytes_generate_stack, + DEMO_HELPER_STACK_SIZE, + DEMO_HELPER_THREAD_PRIORITY + 1, + DEMO_HELPER_THREAD_PRIORITY + 1, + TX_NO_TIME_SLICE, TX_AUTO_START), + NX_AZURE_IOT_SUCCESS); + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, + (UCHAR *)_nx_azure_iot_root_cert, + (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", + g_ip_ptr, g_pool_ptr, g_dns_ptr, + (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), + DEMO_CLOUD_THREAD_PRIORITY, unix_time_get), + NX_AZURE_IOT_SUCCESS); + + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&iothub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&iothub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); + + /* Set symmetric key credentials */ + assert_int_equal(nx_azure_iot_hub_client_symmetric_key_set(&iothub_client, + g_symmetric_key, + sizeof(g_symmetric_key) - 1), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_component_add_internal(&iothub_client, + g_test_component, + sizeof(g_test_component) - 1, + system_property_process, + NX_NULL), + NX_AZURE_IOT_SUCCESS); + iothub_client.nx_azure_iot_hub_client_component_callback[0] = NX_NULL; + + will_return_always(__wrap__nxde_mqtt_client_subscribe, NX_AZURE_IOT_SUCCESS); + + /* Connect IoTHub client */ + assert_int_equal(nx_azure_iot_hub_client_connect(&iothub_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + /* Enable properties. */ + assert_int_equal(nx_azure_iot_hub_client_properties_enable(&iothub_client), + NX_AZURE_IOT_SUCCESS); +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_suit_end() +{ + assert_int_equal(nx_azure_iot_hub_client_disconnect(&iothub_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iothub_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_delete(&iot), + NX_AZURE_IOT_SUCCESS); +} + +/* Hook executed before every test */ +static VOID test_begin() +{ + reset_global_state(); + + /* Record number of available packet before test */ + g_available_packet = g_pool_ptr -> nx_packet_pool_available; +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_end() +{ + /* Check if all the packet are released */ + assert_int_equal(g_pool_ptr -> nx_packet_pool_available, g_available_packet); +} + +/** + * Test invalid argument failure. + * + **/ +static VOID test_nx_azure_iot_hub_client_invalid_argument_fail() +{ +NX_PACKET *packet_ptr; +NX_AZURE_IOT_JSON_WRITER writer; +NX_AZURE_IOT_JSON_READER reader; +const UCHAR *component_name; +USHORT component_name_length; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_create(NX_NULL, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_create(&iothub_client, + NX_NULL, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_component_begin(NX_NULL, + &writer, + NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_component_begin(&iothub_client, + NX_NULL, + NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_component_end(&iothub_client, + NX_NULL), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_component_end(NX_NULL, + &writer), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_send(NX_NULL, + packet_ptr, + NX_NULL, NX_NULL, + NX_NULL, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_send(&iothub_client, + NX_NULL, + NX_NULL, NX_NULL, + NX_NULL, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_request(NX_NULL, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_receive(NX_NULL, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_receive(&iothub_client, + NX_NULL, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_writable_properties_receive(NX_NULL, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_writable_properties_receive(&iothub_client, + NX_NULL, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_version_get(NX_NULL, + &reader, + NX_AZURE_IOT_HUB_PROPERTIES, + &version), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_version_get(&iothub_client, + NX_NULL, + NX_AZURE_IOT_HUB_PROPERTIES, + &version), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_version_get(&iothub_client, + &reader, + 0, + &version), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_version_get(&iothub_client, + &reader, + NX_AZURE_IOT_HUB_PROPERTIES, + NX_NULL), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_component_property_next_get(NX_NULL, + &reader, + NX_AZURE_IOT_HUB_PROPERTIES, + NX_AZURE_IOT_HUB_CLIENT_PROPERTY_WRITABLE, + &component_name, &component_name_length), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_component_property_next_get(&iothub_client, + NX_NULL, + NX_AZURE_IOT_HUB_PROPERTIES, + NX_AZURE_IOT_HUB_CLIENT_PROPERTY_WRITABLE, + &component_name, &component_name_length), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_component_property_next_get(&iothub_client, + &reader, + 1, + NX_AZURE_IOT_HUB_CLIENT_PROPERTY_WRITABLE, + &component_name, &component_name_length), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_component_property_next_get(&iothub_client, + &reader, + NX_AZURE_IOT_HUB_PROPERTIES, + 3, + &component_name, &component_name_length), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_component_property_next_get(&iothub_client, + &reader, + NX_AZURE_IOT_HUB_PROPERTIES, + NX_AZURE_IOT_HUB_CLIENT_PROPERTY_WRITABLE, + NX_NULL, &component_name_length), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_component_property_next_get(&iothub_client, + &reader, + NX_AZURE_IOT_HUB_PROPERTIES, + NX_AZURE_IOT_HUB_CLIENT_PROPERTY_WRITABLE, + &component_name, NX_NULL), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_component_add(NX_NULL, NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_component_add(&iothub_client, NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_response_callback_set(NX_NULL, NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_status_begin(&iothub_client, + NX_NULL, NX_NULL, + 0, 0, 0, NX_NULL, 0), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_status_end(&iothub_client, NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful pnp property send. + * + **/ +static VOID test_nx_azure_iot_hub_client_property_send_success() +{ +NX_PACKET *packet_ptr; +UINT request_id; +UINT response_status; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + assert_int_equal(nx_azure_iot_hub_client_reported_properties_create(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_properties(&iothub_client, packet_ptr, NX_FALSE), + NX_AZURE_IOT_SUCCESS); + generate_test_property_send_response_bytes = NX_TRUE; + + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_reported_properties_send(&iothub_client, + packet_ptr, + &request_id, &response_status, + &version, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful pnp property send with NO_WAIT. + * + **/ +static VOID test_nx_azure_iot_hub_client_property_send_async_success() +{ +NX_PACKET *packet_ptr; +UINT response_status = 0; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + assert_int_equal(nx_azure_iot_hub_client_reported_properties_response_callback_set(&iothub_client, + reported_property_cb, + &response_status), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_reported_properties_create(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_properties(&iothub_client, packet_ptr, NX_FALSE), + NX_AZURE_IOT_SUCCESS); + generate_test_property_send_response_bytes = NX_TRUE; + + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_reported_properties_send(&iothub_client, + packet_ptr, + NX_NULL, &response_status, + NX_NULL, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + while (response_status == 0) + { + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + } + + assert_int_equal(nx_azure_iot_hub_client_reported_properties_response_callback_set(&iothub_client, + NX_NULL, NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful pnp component property send. + * + **/ +static VOID test_nx_azure_iot_hub_client_component_property_send_success() +{ +NX_PACKET *packet_ptr; +UINT request_id; +UINT response_status; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + + assert_int_equal(nx_azure_iot_hub_client_reported_properties_create(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_properties(&iothub_client, packet_ptr, NX_TRUE), + NX_AZURE_IOT_SUCCESS); + generate_test_property_send_response_bytes = NX_TRUE; + + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_reported_properties_send(&iothub_client, + packet_ptr, + &request_id, &response_status, + &version, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful send reported pnp property status. + * + **/ +static VOID test_nx_azure_iot_hub_client_reported_property_status_send_success() +{ +NX_PACKET *packet_ptr; +UINT request_id; +UINT response_status; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + assert_int_equal(nx_azure_iot_hub_client_reported_properties_create(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_properties_with_status(&iothub_client, packet_ptr, NX_FALSE), + NX_AZURE_IOT_SUCCESS); + generate_test_property_send_response_bytes = NX_TRUE; + + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_reported_properties_send(&iothub_client, + packet_ptr, + &request_id, &response_status, + &version, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful send reported pnp component property status. + * + **/ +static VOID test_nx_azure_iot_hub_client_reported_component_property_status_send_success() +{ +NX_PACKET *packet_ptr; +UINT request_id; +UINT response_status; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + assert_int_equal(nx_azure_iot_hub_client_reported_properties_create(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_properties_with_status(&iothub_client, packet_ptr, NX_TRUE), + NX_AZURE_IOT_SUCCESS); + generate_test_property_send_response_bytes = NX_TRUE; + + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_reported_properties_send(&iothub_client, + packet_ptr, + &request_id, &response_status, + &version, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test pnp property send fail. + * + **/ +static VOID test_nx_azure_iot_hub_client_property_send_fail() +{ +NX_PACKET *packet_ptr; +UINT request_id; +UINT response_status; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + + assert_int_equal(nx_azure_iot_hub_client_reported_properties_create(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_properties(&iothub_client, packet_ptr, NX_FALSE), + NX_AZURE_IOT_SUCCESS); + + generate_test_property_send_response_bytes = NX_TRUE; + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_FAILURE); + assert_int_not_equal(nx_azure_iot_hub_client_reported_properties_send(&iothub_client, + packet_ptr, + &request_id, &response_status, + &version, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + assert_ptr_not_equal(packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next, (NX_PACKET *)NX_PACKET_FREE); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test pnp property send fail due to throttling. + * + **/ +static VOID test_nx_azure_iot_hub_client_property_send_throttled_fail() +{ +NX_PACKET *packet_ptr; +UINT request_id; +UINT response_status; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + assert_int_equal(nx_azure_iot_hub_client_reported_properties_create(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_properties(&iothub_client, packet_ptr, NX_FALSE), + NX_AZURE_IOT_SUCCESS); + + generate_test_property_send_throttled_response_bytes = NX_TRUE; + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_reported_properties_send(&iothub_client, + packet_ptr, + &request_id, &response_status, + &version, 1 * NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(response_status, 0); + assert_int_not_equal(iothub_client.nx_azure_iot_hub_client_throttle_count, 0); + assert_int_not_equal(iothub_client.nx_azure_iot_hub_client_throttle_end_time, 0); + + /* Create new message */ + iothub_client.nx_azure_iot_hub_client_request_id = 0; + assert_int_equal(nx_azure_iot_hub_client_reported_properties_create(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(generate_test_properties(&iothub_client, packet_ptr, NX_FALSE), + NX_AZURE_IOT_SUCCESS); + + generate_test_property_send_response_bytes = NX_TRUE; + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + while (nx_azure_iot_hub_client_reported_properties_send(&iothub_client, + packet_ptr, + &request_id, &response_status, + &version, NX_WAIT_FOREVER)) + { + /* Do not sleep as we want to kick network response only when thread is inside send */ + } + + assert_int_not_equal(response_status, 429); +} + +/** + * Test get pnp properties success. + * + **/ +static VOID test_nx_azure_iot_hub_client_property_get_success() +{ +NX_PACKET *packet_ptr; +NX_AZURE_IOT_JSON_READER reader; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + + g_expected_message = ""; + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_properties_request(&iothub_client, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + generate_test_all_properties_bytes = NX_TRUE; + + assert_int_equal(nx_azure_iot_hub_client_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + validate_json_reader(&reader, test_device_twin_document_response_payload); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test get pnp properties success with NO_WAIT. + * + **/ +static VOID test_nx_azure_iot_hub_client_property_get_async_success() +{ +NX_PACKET *packet_ptr; +NX_AZURE_IOT_JSON_READER reader; +ULONG version; +UINT received_bytes = 0; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + + assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iothub_client, + NX_AZURE_IOT_HUB_PROPERTIES, + on_receive_callback, + &received_bytes), + NX_AZURE_IOT_SUCCESS); + + g_expected_message = ""; + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_properties_request(&iothub_client, + NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + generate_test_all_properties_bytes = NX_TRUE; + + while (received_bytes == 0) + { + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + } + + assert_int_equal(nx_azure_iot_hub_client_properties_receive(&iothub_client, + &packet_ptr, + NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + validate_json_reader(&reader, test_device_twin_document_response_payload); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iothub_client, + NX_AZURE_IOT_HUB_PROPERTIES, + NX_NULL, NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test get pnp properties fail to send request. + * + **/ +static VOID test_nx_azure_iot_hub_client_property_get_send_fail() +{ +NX_AZURE_IOT_JSON_READER reader; +UINT request_id; +UINT response_status; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + + g_expected_message = ""; + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_FAILURE); + assert_int_not_equal(nx_azure_iot_hub_client_properties_request(&iothub_client, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test get pnp properties fail to receive. + * + **/ +static VOID test_nx_azure_iot_hub_client_property_get_receive_fail() +{ +NX_PACKET *packet_ptr; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + + g_expected_message = ""; + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_properties_request(&iothub_client, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_not_equal(nx_azure_iot_hub_client_properties_receive(&iothub_client, + &packet_ptr, + 5 * (NX_IP_PERIODIC_RATE)), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test get pnp properties fail due to throttled error. + * + **/ +static VOID test_nx_azure_iot_hub_client_property_get_request_throttle_fail() +{ +NX_PACKET *packet_ptr; +NX_AZURE_IOT_JSON_READER reader; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + + g_expected_message = ""; + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_properties_request(&iothub_client, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + generate_test_all_properties__throttled_bytes = NX_TRUE; + assert_int_not_equal(nx_azure_iot_hub_client_properties_receive(&iothub_client, + &packet_ptr, + 1 * NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_properties_request(&iothub_client, NX_NO_WAIT), + NX_AZURE_IOT_THROTTLED); + + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + while (nx_azure_iot_hub_client_properties_request(&iothub_client, NX_NO_WAIT)) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + generate_test_all_properties_bytes = NX_TRUE; + assert_int_equal(nx_azure_iot_hub_client_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + validate_json_reader(&reader, test_device_twin_document_response_payload); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test receive pnp desired properties success. + * + **/ +static VOID test_nx_azure_iot_hub_client_desired_property_receive_success() +{ +NX_PACKET *packet_ptr; +NX_AZURE_IOT_JSON_READER reader; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + generate_test_desired_properties_bytes = NX_TRUE; + + assert_int_equal(nx_azure_iot_hub_client_writable_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_properties_version_get(&iothub_client, + &reader, + NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES, + &version), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + validate_json_reader(&reader, test_device_twin_desired_properties_response_payload); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test receive pnp desired properties success with NO_WAIT. + * + **/ +static VOID test_nx_azure_iot_hub_client_desired_property_receive_async_success() +{ +NX_PACKET *packet_ptr; +NX_AZURE_IOT_JSON_READER reader; +ULONG version; +UINT received_bytes = 0; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + generate_test_desired_properties_bytes = NX_TRUE; + + assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iothub_client, + NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES, + on_receive_callback, + &received_bytes), + NX_AZURE_IOT_SUCCESS); + + while (received_bytes == 0) + { + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + } + + assert_int_equal(nx_azure_iot_hub_client_writable_properties_receive(&iothub_client, + &packet_ptr, + NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_properties_version_get(&iothub_client, + &reader, + NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES, + &version), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + validate_json_reader(&reader, test_device_twin_desired_properties_response_payload); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_receive_callback_set(&iothub_client, + NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES, + NX_NULL, NX_NULL), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test scan desired PnP property. + * + **/ +static VOID test_nx_azure_iot_hub_client_desired_property_iterate_success() +{ +NX_PACKET *packet_ptr; +NX_AZURE_IOT_JSON_READER reader; +const UCHAR *component_ptr; +USHORT component_length = 0; +int32_t value; +UINT found_component = NX_FALSE; +UINT found_root_component = NX_FALSE; +ULONG version; +UINT index = 0; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + generate_test_desired_properties_bytes = NX_TRUE; + assert_int_equal(nx_azure_iot_hub_client_writable_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_properties_version_get(&iothub_client, + &reader, + NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES, + &version), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + while (nx_azure_iot_hub_client_properties_component_property_next_get(&iothub_client, &reader, + NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES, + NX_AZURE_IOT_HUB_CLIENT_PROPERTY_WRITABLE, + &component_ptr, &component_length) == NX_AZURE_IOT_SUCCESS) + { + if ((index == 0) || (index == 1)) + { + assert_memory_equal(component_ptr, g_test_component, sizeof(g_test_component) - 1); + found_component = NX_TRUE; + } + else + { + assert_non_null(found_component); + found_root_component = NX_TRUE; + } + + if ((index == 0) || (index == 2)) + { + assert_int_equal(nx_azure_iot_json_reader_token_is_text_equal(&reader, + (UCHAR *)g_test_reported_property_name, + sizeof(g_test_reported_property_name) - 1), + NX_TRUE); + } + else + { + assert_int_equal(nx_azure_iot_json_reader_token_is_text_equal(&reader, + (UCHAR *)g_test_reported_property_name_2, + sizeof(g_test_reported_property_name_2) - 1), + NX_TRUE); + } + + assert_int_equal(nx_azure_iot_json_reader_next_token(&reader), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_json_reader_token_int32_get(&reader, &value), + NX_AZURE_IOT_SUCCESS); + + if ((index == 0) || (index == 2)) + { + assert_int_equal(value, g_test_reported_property_value); + } + else + { + assert_int_equal(value, g_test_reported_property_value_2); + } + + assert_int_equal(nx_azure_iot_json_reader_next_token(&reader), + NX_AZURE_IOT_SUCCESS); + + index++; + } + + assert_true(found_component); + assert_true(found_root_component); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test get desired PnP properties version. + * + **/ +static VOID test_nx_azure_iot_hub_client_desired_properties_version_success() +{ +NX_PACKET *packet_ptr; +NX_AZURE_IOT_JSON_READER reader; +ULONG version; + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + generate_test_desired_properties_bytes = NX_TRUE; + assert_int_equal(nx_azure_iot_hub_client_writable_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_properties_version_get(&iothub_client, + &reader, + NX_AZURE_IOT_HUB_WRITABLE_PROPERTIES, + &version), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(version, 6); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + + g_expected_message = ""; + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_properties_request(&iothub_client, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + generate_test_all_properties_bytes = NX_TRUE; + + assert_int_equal(nx_azure_iot_hub_client_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_properties_version_get(&iothub_client, + &reader, + NX_AZURE_IOT_HUB_PROPERTIES, + &version), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(version, 6); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); +} + +static UINT system_property_processed; +static UINT system_property_process(VOID *reader_ptr, + ULONG version, + VOID *args) +{ +NX_AZURE_IOT_JSON_READER *json_reader_ptr = (NX_AZURE_IOT_JSON_READER *)reader_ptr; + + /* Update the flag. */ + system_property_processed = NX_TRUE; + + /* Yes, skip it and find the next. */ + nx_azure_iot_json_reader_next_token(json_reader_ptr); + + /* Skip children in case the property value is an object. */ + if (nx_azure_iot_json_reader_token_type(json_reader_ptr) == NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT) + { + nx_azure_iot_json_reader_skip_children(json_reader_ptr); + } + nx_azure_iot_json_reader_next_token(json_reader_ptr); + + return(NX_AZURE_IOT_SUCCESS); +} + +/** + * Test system properties success. + * + **/ +static VOID test_nx_azure_iot_hub_client_system_property_get_success() +{ +NX_PACKET *packet_ptr; +NX_AZURE_IOT_JSON_READER reader; +const UCHAR *component_ptr; +USHORT component_length; +int32_t value; +UINT found_component = NX_FALSE; +UINT found_root_component = NX_FALSE; +ULONG version; + + + printf("test starts =>: %s\n", __func__); + + iothub_client.nx_azure_iot_hub_client_request_id = 0; + + /* Initialize. */ + system_property_processed = NX_FALSE; + + /* Set component process routine for system component. */ + iothub_client.nx_azure_iot_hub_client_component_properties_process = nx_azure_iot_hub_client_properties_component_process; + + /* Mark g_test_component as system component. */ + iothub_client.nx_azure_iot_hub_client_component_callback[0] = system_property_process; + + g_expected_message = ""; + will_return(__wrap__nxd_mqtt_client_publish_packet_send, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_properties_request(&iothub_client, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + generate_test_all_properties_bytes = NX_TRUE; + + assert_int_equal(nx_azure_iot_hub_client_properties_receive(&iothub_client, + &packet_ptr, + NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_properties_version_get(&iothub_client, + &reader, + NX_AZURE_IOT_HUB_PROPERTIES, + &version), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_json_reader_init(&reader, packet_ptr), + NX_AZURE_IOT_SUCCESS); + + while (nx_azure_iot_hub_client_properties_component_property_next_get(&iothub_client, &reader, + NX_AZURE_IOT_HUB_PROPERTIES, + NX_AZURE_IOT_HUB_CLIENT_PROPERTY_WRITABLE, + &component_ptr, &component_length) == NX_AZURE_IOT_SUCCESS) + { + if (component_ptr != NX_NULL) + { + found_component = NX_TRUE; + } + else + { + found_root_component = NX_TRUE; + } + + assert_int_equal(nx_azure_iot_json_reader_token_is_text_equal(&reader, + (UCHAR *)g_test_reported_property_name, + sizeof(g_test_reported_property_name) - 1), + NX_TRUE); + assert_int_equal(nx_azure_iot_json_reader_next_token(&reader), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_json_reader_token_int32_get(&reader, &value), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(value, g_test_reported_property_value); + assert_int_equal(nx_azure_iot_json_reader_next_token(&reader), + NX_AZURE_IOT_SUCCESS); + } + + assert_false(found_component); + assert_true(found_root_component); + assert_true(system_property_processed); + + assert_int_equal(nx_packet_release(packet_ptr), + NX_AZURE_IOT_SUCCESS); + + /* Mark g_test_component assystem component. */ + iothub_client.nx_azure_iot_hub_client_component_callback[0] = NX_NULL; +} + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ + NX_AZURE_TEST_FN tests[] = {test_nx_azure_iot_hub_client_invalid_argument_fail, + test_nx_azure_iot_hub_client_property_send_success, + test_nx_azure_iot_hub_client_property_send_async_success, + test_nx_azure_iot_hub_client_component_property_send_success, + test_nx_azure_iot_hub_client_reported_property_status_send_success, + test_nx_azure_iot_hub_client_reported_component_property_status_send_success, + test_nx_azure_iot_hub_client_property_send_fail, + test_nx_azure_iot_hub_client_property_send_throttled_fail, + test_nx_azure_iot_hub_client_property_get_success, + test_nx_azure_iot_hub_client_property_get_async_success, + test_nx_azure_iot_hub_client_property_get_send_fail, + test_nx_azure_iot_hub_client_property_get_receive_fail, + test_nx_azure_iot_hub_client_property_get_request_throttle_fail, + test_nx_azure_iot_hub_client_desired_property_receive_success, + test_nx_azure_iot_hub_client_desired_property_receive_async_success, + test_nx_azure_iot_hub_client_desired_property_iterate_success, + test_nx_azure_iot_hub_client_desired_properties_version_success, + test_nx_azure_iot_hub_client_system_property_get_success + }; + INT number_of_tests = sizeof(tests)/sizeof(tests[0]); + g_ip_ptr = ip_ptr; + g_pool_ptr = pool_ptr; + g_dns_ptr = dns_ptr; + + test_suit_begin(); + + printf("Number of tests %d\r\n", number_of_tests); + for (INT index = 0; index < number_of_tests; index++) + { + test_begin(); + tests[index](); + test_end(); + } + + test_suit_end(); +} diff --git a/test/regression/azure_iot/nx_azure_iot_pnp_client_telemetry_unit_test.c b/test/regression/azure_iot/nx_azure_iot_pnp_client_telemetry_unit_test.c new file mode 100644 index 00000000..27b7cf3f --- /dev/null +++ b/test/regression/azure_iot/nx_azure_iot_pnp_client_telemetry_unit_test.c @@ -0,0 +1,993 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "azure/core/az_span.h" +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +#ifndef MAXIMUM_PAYLOAD_LENGTH +#define MAXIMUM_PAYLOAD_LENGTH 10240 +#endif /* MAXIMUM_PAYLOAD_LENGTH */ + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, sizeof(s) - 1 + +#define MQTT_CLIENT_GET(c) ((c) -> nx_azure_iot_hub_client_resource.resource_mqtt) + +typedef VOID (*NX_AZURE_TEST_FN)(); + +static const UCHAR g_hostname[] = "unit-test.iot-azure.com"; +static const UCHAR g_device_id[] = "unit_test_device"; +static const UCHAR g_pnp_model_id[] = "pnp_model_id_unit_test"; +static const UCHAR g_symmetric_key[] = "6CLK6It9jOiABpFVu11CQDv9O49ebAneK3KbsvaoU1o="; +static const UCHAR g_test_component[] = "sample_test"; +static const UCHAR g_test_property_name[] = "sample_test_property_name"; +static const UCHAR g_test_property_value[] = "sample_test_property_value"; +static const UCHAR g_test_telemetry_data[] = "sample_telemetry_test_data"; + +static UINT g_total_append = 0; +static UINT g_failed_append_index = 0; +static UINT g_total_allocation = 0; +static UINT g_failed_allocation_index = -1; +static UINT g_telemetry_ack_count = 0; +static NX_IP* g_ip_ptr; +static NX_PACKET_POOL* g_pool_ptr; +static NX_DNS* g_dns_ptr; +static ULONG g_available_packet; +static CHAR *g_expected_message; +static UINT g_connect_status; +static VOID (*test_connect_notify)(struct NXD_MQTT_CLIENT_STRUCT *client_ptr, UINT status, VOID *context) = NX_NULL; +static VOID *test_connect_notify_context = NX_NULL; +static VOID (*test_telemetry_ack_notify)(NXD_MQTT_CLIENT *client_ptr, UINT message_count) = NX_NULL; + +extern UINT _nxd_mqtt_client_append_message(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, CHAR *message, + UINT length, ULONG wait_option); +extern UINT _nxd_mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + UCHAR control_header, UINT length, UINT wait_option); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT hub_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +static UCHAR message_payload[MAXIMUM_PAYLOAD_LENGTH]; +static UCHAR result_buffer[MAXIMUM_PAYLOAD_LENGTH]; + +UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __real__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option); +UINT __wrap__nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size, + NX_PACKET_POOL *pool_ptr, ULONG wait_option) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_append_index == g_total_append) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_append++; + return __real__nx_packet_data_append(packet_ptr, data_start, data_size, pool_ptr, wait_option); +} + +UINT __real_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context); +UINT __wrap_nx_azure_iot_buffer_allocate(NX_AZURE_IOT *nx_azure_iot_ptr, UCHAR **buffer_pptr, + UINT *buffer_size, VOID **buffer_context) +{ + printf("HIJACKED: %s\n", __func__); + + if (g_failed_allocation_index == g_total_allocation) + { + return(NX_NOT_SUCCESSFUL); + } + + g_total_allocation++; + return __real_nx_azure_iot_buffer_allocate(nx_azure_iot_ptr, buffer_pptr, buffer_size, buffer_context); +} + +UINT __wrap__nx_tcp_socket_send(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, ULONG wait_option) +{ +UINT status = (UINT)mock(); + + printf("HIJACKED: %s\n", __func__); + + if (status == NX_SUCCESS) + { + + /* packet ownership taken and released */ + nx_packet_release(packet_ptr); + } + + return(status); +} + +UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, + UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *, + NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *), + UINT keepalive, UINT clean_session, ULONG wait_option) +{ +az_span source = az_span_create(client_ptr -> nxd_mqtt_client_username, + (INT)client_ptr -> nxd_mqtt_client_username_length); +az_span target = az_span_create((UCHAR *)g_pnp_model_id, sizeof(g_pnp_model_id) - 1); +UINT status = (UINT)mock(); + + printf("HIJACKED: %s\n", __func__); + + if ((status != NXD_MQTT_SUCCESS) && (status != NX_IN_PROGRESS)) + { + return(status); + } + + /* Check username and client Id to contain modelId and device */ + assert_memory_equal(client_ptr -> nxd_mqtt_client_id, g_device_id, sizeof(g_device_id) - 1); + assert_int_not_equal(az_span_find(source, target), -1); + + tx_thread_suspend(&(iot.nx_azure_iot_ip_ptr -> nx_ip_thread)); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + client_ptr -> nxd_mqtt_client_packet_identifier = 1; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_FALSE; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &client_ptr -> nxd_mqtt_client_socket; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + test_connect_notify = client_ptr -> nxd_mqtt_connect_notify; + test_connect_notify_context = client_ptr -> nxd_mqtt_connect_context; + + return(status); +} + +UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr) +{ + printf("HIJACKED: %s\n", __func__); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + + if (client_ptr -> nxd_mqtt_disconnect_notify) + { + client_ptr -> nxd_mqtt_disconnect_notify(client_ptr); + } + + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ + printf("HIJACKED: %s\n", __func__); + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NX_DNS_SUCCESS); +} + +UINT __wrap__nxd_mqtt_client_sub_unsub(NXD_MQTT_CLIENT *client_ptr, CHAR *topic_name, + UINT topic_name_length, UINT QoS) +{ + hub_client.nx_azure_iot_hub_client_properties_subscribe_ack = 0; + + return(NX_AZURE_IOT_SUCCESS); +} + +static VOID telemetry_ack_callback(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, USHORT packet_id) +{ + NX_PARAMETER_NOT_USED(hub_client_ptr); + NX_PARAMETER_NOT_USED(packet_id); + + g_telemetry_ack_count ++; +} + +static UCHAR test_telemetry_ack_tcp_header[]={0x01, 0xbb, 0xcb, 0x84, 0x78, 0x58, 0x93, 0xd1, + 0x2d, 0x55, 0x45, 0x5f, 0xff, 0xff, 0x10, 0x50, + 0xbd, 0xf0, 0x00, 0x00}; + +static UCHAR test_telemetry_ack_puback_header[] ={0x40, 0x02}; + +static VOID generate_test_telemetry_ack(NX_AZURE_IOT_HUB_CLIENT *iothub_client_ptr, USHORT packet_id) +{ +NX_PACKET *packet_ptr; +UCHAR bytes[2]; + + + printf("Bytes : %s\n", __func__); + /* Create the socket. */ + nx_tcp_socket_create(g_ip_ptr, &(MQTT_CLIENT_GET(iothub_client_ptr).nxd_mqtt_client_socket), "mqtt client socket", + NX_IP_NORMAL, NX_DONT_FRAGMENT, 0x80, NXD_MQTT_CLIENT_SOCKET_WINDOW_SIZE, + NX_NULL, NX_NULL); + + + /* Record the client_ptr in the socket structure. */ + MQTT_CLIENT_GET(iothub_client_ptr).nxd_mqtt_client_socket.nx_tcp_socket_reserved_ptr = (VOID *)iothub_client_ptr; + + nx_tcp_client_socket_bind(&(MQTT_CLIENT_GET(iothub_client_ptr).nxd_mqtt_client_socket), NX_ANY_PORT, NX_NO_WAIT); + + assert_int_equal(nx_packet_allocate(iot.nx_azure_iot_pool_ptr, &packet_ptr, 0, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + + /* Fill the TCP header data. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, test_telemetry_ack_tcp_header, + sizeof(test_telemetry_ack_tcp_header), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Fill the MQTT PUBACK header data. */ + assert_int_equal(__real__nx_packet_data_append(packet_ptr, test_telemetry_ack_puback_header, + sizeof(test_telemetry_ack_puback_header), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Set packet ID. */ + bytes[0] = (UCHAR)(packet_id >> 8); + bytes[1] = (UCHAR)(packet_id & 0xFF); + assert_int_equal(__real__nx_packet_data_append(packet_ptr, bytes, sizeof(bytes), + iot.nx_azure_iot_pool_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Simulate callback from MQTT layer. */ + packet_ptr -> nx_packet_queue_next = (NX_PACKET *)0xBBBBBBBB; + MQTT_CLIENT_GET(iothub_client_ptr).nxd_mqtt_client_socket.nx_tcp_socket_receive_queue_head = packet_ptr; + MQTT_CLIENT_GET(iothub_client_ptr).nxd_mqtt_client_socket.nx_tcp_socket_receive_queue_tail = packet_ptr; + MQTT_CLIENT_GET(iothub_client_ptr).nxd_mqtt_client_socket.nx_tcp_socket_receive_queue_count = 1; + MQTT_CLIENT_GET(iothub_client_ptr).nxd_mqtt_client_socket.nx_tcp_socket_state = 1; + nx_cloud_module_event_set(&(MQTT_CLIENT_GET(iothub_client_ptr).nxd_mqtt_client_cloud_module), 0x00000002); /* MQTT_PACKET_RECEIVE_EVENT */ +} + +static UINT mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, UCHAR control_header, UINT length, UINT wait_option) +{ +UCHAR fixed_header[5]; +UCHAR *byte = fixed_header; +UINT count = 0; +UINT ret; + + *byte = control_header; + byte++; + + do + { + if (length & 0xFFFFFF80) + { + *(byte + count) = (UCHAR)((length & 0x7F) | 0x80); + } + else + { + *(byte + count) = length & 0x7F; + } + length = length >> 7; + + count++; + } while (length != 0); + + ret = __real__nx_packet_data_append(packet_ptr, fixed_header, count + 1, + client_ptr -> nxd_mqtt_client_packet_pool_ptr, wait_option); + + return(ret); +} + +static VOID connection_status_cb(NX_AZURE_IOT_HUB_CLIENT *hub_client_ptr, UINT status) +{ + g_connect_status = status; +} + +static VOID reset_global_state() +{ + /* reset global state */ + g_failed_append_index = (UINT)-1; + g_total_append = 0; + g_failed_allocation_index = (UINT)-1; + g_total_allocation = 0; + g_expected_message = NX_NULL; + g_connect_status = NX_AZURE_IOT_FAILURE; +} + +/* Hook execute before all tests. */ +static VOID test_suit_begin() +{ + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, + (UCHAR *)_nx_azure_iot_root_cert, + (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", + g_ip_ptr, g_pool_ptr, g_dns_ptr, + (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), + DEMO_CLOUD_THREAD_PRIORITY, unix_time_get), + NX_AZURE_IOT_SUCCESS); +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_suit_end() +{ + assert_int_equal(nx_azure_iot_delete(&iot), + NX_AZURE_IOT_SUCCESS); +} + +/* Hook executed before every test */ +static VOID test_begin() +{ + reset_global_state(); + + /* Record number of available packet before test */ + g_available_packet = g_pool_ptr -> nx_packet_pool_available; +} + +/* Hook execute after all tests are executed successfully */ +static VOID test_end() +{ + /* Check if all the packet are released */ + assert_int_equal(g_pool_ptr -> nx_packet_pool_available, g_available_packet); +} + +/** + * Test invalid argument failure. + * + **/ +static VOID test_nx_azure_iot_hub_client_invalid_argument_fail() +{ +NX_PACKET *packet_ptr; + + printf("test starts =>: %s\n", __func__); + + /*********** Test nx_azure_iot_hub_client_model_id_set() ***********/ + /* NX_NULL iothub handle */ + assert_int_not_equal(nx_azure_iot_hub_client_model_id_set(NX_NULL, + g_pnp_model_id, sizeof(g_pnp_model_id) - 1), + NX_AZURE_IOT_SUCCESS); + + /* NX_NULL model id pointer */ + assert_int_not_equal(nx_azure_iot_hub_client_model_id_set(&hub_client, + NX_NULL, sizeof(g_pnp_model_id) - 1), + NX_AZURE_IOT_SUCCESS); + + /* 0 model id string length */ + assert_int_not_equal(nx_azure_iot_hub_client_model_id_set(&hub_client, + g_pnp_model_id, 0), + NX_AZURE_IOT_SUCCESS); + + /*********** Test nx_azure_iot_hub_client_component_add() ***********/ + /* NX_NULL iothub handle */ + assert_int_not_equal(nx_azure_iot_hub_client_component_add(NX_NULL, + g_test_component, sizeof(g_test_component) - 1), + NX_AZURE_IOT_SUCCESS); + + /* NX_NULL component pointer */ + assert_int_not_equal(nx_azure_iot_hub_client_component_add(&hub_client, + NX_NULL, sizeof(g_test_component) - 1), + NX_AZURE_IOT_SUCCESS); + + /* 0 model component name length */ + assert_int_not_equal(nx_azure_iot_hub_client_component_add(&hub_client, + g_test_component, 0), + NX_AZURE_IOT_SUCCESS); + + /*********** Test nx_azure_iot_hub_client_telemetry_component_set() ***********/ + /* NX_NULL packet */ + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_component_set(NX_NULL, + g_test_component, sizeof(g_test_component) - 1, + NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* NX_NULL component pointer */ + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_component_set(packet_ptr, + NX_NULL, sizeof(g_test_component) - 1, + NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* 0 component name length */ + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_component_set(packet_ptr, + g_test_component, 0, + NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful pnp connect. + * + **/ +static VOID test_nx_azure_iot_hub_client_connect_success() +{ + printf("test starts =>: %s\n", __func__); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&hub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&hub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); + + /* Set symmetric key credentials */ + assert_int_equal(nx_azure_iot_hub_client_symmetric_key_set(&hub_client, + g_symmetric_key, + sizeof(g_symmetric_key) - 1), + NX_AZURE_IOT_SUCCESS); + + /* Connect IoTHub client */ + will_return(__wrap__nxde_mqtt_client_secure_connect, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_connect(&hub_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&hub_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful pnp connect with cert. + * + **/ +static VOID test_nx_azure_iot_hub_client_connect_with_cert_success() +{ + printf("test starts =>: %s\n", __func__); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&hub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&hub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); + + /* Set certificate */ + assert_int_equal(nx_azure_iot_hub_client_device_cert_set(&hub_client, + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Connect IoTHub client */ + will_return(__wrap__nxde_mqtt_client_secure_connect, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_connect(&hub_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&hub_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful pnp connect with NO_WAIT. + * + **/ +static VOID test_nx_azure_iot_hub_client_connect_async_success() +{ + printf("test starts =>: %s\n", __func__); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&hub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&hub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); + + /* Set certificate */ + assert_int_equal(nx_azure_iot_hub_client_device_cert_set(&hub_client, + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set connect callback */ + assert_int_equal(nx_azure_iot_hub_client_connection_status_callback_set(&hub_client, + connection_status_cb), + NX_AZURE_IOT_SUCCESS); + + /* Connect IoTHub client */ + will_return(__wrap__nxde_mqtt_client_secure_connect, NX_IN_PROGRESS); + assert_int_equal(nx_azure_iot_hub_client_connect(&hub_client, NX_FALSE, NX_NO_WAIT), + NX_AZURE_IOT_CONNECTING); + + assert_non_null(test_connect_notify); + test_connect_notify(&(MQTT_CLIENT_GET(&hub_client)), + NXD_MQTT_SUCCESS, test_connect_notify_context); + + assert_int_equal(g_connect_status, NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&hub_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test failure pnp connect with NO_WAIT. + * + **/ +static VOID test_nx_azure_iot_hub_client_connect_async_fail() +{ + printf("test starts =>: %s\n", __func__); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&hub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&hub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); + + /* Set certificate */ + assert_int_equal(nx_azure_iot_hub_client_device_cert_set(&hub_client, + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set connect callback */ + assert_int_equal(nx_azure_iot_hub_client_connection_status_callback_set(&hub_client, + connection_status_cb), + NX_AZURE_IOT_SUCCESS); + + /* Connect IoTHub client */ + will_return(__wrap__nxde_mqtt_client_secure_connect, NX_IN_PROGRESS); + assert_int_equal(nx_azure_iot_hub_client_connect(&hub_client, NX_FALSE, NX_NO_WAIT), + NX_AZURE_IOT_CONNECTING); + + assert_non_null(test_connect_notify); + test_connect_notify(&(MQTT_CLIENT_GET(&hub_client)), + NXD_MQTT_CONNECT_FAILURE, test_connect_notify_context); + + assert_int_equal(g_connect_status, NXD_MQTT_CONNECT_FAILURE); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&hub_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test pnp connect failure with OOM. + * + **/ +static VOID test_nx_azure_iot_hub_client_connect_with_oom_failure() +{ +UINT max_allocation; + + printf("test starts =>: %s\n", __func__); + + /* Set how many allocation required in g_total_allocation. */ + test_nx_azure_iot_hub_client_connect_success(); + max_allocation = g_total_allocation; + + reset_global_state(); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&hub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&hub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); + + /* Set symmetric key credentials */ + assert_int_equal(nx_azure_iot_hub_client_symmetric_key_set(&hub_client, + g_symmetric_key, + sizeof(g_symmetric_key) - 1), + NX_AZURE_IOT_SUCCESS); + + for (UINT index = 0; index < max_allocation; index++) + { + g_failed_allocation_index = index; + + /* Connect IoTHub client */ + assert_int_not_equal(nx_azure_iot_hub_client_connect(&hub_client, NX_FALSE, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + } + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&hub_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful pnp disconnect. + * + **/ +static VOID test_nx_azure_iot_hub_client_disconnect_success() +{ + printf("test starts =>: %s\n", __func__); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&hub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&hub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); + + /* Set connect callback */ + assert_int_equal(nx_azure_iot_hub_client_connection_status_callback_set(&hub_client, + connection_status_cb), + NX_AZURE_IOT_SUCCESS); + + /* Connect IoTHub client */ + will_return(__wrap__nxde_mqtt_client_secure_connect, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_connect(&hub_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_disconnect(&hub_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&hub_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful telemetry send. + * + **/ +static VOID test_nx_azure_iot_hub_client_telemetry_send_success() +{ +NX_PACKET *packet_ptr; +UINT round = 0; + + printf("test starts =>: %s\n", __func__); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&hub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&hub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); + + /* Connect IoTHub client */ + will_return(__wrap__nxde_mqtt_client_secure_connect, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_connect(&hub_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + will_return(__wrap__nx_tcp_socket_send, NX_SUCCESS); + + while (NX_TRUE) + { + g_failed_append_index = g_total_append + round++; + if (nx_azure_iot_hub_client_telemetry_message_create(&hub_client, + &packet_ptr, NX_NO_WAIT)) + { + printf("Message creation failed\r\n"); + } + else if (nx_azure_iot_hub_client_telemetry_component_set(packet_ptr, + STRING_UNSIGNED_ARGS(g_test_component), + NX_NO_WAIT)) + { + nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr); + printf("Add property failed\r\n"); + } + else if (nx_azure_iot_hub_client_telemetry_property_add(packet_ptr, + STRING_UNSIGNED_ARGS(g_test_property_name), + STRING_UNSIGNED_ARGS(g_test_property_value), + NX_NO_WAIT)) + { + nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr); + printf("Add property failed\r\n"); + } + else if (nx_azure_iot_hub_client_telemetry_send(&hub_client, + packet_ptr, + STRING_UNSIGNED_ARGS(g_test_telemetry_data), + NX_NO_WAIT)) + { + nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr); + printf("Send telemetry failed \r\n"); + } + else + { + break; + } + } + + assert_int_equal(nx_azure_iot_hub_client_disconnect(&hub_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&hub_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test successful telemetry send extended. + * + **/ +static VOID test_nx_azure_iot_hub_client_telemetry_send_extended_success() +{ +NX_PACKET *packet_ptr; +UINT round = 0; +USHORT packet_id; + + printf("test starts =>: %s\n", __func__); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&hub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&hub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); + + /* Set telemetry ack callback. */ + assert_int_equal(nx_azure_iot_hub_client_telemetry_ack_callback_set(&hub_client, + telemetry_ack_callback), + NX_AZURE_IOT_SUCCESS); + + /* Connect IoTHub client */ + will_return(__wrap__nxde_mqtt_client_secure_connect, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_connect(&hub_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + will_return(__wrap__nx_tcp_socket_send, NX_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_create(&hub_client, &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_telemetry_send_extended(&hub_client, + packet_ptr, + STRING_UNSIGNED_ARGS(g_test_telemetry_data), + &packet_id, + NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Inject the telemetry puback message. */ + generate_test_telemetry_ack(&hub_client, packet_id); + + /* Sleep 1 second. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + assert_int_not_equal(g_telemetry_ack_count, 0); + + assert_int_equal(nx_azure_iot_hub_client_disconnect(&hub_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&hub_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test telemetry send publish failure. + * + **/ +static VOID test_nx_azure_iot_hub_client_telemetry_send_fail() +{ +NX_PACKET *packet_ptr; +UINT round = 0; + + printf("test starts =>: %s\n", __func__); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&hub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Set model id. */ + assert_int_equal(nx_azure_iot_hub_client_model_id_set(&hub_client, + STRING_UNSIGNED_ARGS(g_pnp_model_id)), + NX_AZURE_IOT_SUCCESS); + + /* Connect IoTHub client */ + will_return(__wrap__nxde_mqtt_client_secure_connect, NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_connect(&hub_client, NX_FALSE, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_create(&hub_client, + &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_telemetry_component_set(packet_ptr, + STRING_UNSIGNED_ARGS(g_test_component), + NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_telemetry_property_add(packet_ptr, + STRING_UNSIGNED_ARGS(g_test_property_name), + STRING_UNSIGNED_ARGS(g_test_property_value), + NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + will_return(__wrap__nx_tcp_socket_send, NX_AZURE_IOT_FAILURE); + assert_int_not_equal(nx_azure_iot_hub_client_telemetry_send(&hub_client, + packet_ptr, + STRING_UNSIGNED_ARGS(g_test_telemetry_data), + NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr), NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_disconnect(&hub_client), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&hub_client), + NX_AZURE_IOT_SUCCESS); +} + +/** + * Test telemetry send publish failure with mutex. + * + **/ +static VOID test_nx_azure_iot_hub_client_telemetry_send_fail_mutex() +{ +NX_PACKET *packet_ptr; + + printf("test starts =>: %s\n", __func__); + + /* Initialize azure iot handle. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&hub_client, &iot, + STRING_UNSIGNED_ARGS(g_hostname), + STRING_UNSIGNED_ARGS(g_device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_create(&hub_client, + &packet_ptr, NX_NO_WAIT), + NX_AZURE_IOT_SUCCESS); + + /* Return NX_AZURE_IOT_DISCONNECTED as the connection is not established. */ + assert_int_equal(nx_azure_iot_hub_client_telemetry_send(&hub_client, + packet_ptr, + STRING_UNSIGNED_ARGS(g_test_telemetry_data), + NX_NO_WAIT), + NX_AZURE_IOT_DISCONNECTED); + + /* Release the packet. */ + assert_int_equal(nx_azure_iot_hub_client_telemetry_message_delete(packet_ptr), NX_AZURE_IOT_SUCCESS); + + /* Check if the mutex is released correctly before return. */ + assert_int_equal(hub_client.nx_azure_iot_ptr -> nx_azure_iot_mutex_ptr -> tx_mutex_ownership_count, 0); + + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&hub_client), + NX_AZURE_IOT_SUCCESS); +} + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ + NX_AZURE_TEST_FN tests[] = {test_nx_azure_iot_hub_client_invalid_argument_fail, + test_nx_azure_iot_hub_client_connect_success, + test_nx_azure_iot_hub_client_connect_with_cert_success, + test_nx_azure_iot_hub_client_connect_async_success, + test_nx_azure_iot_hub_client_connect_async_fail, + test_nx_azure_iot_hub_client_connect_with_oom_failure, + test_nx_azure_iot_hub_client_disconnect_success, + test_nx_azure_iot_hub_client_telemetry_send_success, + test_nx_azure_iot_hub_client_telemetry_send_extended_success, + test_nx_azure_iot_hub_client_telemetry_send_fail, + test_nx_azure_iot_hub_client_telemetry_send_fail_mutex + }; + INT number_of_tests = sizeof(tests)/sizeof(tests[0]); + g_ip_ptr = ip_ptr; + g_pool_ptr = pool_ptr; + g_dns_ptr = dns_ptr; + + test_suit_begin(); + + printf("Number of tests %d\r\n", number_of_tests); + for (INT index = 0; index < number_of_tests; index++) + { + test_begin(); + tests[index](); + test_end(); + } + + test_suit_end(); +} diff --git a/test/regression/azure_iot/nx_azure_iot_unit_test.c b/test/regression/azure_iot/nx_azure_iot_unit_test.c new file mode 100644 index 00000000..e9231935 --- /dev/null +++ b/test/regression/azure_iot/nx_azure_iot_unit_test.c @@ -0,0 +1,298 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot.h" +#include "nx_azure_iot_ciphersuites.h" +#include "nx_crypto_aes.h" +#include "nx_websocket_client.h" + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + +#ifndef MAX_BUFFER_SIZE +#define MAX_BUFFER_SIZE 1500 +#endif /* MAX_BUFFER_SIZE */ + +typedef VOID (*NX_AZURE_TEST_FN)(); + +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static UCHAR buffer[MAX_BUFFER_SIZE] = { 0 }; + +static CHAR *g_url_encoded_hmac_sha256_data_set[][3] = { +{ "De1TOYsqBULq0nSzjVWvjCYUnQ3pklTuUdmoLsleyaw=", + "0ne000A247E/registrations/test1\n1587103748", + "mU63otlyFYT+ATVO9mM0g81c3CQ5fmr0DrviGG2wX0Q=" }, +{ "j07p2UdpIZn/Y+WvdCf8j3KVio2PqOAc55f3aERGtUE=", + "0ne000A247E/registrations/test1\n1587103748", + "/kZa770GiwCyGVtcPL0KoCRAKqeF2NxXWUrhB4pkOSQ=" }, +{ "j07p2UdpIZn/Y+WvdCf8j3KVio2PqOAc55f3aERGtUE=", + "0ne000A247E/registrations/test4\n1587103748", + "3Iv4Y9dPmTc24ETg/5wr2AZ66s10sGig6mah93R6IB4=" } +}; +static UINT log_index = 0; + +static VOID test_log_reset() +{ + log_index = 0; + memset(buffer, 0, sizeof(buffer)); +} + +static VOID test_log_callback(az_log_classification classification, UCHAR *msg, UINT msg_len) +{ + if ((classification == AZ_LOG_IOT_AZURERTOS) && ((log_index + msg_len) <= MAX_BUFFER_SIZE)) + { + memcpy((VOID *)(buffer + log_index), (VOID *)msg, msg_len); + log_index += msg_len; + } +} + +/** + * Test base64 decoding + * + **/ +static VOID test_nx_azure_iot_url_encoded_hmac_sha256_calculate_success() +{ +UCHAR *output_ptr; +UINT output_len; +UINT status; +INT number_of_data_set = sizeof(g_url_encoded_hmac_sha256_data_set)/sizeof(g_url_encoded_hmac_sha256_data_set[0]); +NX_AZURE_IOT_RESOURCE resource; + + printf("test starts =>: %s\n", __func__); + + resource.resource_crypto_array = _nx_azure_iot_tls_supported_crypto; + resource.resource_crypto_array_size = _nx_azure_iot_tls_supported_crypto_size; + resource.resource_cipher_map = _nx_azure_iot_tls_ciphersuite_map; + resource.resource_cipher_map_size = _nx_azure_iot_tls_ciphersuite_map_size; + resource.resource_metadata_ptr = metadata_buffer; + resource.resource_metadata_size = sizeof(metadata_buffer); + + for (INT index = 0; index < number_of_data_set; index++) + { + status = nx_azure_iot_base64_hmac_sha256_calculate(&resource, + g_url_encoded_hmac_sha256_data_set[index][0], + strlen(g_url_encoded_hmac_sha256_data_set[index][0]), + g_url_encoded_hmac_sha256_data_set[index][1], + strlen(g_url_encoded_hmac_sha256_data_set[index][1]), + buffer, sizeof(buffer), &output_ptr, &output_len); + assert_int_equal(status, NX_AZURE_IOT_SUCCESS); + assert_memory_equal(g_url_encoded_hmac_sha256_data_set[index][2], output_ptr, + strlen(g_url_encoded_hmac_sha256_data_set[index][2])); + } +} + +/** + * Test function nx_azure_iot_publish_packet_get + * + **/ +extern NX_CRYPTO_METHOD crypto_method_tls_prf_sha256; +static NXD_MQTT_CLIENT mqtt_client; +static NX_SECURE_TLS_CIPHERSUITE_INFO test_ciphersuite = {TLS_NULL_WITH_NULL_NULL, NX_NULL, NX_NULL, NX_NULL, 0, 0, NX_NULL, 0, NX_NULL}; +static NX_CRYPTO_METHOD session_method; +static NX_SECURE_TLS_CRYPTO test_crypto_table = +{ + /* Ciphersuite lookup table and size. */ + &test_ciphersuite, + 1, +#ifndef NX_SECURE_DISABLE_X509 + /* X.509 certificate cipher table and size. */ + NX_NULL, + 0, +#endif + /* TLS version-specific methods. */ +#if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED) + NX_NULL, + NX_NULL, + &crypto_method_tls_prf_1, +#endif + +#if (NX_SECURE_TLS_TLS_1_2_ENABLED) + NX_NULL, + &crypto_method_tls_prf_sha256, +#endif + +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + &crypto_method_hkdf, + &crypto_method_hmac, + &crypto_method_ecdhe, +#endif +}; + +static VOID test_nx_azure_iot_publish_packet_get() +{ +NX_AZURE_IOT *nx_azure_iot_ptr; +NX_PACKET *packet_ptr; + + + /* ---- Test preparation ---- */ + mqtt_client.nxd_mqtt_client_ip_ptr = &ip_0; + mqtt_client.nxd_mqtt_client_packet_pool_ptr = &pool_0; + mqtt_client.nxd_mqtt_client_use_websocket = NX_FALSE; + mqtt_client.nxd_mqtt_client_use_tls = NX_FALSE; + mqtt_client.nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID; + mqtt_client.nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &(mqtt_client.nxd_mqtt_client_socket); + mqtt_client.nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_TRUE; + mqtt_client.nxd_mqtt_tls_session.nx_secure_tls_session_ciphersuite = &test_ciphersuite; + mqtt_client.nxd_mqtt_tls_session.nx_secure_tls_crypto_table = &test_crypto_table; + test_ciphersuite.nx_secure_tls_session_cipher = &session_method; + session_method.nx_crypto_algorithm = NX_CRYPTO_ENCRYPTION_AES_CBC; + session_method.nx_crypto_IV_size_in_bits = NX_CRYPTO_AES_IV_LEN_IN_BITS; + mqtt_client.nxd_mqtt_tls_session.nx_secure_tls_protocol_version = NX_SECURE_TLS_VERSION_TLS_1_2; + assert_int_equal(nx_tcp_socket_create(mqtt_client.nxd_mqtt_client_ip_ptr, &(mqtt_client.nxd_mqtt_client_socket), "test_client", + NX_IP_NORMAL, NX_DONT_FRAGMENT, 0x80, NXD_MQTT_CLIENT_SOCKET_WINDOW_SIZE, NX_NULL, NX_NULL), + NX_SUCCESS); + + /* Test 1: websocket disabled, tls disabled, use ipv4. */ + mqtt_client.nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + assert_int_equal(nx_azure_iot_publish_packet_get(NX_NULL, &mqtt_client, &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + assert_true(packet_ptr -> nx_packet_data_start == (packet_ptr -> nx_packet_prepend_ptr - + NX_AZURE_IOT_PUBLISH_PACKET_START_OFFSET - + NX_IPv4_TCP_PACKET)); + nx_packet_release(packet_ptr); + + /* Test 2: websocket disabled, tls disabled, use ipv6. */ + mqtt_client.nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V6; + assert_int_equal(nx_azure_iot_publish_packet_get(NX_NULL, &mqtt_client, &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + assert_true(packet_ptr -> nx_packet_data_start == (packet_ptr -> nx_packet_prepend_ptr - + NX_AZURE_IOT_PUBLISH_PACKET_START_OFFSET - + NX_IPv6_TCP_PACKET)); + nx_packet_release(packet_ptr); + + /* Test 3: websocket disabled, tls enabled, use ipv4. */ + mqtt_client.nxd_mqtt_client_use_tls = NX_TRUE; + mqtt_client.nxd_mqtt_tls_session.nx_secure_tls_tcp_socket -> nx_tcp_socket_state = NX_TCP_ESTABLISHED; + mqtt_client.nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + assert_int_equal(nx_azure_iot_publish_packet_get(NX_NULL, &mqtt_client, &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + assert_true(packet_ptr -> nx_packet_data_start == (packet_ptr -> nx_packet_prepend_ptr - + NX_AZURE_IOT_PUBLISH_PACKET_START_OFFSET - + NX_SECURE_TLS_RECORD_HEADER_SIZE - (NX_CRYPTO_AES_IV_LEN_IN_BITS >> 3) - + NX_IPv4_TCP_PACKET)); + nx_packet_release(packet_ptr); + + /* Test 4: websocket disabled, tls enabled, use ipv6. */ + mqtt_client.nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V6; + assert_int_equal(nx_azure_iot_publish_packet_get(NX_NULL, &mqtt_client, &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + assert_true(packet_ptr -> nx_packet_data_start == (packet_ptr -> nx_packet_prepend_ptr - + NX_AZURE_IOT_PUBLISH_PACKET_START_OFFSET - + NX_SECURE_TLS_RECORD_HEADER_SIZE - (NX_CRYPTO_AES_IV_LEN_IN_BITS >> 3) - + NX_IPv6_TCP_PACKET)); + nx_packet_release(packet_ptr); + + /* ---- Disable TLS again, and then enable websocket ---- */ + mqtt_client.nxd_mqtt_client_use_tls = NX_FALSE; + mqtt_client.nxd_mqtt_client_use_websocket = NX_TRUE; + assert_int_equal(nx_websocket_client_create(&mqtt_client.nxd_mqtt_client_websocket, "Test websocket client", &ip_0, &pool_0), + NX_SUCCESS); + mqtt_client.nxd_mqtt_client_websocket.nx_websocket_client_socket_ptr = &(mqtt_client.nxd_mqtt_client_socket); + + /* Test 5: websocket enabled, tls disabled, use ipv4. */ + mqtt_client.nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + assert_int_equal(nx_azure_iot_publish_packet_get(NX_NULL, &mqtt_client, &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + assert_true(packet_ptr -> nx_packet_data_start == (packet_ptr -> nx_packet_prepend_ptr - + NX_AZURE_IOT_PUBLISH_PACKET_START_OFFSET - + NX_WEBSOCKET_HEADER_SIZE - + NX_IPv4_TCP_PACKET)); + nx_packet_release(packet_ptr); + + /* Test 6: websocket enabled, tls disabled, use ipv6. */ + mqtt_client.nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V6; + assert_int_equal(nx_azure_iot_publish_packet_get(NX_NULL, &mqtt_client, &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + assert_true(packet_ptr -> nx_packet_data_start == (packet_ptr -> nx_packet_prepend_ptr - + NX_AZURE_IOT_PUBLISH_PACKET_START_OFFSET - + NX_WEBSOCKET_HEADER_SIZE - + NX_IPv6_TCP_PACKET)); + nx_packet_release(packet_ptr); + + /* Test 7: websocket enabled, tls enabled, use ipv4. */ + mqtt_client.nxd_mqtt_client_use_tls = NX_TRUE; + mqtt_client.nxd_mqtt_client_websocket.nx_websocket_client_use_tls = NX_TRUE; + mqtt_client.nxd_mqtt_client_websocket.nx_websocket_client_tls_session_ptr = &(mqtt_client.nxd_mqtt_tls_session); + mqtt_client.nxd_mqtt_tls_session.nx_secure_tls_tcp_socket -> nx_tcp_socket_state = NX_TCP_ESTABLISHED; + mqtt_client.nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + assert_int_equal(nx_azure_iot_publish_packet_get(NX_NULL, &mqtt_client, &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + assert_true(packet_ptr -> nx_packet_data_start == (packet_ptr -> nx_packet_prepend_ptr - + NX_AZURE_IOT_PUBLISH_PACKET_START_OFFSET - + NX_WEBSOCKET_HEADER_SIZE - + NX_SECURE_TLS_RECORD_HEADER_SIZE - (NX_CRYPTO_AES_IV_LEN_IN_BITS >> 3) - + NX_IPv4_TCP_PACKET)); + nx_packet_release(packet_ptr); + + /* Test 8: websocket enabled, tls enabled, use ipv6. */ + mqtt_client.nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V6; + assert_int_equal(nx_azure_iot_publish_packet_get(NX_NULL, &mqtt_client, &packet_ptr, NX_WAIT_FOREVER), + NX_AZURE_IOT_SUCCESS); + assert_true(packet_ptr -> nx_packet_data_start == (packet_ptr -> nx_packet_prepend_ptr - + NX_AZURE_IOT_PUBLISH_PACKET_START_OFFSET - + NX_WEBSOCKET_HEADER_SIZE - + NX_SECURE_TLS_RECORD_HEADER_SIZE - (NX_CRYPTO_AES_IV_LEN_IN_BITS >> 3) - + NX_IPv6_TCP_PACKET)); + nx_packet_release(packet_ptr); +} + +/** + * Test logging + * + **/ +static VOID test_nx_azure_iot_log_success() +{ +static const CHAR log_message_ptr[] = "[INFO] hello world 1"; + + nx_azure_iot_log_init(test_log_callback); + +#ifndef AZ_NO_LOGGING + test_log_reset(); + nx_azure_iot_log(LogLiteralArgs("[INFO]"), LogLiteralArgs(" hello world 1")); + assert_memory_equal(log_message_ptr, buffer, sizeof(log_message_ptr) - 1); + + test_log_reset(); + nx_azure_iot_log(LogLiteralArgs("[INFO]"), LogLiteralArgs(" hello world %d"), 1); + assert_memory_equal(log_message_ptr, buffer, sizeof(log_message_ptr) - 1); + + test_log_reset(); + nx_azure_iot_log(LogLiteralArgs("[INFO]"), LogLiteralArgs(" hello %s"), LogLiteralArgs("world 1")); + assert_memory_equal(log_message_ptr, buffer, sizeof(log_message_ptr) - 1); +#endif /* AZ_NO_LOGGING */ +} + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ +NX_AZURE_TEST_FN tests[] = { test_nx_azure_iot_url_encoded_hmac_sha256_calculate_success, + test_nx_azure_iot_publish_packet_get, + test_nx_azure_iot_log_success }; +INT number_of_tests = sizeof(tests)/sizeof(tests[0]); + + printf("Number of tests %d\r\n", number_of_tests); + for (INT index = 0; index < number_of_tests; index++) + { + tests[index](); + } +} diff --git a/test/regression/azure_iot/trusted_cert_unit_test.c b/test/regression/azure_iot/trusted_cert_unit_test.c new file mode 100644 index 00000000..5dd9b25d --- /dev/null +++ b/test/regression/azure_iot/trusted_cert_unit_test.c @@ -0,0 +1,170 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" +#include "nx_azure_iot_provisioning_client.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_AZURE_IOT_PROVISIONING_CLIENT iot_prov_client; +static NX_SECURE_X509_CERT root_ca_cert; +static NX_SECURE_X509_CERT root_ca_cert_2; +static NX_SECURE_X509_CERT root_ca_cert_3; +static NX_SECURE_X509_CERT root_ca_cert_4; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +static NX_PACKET *allocated_packets[256]; +static UCHAR large_property_name[2048]; +static ULONG small_pool_stack[1024 >> 2]; +static NX_PACKET_POOL small_pool; +extern int g_argc; +extern char **g_argv; + +CHAR *expected_topic = ""; +CHAR *expected_message = ""; + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ +CHAR *host_name = "host_name"; +CHAR *device_id = "device_id"; +CHAR *module_id = "module_id"; +CHAR *endpoint = "host_name"; +CHAR *id_scope = "id_scope"; +CHAR *reg_id = "reg_id"; + + assert_int_equal(nx_packet_pool_create(&small_pool, "Small Packet Pool", 4, + (UCHAR *)small_pool_stack , sizeof(small_pool_stack)), + NX_AZURE_IOT_SUCCESS); + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert, (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert_2, (UCHAR *)_nx_azure_iot_root_cert_2, (USHORT)_nx_azure_iot_root_cert_size_2, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert_2, (UCHAR *)_nx_azure_iot_root_cert_3, (USHORT)_nx_azure_iot_root_cert_size_3, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* Initialize IoT hub client. */ + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: hub_client_ptr is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_trusted_cert_add(NX_NULL, &root_ca_cert_2), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: trusted_certificate is NULL. */ + assert_int_not_equal(nx_azure_iot_hub_client_trusted_cert_add(&iot_client, NX_NULL), + NX_AZURE_IOT_SUCCESS); + +#if (NX_AZURE_IOT_MAX_NUM_OF_TRUSTED_CERTS == 3) + /* SUCCESS: set trusted certificate again. */ + assert_int_equal(nx_azure_iot_hub_client_trusted_cert_add(&iot_client, &root_ca_cert_2), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_hub_client_trusted_cert_add(&iot_client, &root_ca_cert_3), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: no more entry for trusted cert. */ + assert_int_not_equal(nx_azure_iot_hub_client_trusted_cert_add(&iot_client, &root_ca_cert_4), + NX_AZURE_IOT_SUCCESS); +#endif + + /* Deinitialize IoT hub client. */ + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + + /* Initialize provisioning client. */ + assert_int_equal(nx_azure_iot_provisioning_client_initialize(&iot_prov_client, &iot, + endpoint, sizeof(endpoint) - 1, + id_scope, sizeof(id_scope) - 1, + reg_id, sizeof(reg_id) - 1, + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: iot_prov_client is NULL. */ + assert_int_not_equal(nx_azure_iot_provisioning_client_trusted_cert_add(NX_NULL, &root_ca_cert_2), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: trusted_certificate is NULL. */ + assert_int_not_equal(nx_azure_iot_provisioning_client_trusted_cert_add(&iot_prov_client, NX_NULL), + NX_AZURE_IOT_SUCCESS); + +#if (NX_AZURE_IOT_MAX_NUM_OF_TRUSTED_CERTS == 3) + /* SUCCESS: set trusted certificate again. */ + assert_int_equal(nx_azure_iot_provisioning_client_trusted_cert_add(&iot_prov_client, &root_ca_cert_2), + NX_AZURE_IOT_SUCCESS); + assert_int_equal(nx_azure_iot_provisioning_client_trusted_cert_add(&iot_prov_client, &root_ca_cert_3), + NX_AZURE_IOT_SUCCESS); + + /* FAIL: no more entry for trusted cert. */ + assert_int_not_equal(nx_azure_iot_provisioning_client_trusted_cert_add(&iot_prov_client, &root_ca_cert_4), + NX_AZURE_IOT_SUCCESS); +#endif + + /* Deinitialize IoT provisioning client. */ + assert_int_equal(nx_azure_iot_provisioning_client_deinitialize(&iot_prov_client), + NX_AZURE_IOT_SUCCESS); + + + /* SUCCESS: iot is deleted. */ + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); +} + diff --git a/test/regression/azure_iot/user_agent_string_unit_test.c b/test/regression/azure_iot/user_agent_string_unit_test.c new file mode 100644 index 00000000..daab8083 --- /dev/null +++ b/test/regression/azure_iot/user_agent_string_unit_test.c @@ -0,0 +1,308 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +#include +#include +#include /* macros: https://api.cmocka.org/group__cmocka__asserts.html */ + +#include "nx_api.h" +#include "nx_azure_iot_hub_client.h" +#include "nx_azure_iot_cert.h" +#include "nx_azure_iot_ciphersuites.h" + + +#define DEMO_DHCP_DISABLE +#define DEMO_IPV4_ADDRESS IP_ADDRESS(192, 168, 100, 33) +#define DEMO_IPV4_MASK 0xFFFFFF00UL +#define DEMO_GATEWAY_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define DEMO_DNS_SERVER_ADDRESS IP_ADDRESS(192, 168, 100, 1) +#define NETWORK_DRIVER _nx_ram_network_driver + +/* Include main.c in the test case since we need to disable DHCP in this test. */ +#include "main.c" + + +#define STRING_UNSIGNED_ARGS(s) (UCHAR *)s, strlen(s) + +#ifndef DEMO_CLOUD_STACK_SIZE +#define DEMO_CLOUD_STACK_SIZE 2048 +#endif /* DEMO_CLOUD_STACK_SIZE */ + +#ifndef DEMO_CLOUD_THREAD_PRIORITY +#define DEMO_CLOUD_THREAD_PRIORITY (4) +#endif /* DEMO_CLOUD_THREAD_PRIORITY */ + +static UINT interface_type_check(ULONG interface_type); +static UINT deplete_packets(NX_PACKET_POOL *pool_ptr, UINT remaining_packets); +static VOID release_packets(NX_PACKET_POOL *pool_ptr, UINT count); + +static NX_AZURE_IOT iot; +static NX_AZURE_IOT_HUB_CLIENT iot_client; +static NX_SECURE_X509_CERT root_ca_cert; +static UCHAR metadata_buffer[NX_AZURE_IOT_TLS_METADATA_BUFFER_SIZE]; +static ULONG demo_cloud_thread_stack[DEMO_CLOUD_STACK_SIZE / sizeof(ULONG)]; +static NX_PACKET *allocated_packets[256]; +static UCHAR large_property_name[2048]; +static ULONG small_pool_stack[1024 >> 2]; +static NX_PACKET_POOL small_pool; +extern int g_argc; +extern char **g_argv; + +ULONG g_interface_type = 0; + +VOID demo_entry(NX_IP* ip_ptr, NX_PACKET_POOL* pool_ptr, NX_DNS* dns_ptr, UINT (*unix_time_callback)(ULONG *unix_time)) +{ +CHAR *host_name = "host_name"; +CHAR *device_id = "device_id"; +CHAR *module_id = "module_id"; +CHAR *symmetric_key = "symmetric_key"; +CHAR property_name[] = "property_name"; +CHAR property_value[] = "property_value"; +NX_PACKET *packet_ptr; +UINT count; +ULONG pool_ptr_available_packet; +ULONG small_pool_available_packet; + + assert_int_equal(nx_packet_pool_create(&small_pool, "Small Packet Pool", 4, + (UCHAR *)small_pool_stack , sizeof(small_pool_stack)), + NX_AZURE_IOT_SUCCESS); + + /* Initialize root certificate. */ + assert_int_equal(nx_secure_x509_certificate_initialize(&root_ca_cert, (UCHAR *)_nx_azure_iot_root_cert, (USHORT)_nx_azure_iot_root_cert_size, + NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE), + NX_AZURE_IOT_SUCCESS); + + assert_int_equal(nx_azure_iot_create(&iot, (UCHAR *)"Azure IoT", ip_ptr, pool_ptr, dns_ptr, (UCHAR *)demo_cloud_thread_stack, + sizeof(demo_cloud_thread_stack), DEMO_CLOUD_THREAD_PRIORITY, unix_time_callback), + NX_AZURE_IOT_SUCCESS); + + /* Record number of available packet before test */ + pool_ptr_available_packet = pool_ptr -> nx_packet_pool_available; + small_pool_available_packet = small_pool.nx_packet_pool_available; + + assert_int_equal(nx_azure_iot_hub_client_initialize(&iot_client, &iot, + STRING_UNSIGNED_ARGS(host_name), + STRING_UNSIGNED_ARGS(device_id), + STRING_UNSIGNED_ARGS(""), + _nx_azure_iot_tls_supported_crypto, + _nx_azure_iot_tls_supported_crypto_size, + _nx_azure_iot_tls_ciphersuite_map, + _nx_azure_iot_tls_ciphersuite_map_size, + metadata_buffer, sizeof(metadata_buffer), + &root_ca_cert), + NX_AZURE_IOT_SUCCESS); + + /* Fail to set the type. */ + g_interface_type = NX_INTERFACE_TYPE_UNKNOWN; + will_return(__wrap__nxe_ip_driver_interface_direct_command, NX_NOT_SUCCESSFUL); + + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_TRUE, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* The interface type should not be updated. */ + assert_int_equal(interface_type_check(NX_INTERFACE_TYPE_UNKNOWN), NX_AZURE_IOT_SUCCESS); + + nx_azure_iot_hub_client_disconnect(&iot_client); + + /* Set the type as NX_INTERFACE_TYPE_OTHER. */ + g_interface_type = NX_INTERFACE_TYPE_OTHER; + will_return(__wrap__nxe_ip_driver_interface_direct_command, NX_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_TRUE, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* The interface type should be updated as NX_INTERFACE_TYPE_OTHER. */ + assert_int_equal(interface_type_check(NX_INTERFACE_TYPE_OTHER), NX_AZURE_IOT_SUCCESS); + + nx_azure_iot_hub_client_disconnect(&iot_client); + + /* Set the type as NX_INTERFACE_TYPE_ETHERNET. */ + g_interface_type = NX_INTERFACE_TYPE_ETHERNET; + will_return(__wrap__nxe_ip_driver_interface_direct_command, NX_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_TRUE, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* The interface type should be updated as NX_INTERFACE_TYPE_ETHERNET. */ + assert_int_equal(interface_type_check(NX_INTERFACE_TYPE_ETHERNET), NX_AZURE_IOT_SUCCESS); + + nx_azure_iot_hub_client_disconnect(&iot_client); + + /* Set the type as NX_INTERFACE_TYPE_LORAWAN. */ + g_interface_type = NX_INTERFACE_TYPE_LORAWAN; + will_return(__wrap__nxe_ip_driver_interface_direct_command, NX_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_TRUE, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* The interface type should be updated as NX_INTERFACE_TYPE_LORAWAN. */ + assert_int_equal(interface_type_check(NX_INTERFACE_TYPE_LORAWAN), NX_AZURE_IOT_SUCCESS); + + nx_azure_iot_hub_client_disconnect(&iot_client); + + /* Set the type as NX_INTERFACE_TYPE_MAX - 1. */ + g_interface_type = NX_INTERFACE_TYPE_MAX - 1; + will_return(__wrap__nxe_ip_driver_interface_direct_command, NX_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_TRUE, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* The interface type should be updated as NX_INTERFACE_TYPE_MAX - 1. */ + assert_int_equal(interface_type_check(NX_INTERFACE_TYPE_MAX - 1), NX_AZURE_IOT_SUCCESS); + + nx_azure_iot_hub_client_disconnect(&iot_client); + + /* Set the type as NX_INTERFACE_TYPE_MAX. */ + g_interface_type = NX_INTERFACE_TYPE_MAX; + will_return(__wrap__nxe_ip_driver_interface_direct_command, NX_SUCCESS); + + assert_int_equal(nx_azure_iot_hub_client_connect(&iot_client, NX_TRUE, NX_IP_PERIODIC_RATE), + NX_AZURE_IOT_SUCCESS); + + /* The interface type should be updated as NX_INTERFACE_TYPE_OTHER. */ + assert_int_equal(interface_type_check(NX_INTERFACE_TYPE_OTHER), NX_AZURE_IOT_SUCCESS); + + nx_azure_iot_hub_client_disconnect(&iot_client); + + iot_client.nx_azure_iot_hub_client_resource.resource_mqtt.nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + assert_int_equal(nx_azure_iot_hub_client_deinitialize(&iot_client), + NX_AZURE_IOT_SUCCESS); + + /* Check if all the packet are released */ + assert_int_equal(pool_ptr -> nx_packet_pool_available, pool_ptr_available_packet); + assert_int_equal(small_pool.nx_packet_pool_available, small_pool_available_packet); + + /* SUCCESS: iot is created. */ + assert_int_equal(nx_azure_iot_delete(&iot), NX_AZURE_IOT_SUCCESS); +} + +static UINT interface_type_check(ULONG interface_type) +{ +UINT index; +UCHAR type; + + /* Decode the interface type. */ + for (index = 0; index < (iot_client.iot_hub_client_core._internal.options.user_agent._internal.size - 3); index++) + { + + /* The interface type is after the first semicolon. */ + if ((*(iot_client.iot_hub_client_core._internal.options.user_agent._internal.ptr + index) == '%') && + (*(iot_client.iot_hub_client_core._internal.options.user_agent._internal.ptr + index + 1) == '3') && + (*(iot_client.iot_hub_client_core._internal.options.user_agent._internal.ptr + index + 2) == 'B')) + { + type = *(iot_client.iot_hub_client_core._internal.options.user_agent._internal.ptr + index + 3) - '0'; + if (type == interface_type) + { + return(NX_AZURE_IOT_SUCCESS); + } + else + { + return(NX_AZURE_IOT_FAILURE); + } + } + } + + return(NX_AZURE_IOT_FAILURE); +} + +static UINT deplete_packets(NX_PACKET_POOL *pool_ptr, UINT remaining_packets) +{ +UINT count = 0; + + while (pool_ptr -> nx_packet_pool_available > remaining_packets) + { + nx_packet_allocate(pool_ptr, &allocated_packets[count++], 0, NX_WAIT_FOREVER); + } + return(count); +} + +static VOID release_packets(NX_PACKET_POOL *pool_ptr, UINT count) +{ + while (count != 0) + { + nx_packet_release(allocated_packets[--count]); + } +} + +UINT __wrap__nxe_ip_driver_interface_direct_command(NX_IP *ip_ptr, UINT command, UINT interface_index, ULONG *return_value_ptr) +{ + printf("HIJACKED: %s\n", __func__); + *return_value_ptr = g_interface_type; + return((UINT)mock()); +} + +UINT __wrap__nxde_mqtt_client_secure_connect(NXD_MQTT_CLIENT *client_ptr, NXD_ADDRESS *server_ip, UINT server_port, + UINT (*tls_setup)(NXD_MQTT_CLIENT *client_ptr, NX_SECURE_TLS_SESSION *, + NX_SECURE_X509_CERT *, NX_SECURE_X509_CERT *), + UINT keepalive, UINT clean_session, ULONG timeout) +{ + printf("HIJACKED: %s\n", __func__); + tx_thread_suspend(&(iot.nx_azure_iot_ip_ptr -> nx_ip_thread)); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + client_ptr -> nxd_mqtt_client_packet_identifier = 1; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_id = NX_SECURE_TLS_ID; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_local_session_active = NX_FALSE; + client_ptr -> nxd_mqtt_tls_session.nx_secure_tls_tcp_socket = &client_ptr -> nxd_mqtt_client_socket; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_mqtt_client_disconnect(NXD_MQTT_CLIENT *client_ptr) +{ + printf("HIJACKED: %s\n", __func__); + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE; + client_ptr -> nxd_mqtt_client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + return(NXD_MQTT_SUCCESS); +} + +UINT __wrap__nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, + ULONG wait_option, UINT lookup_type) +{ + printf("HIJACKED: %s\n", __func__); + host_address_ptr -> nxd_ip_version = NX_IP_VERSION_V4; + host_address_ptr -> nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + return(NX_DNS_SUCCESS); +} + +UINT __wrap__nxd_mqtt_client_publish_packet_send(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, + USHORT packet_id, UINT QoS, ULONG wait_option) +{ +UINT topic_name_length; +UINT message_length; +UCHAR *buffer_ptr; +UINT status = (UINT)mock(); + + printf("HIJACKED: %s\n", __func__); + tx_mutex_put(client_ptr -> nxd_mqtt_client_mutex_ptr); + + if (status) + { + return(status); + } + + /* packet ownership taken and released */ + nx_packet_release(packet_ptr); + + return(status); +} + +UINT __wrap_nx_azure_iot_security_module_enable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +} + +UINT __wrap_nx_azure_iot_security_module_disable(NX_AZURE_IOT *nx_azure_iot_ptr) +{ + printf("HIJACKED: %s\n", __func__); + return(NX_AZURE_IOT_SUCCESS); +}