diff --git a/CHANGELOG b/CHANGELOG index 51be285d..63af7529 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,17 @@ +* Wed Sep 9 2020 Accelize v2.5.0 +- NEW: Add support of the asynchronous metering mechanism +- NEW: Include DRM Library settings in requests +- NEW: Support the new data format in the ROM of the DRM Controller +- NEW: Show host and card information when XRT utilities are installed +- NEW: Show CSP information when available +- NEW: Add Ubuntu to the regression suite +- NEW: Support environment variables: ONEPORTAL_URL, ONEPORTAL_CLIENT_ID, ONEPORTAL_CLIENT_SECRET +- NEW: Log file support "append" mode +- NEW: Validate the support of xclRegRead and xclRegWrite for CPP, OpenCL and Py APIs +- FIX: Refactor retry mechanism from API functions +- DOC: Update documentation: thanks to customers for their feedback +- DOC: Add migration page + * Thu Apr 30 2020 Accelize v2.4.1 - FIX: Correct BIST to allow HDK v3.x diff --git a/CMakeLists.txt b/CMakeLists.txt index fa368624..0e47c925 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ cmake_minimum_required(VERSION 3.12) # - Alpha : 1.0.0-alpha.1 # - Beta : 1.0.0-beta.1 # - Release candidate : 1.0.0-rc.1 -set(ACCELIZEDRM_VERSION 2.4.1) +set(ACCELIZEDRM_VERSION 2.5.0-rc.2) ## Define package release number (Number of time this version was packaged) if (NOT CPACK_PACKAGE_RELEASE) @@ -95,13 +95,16 @@ set(CMAKE_CXX_STANDARD 11) add_compile_options(-fvisibility=hidden) if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") # Enable warnings - add_compile_options(-O0 -Wall -Wextra -Wnon-virtual-dtor -Wpedantic -Werror=format-security) + add_compile_options(-Wall -Wextra -Wnon-virtual-dtor -Wpedantic -Werror=format-security) # Optimize for Debugging if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") add_compile_options(-fdebug-prefix-map=${CMAKE_SOURCE_DIR}=.) endif() + # ABI check + add_compile_options(-g -Og) + # Code coverage option(COVERAGE "Activate code coverage" OFF) if(COVERAGE) @@ -150,6 +153,8 @@ set(DRM_CONTROLLER_SDK_SOURCES drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_0_0.cpp drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_0_1.cpp drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_1_0.cpp + drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_2_0.cpp + drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_2_1.cpp ) include_directories(drm_controller_sdk/include) set_source_files_properties(${DRM_CONTROLLER_SDK_SOURCES} PROPERTIES COMPILE_FLAGS "-Wno-unused-parameter") @@ -198,6 +203,7 @@ set(TARGET_SOURCES spdlog/src/color_sinks.cpp spdlog/src/file_sinks.cpp source/ws_client.cpp + source/csp.cpp source/drm_manager.cpp source/utils.cpp source/error.cpp @@ -567,3 +573,14 @@ if(TESTS) endif() endif() endif() + +# uninstall target +if(NOT TARGET uninstall) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + + add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) +endif() diff --git a/README.md b/README.md index bd2c39c8..8769eed8 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,23 @@ [![Build Status](https://dev.azure.com/Accelize/DRM/_apis/build/status/DRM%20Library?branchName=master)](https://dev.azure.com/Accelize/DRM/_build/latest?definitionId=2&branchName=master)[![codecov](https://codecov.io/gh/Accelize/drmlib/branch/master/graph/badge.svg)](https://codecov.io/gh/Accelize/drmlib) +# :closed_lock_with_key: Accelize DRM library : AccelDRM + +The Accelize DRM solution protects FPGA applications. + +The Accelize DRM library operates the DRM from the software side of the +application. + +This library is responsible for activating the DRM, communicating with the +Accelize web service and managing metering sessions. + +This library provides **API** for : +* C +* C++ +* Python + +Interested in Accelize DRM ? Checkout our [Documentation](https://tech.accelize.com/documentation/stable)! + # :key: Accelize licensing solution The Accelize licensing technology is offered in two distinct modes: @@ -36,10 +53,15 @@ More information in our [documentation](https://tech.accelize.com/documentation/ For a quick tour about the Accelize platform integration steps, please watch [this video](https://youtu.be/7cb_ksLTcRk) -# :registered: License +## :heavy_exclamation_mark: Prerequisites + +To access the Accelize Web Service you need an Internet connection which allows +outbound HTTPS connection to Accelize [server](https://master.metering.accelize.com) + +## :registered: License -Please consult the Accelize DRM library [license](LICENSE) +Please consult [license](LICENSE) -# :floppy_disk: Changelog +## :floppy_disk: Changelog Please consult [CHANGELOG](CHANGELOG) diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in new file mode 100644 index 00000000..c2d34d47 --- /dev/null +++ b/cmake_uninstall.cmake.in @@ -0,0 +1,21 @@ +if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") +endif() + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif() + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif() +endforeach() diff --git a/deployment/Dockerfile.j2 b/deployment/Dockerfile.j2 index 52caea11..24fd337f 100644 --- a/deployment/Dockerfile.j2 +++ b/deployment/Dockerfile.j2 @@ -52,6 +52,9 @@ python3 -m pip install -U{% if osName in ("centos", "rhel") and osVersion == "7" flake8 \ pytest \ requests \ + flask \ + python-dateutil \ + pytest-flask \ tox \ wheel diff --git a/deployment/acid b/deployment/acid index d001b4ea..bda61686 160000 --- a/deployment/acid +++ b/deployment/acid @@ -1 +1 @@ -Subproject commit d001b4ea057ffe1573cef5031001a4a40ddd0d4e +Subproject commit bda61686105ed67d2d657d26ec78e7d1a707d958 diff --git a/deployment/acid_drm.py b/deployment/acid_drm.py index 445c5745..c6259381 100644 --- a/deployment/acid_drm.py +++ b/deployment/acid_drm.py @@ -53,7 +53,7 @@ def get_next_package_release(versions_json): return next_release -def publish_packages(pkg_source, versions_json, deb_repo, rpm_repo, +def publish_packages(pkg_source, versions_json, deb_repo, rpm_repo, deb_s3, gpg_private_key, gpg_key_id): """ Publish Accelize DRM library packages. @@ -64,6 +64,7 @@ def publish_packages(pkg_source, versions_json, deb_repo, rpm_repo, number for all versions. deb_repo (str): Path to local DEB repository. rpm_repo (str): Path to local RPM repository. + deb_s3 (str): S3 DEB repository. gpg_private_key (str): Path to GPG key to use to sign packages. gpg_key_id (str): ID of the GPG key to use to sign packages. """ @@ -82,12 +83,20 @@ def publish_packages(pkg_source, versions_json, deb_repo, rpm_repo, component = 'prerelease' if prerelease else 'stable' repo_base_url = "https://tech.accelize.com" + branch = run(("git", "branch", "--show-current"), capture_output=True, check=True) + if prerelease: + assert branch != "master" + assert deb_s3.endswith("deb_prerelease/") + else: + assert branch == "master" + assert deb_s3.endswith("deb/") + deb_conf = { 'Origin': 'Accelize', 'Label': 'Accelize', 'Codename': None, 'Architectures': 'amd64', - 'Components': 'stable prerelease', + 'Components': component, 'Description': 'Accelize DEB repository', 'SignWith': gpg_key_id } diff --git a/deployment/azure-pipelines.yml b/deployment/azure-pipelines.yml index d981f09f..3f30c870 100644 --- a/deployment/azure-pipelines.yml +++ b/deployment/azure-pipelines.yml @@ -69,87 +69,22 @@ stages: meteringServer: prod ${{ if ne(variables['Build.SourceBranch'], 'refs/heads/master') }}: meteringServer: dev + ${{ if startsWith(variables['Build.SourceBranch'], 'refs/tags') }}: + tox_minimum: '-m minimum' + ${{ if not(startsWith(variables['Build.SourceBranch'], 'refs/tags')) }}: + tox_minimum: '' jobs: - # Start agents - - template: agents/start.yml@acid + - template: runTestOnEc2.yml parameters: - jobName: startAgent_AwsF1 - agentDescription: AWS F1 - provider: awsEc2 - instanceType: f1.4xlarge - acidDir: $(Build.SourcesDirectory)/deployment/acid - ansiblePlaybook: $(Build.SourcesDirectory)/deployment/playbook.yml - - # Run tests on agents - - job: runTests_AwsF1 - displayName: Run tests on AWS F1 - dependsOn: startAgent_AwsF1 - pool: - name: Default - demands: # Use previously instantiated agent - - agent.Name -equals $(Build.BuildId) $(Build.DefinitionName) AWS F1 - - steps: - - - script: | - cat << EOF > $(Build.SourcesDirectory)/cred.json - { - "client_id": "$(clientIdAccelizeAcceleratorTest2)", - "client_secret": "$(clientSecretAccelizeAcceleratorTest2)", - - "name__admin__":"Admin_JBL_Regression", - "client_id__admin__":"$(clientIdAdmin)", - "client_secret__admin__":"$(clientSecretAdmin)", - - "client_id__accelize_accelerator_test_01__": - "$(clientIdAccelizeAcceleratorTest1)", - "client_secret__accelize_accelerator_test_01__": - "$(clientSecretAccelizeAcceleratorTest1)", - "email__accelize_accelerator_test_01__": - "$(mailAccelizeAcceleratorTest1)", - - "client_id__accelize_accelerator_test_02__": - "$(clientIdAccelizeAcceleratorTest2)", - "client_secret__accelize_accelerator_test_02__": - "$(clientSecretAccelizeAcceleratorTest2)", - "email__accelize_accelerator_test_02__": - "$(mailAccelizeAcceleratorTest2)", - - "client_id__accelize_accelerator_test_03__": - "$(clientIdAccelizeAcceleratorTest3)", - "client_secret__accelize_accelerator_test_03__": - "$(clientSecretAccelizeAcceleratorTest3)", - "email__accelize_accelerator_test_03__": - "$(mailAccelizeAcceleratorTest3)", - - "client_id__accelize_accelerator_test_04__": - "$(clientIdAccelizeAcceleratorTest4)", - "client_secret__accelize_accelerator_test_04__": - "$(clientSecretAccelizeAcceleratorTest4)", - "email__accelize_accelerator_test_04__": - "$(mailAccelizeAcceleratorTest4)" - } - EOF - displayName: Create Accelize credentials file - - - script: sudo -E tox -p all -e - aws-build-debug,cpp-debug,c-debug,integration-debug,coverage-debug - -- --cred=$(Build.SourcesDirectory)/cred.json --server=$(meteringServer) - displayName: Run tests with Tox - env: - CODECOV_TOKEN: $(codecovToken) - TOX_PARALLEL_NO_SPINNER: 1 - SDK_DIR: /opt/aws_fpga/sdk - - # Stop agents - - template: agents/stop.yml@acid - parameters: - provider: awsEc2 - agentDescription: AWS F1 - acidDir: $(Build.SourcesDirectory)/deployment/acid - dependsOn: runTests_AwsF1 + instance_type: 'f1.4xlarge' + config_list: + - os_distrib: 'centos_7' + tox_extra_option: '-k "not test_abi_compliance" $(tox_minimum)' + - os_distrib: 'ubuntu_18_04' + tox_extra_option: '-k "not test_abi_compliance" $(tox_minimum)' + dependsOn: 'centos_7' - stage: release displayName: Release @@ -341,7 +276,10 @@ stages: variables: # DEB and RPM repositories paths debRepo: /tmp/deb_repo - debS3: s3://accelize/deb/ + ${{ if not(contains(variables['Build.SourceBranch'], '-')) }}: + debS3: s3://accelize/deb/ + ${{ if contains(variables['Build.SourceBranch'], '-') }}: + debS3: s3://accelize/deb_prerelease/ rpmRepo: /tmp/rpm_repo rpmS3: s3://accelize/rpm/ @@ -410,6 +348,7 @@ stages: pkg_source='$(Pipeline.Workspace)', versions_json='$(versionsJson)', deb_repo='$(debRepo)', rpm_repo='$(rpmRepo)', + deb_s3='$(debS3)', gpg_private_key='$(gpgPrivateKey.secureFilePath)', gpg_key_id='$(gpgKeyId)') diff --git a/deployment/runTestOnEc2.yml b/deployment/runTestOnEc2.yml new file mode 100644 index 00000000..5b16ac37 --- /dev/null +++ b/deployment/runTestOnEc2.yml @@ -0,0 +1,98 @@ +--- +# runTestOnEc2.yml + +parameters: + instance_type: 'f1.4xlarge' + config_list: + - os_distrib: 'centos_7' + tox_extra_option: '' + +jobs: +- ${{ each config in parameters.config_list }}: # For each config + # Start AWS agents + - template: agents/start.yml@acid + parameters: + jobName: startAgent_Aws_${{ config.os_distrib }} + agentDescription: AWS with ${{ config.os_distrib }} + provider: awsEc2 + image: ${{ config.os_distrib }} + instanceType: ${{ parameters.instance_type }} + acidDir: $(Build.SourcesDirectory)/deployment/acid + ansiblePlaybook: $(Build.SourcesDirectory)/deployment/playbook.yml + + # Run tests on AWS agent + - job: runTests_Aws_${{ config.os_distrib }} + displayName: Run tests on AWS with ${{ config.os_distrib }} + dependsOn: + - startAgent_Aws_${{ config.os_distrib }} + - ${{ if config.dependsOn }}: + - runTests_Aws_${{ config.dependsOn }} + condition: succeededOrFailed() + pool: + name: Default + demands: # Use previously instantiated agent + - agent.Name -equals $(Build.BuildId) $(Build.DefinitionName) AWS with ${{ config.os_distrib }} + steps: + - script: | + cat << EOF > $(Build.SourcesDirectory)/cred.json + { + "client_id": "$(clientIdAccelizeAcceleratorTest2)", + "client_secret": "$(clientSecretAccelizeAcceleratorTest2)", + + "name__admin__":"Admin_JBL_Regression", + "client_id__admin__":"$(clientIdAdmin)", + "client_secret__admin__":"$(clientSecretAdmin)", + + "client_id__accelize_accelerator_test_01__": + "$(clientIdAccelizeAcceleratorTest1)", + "client_secret__accelize_accelerator_test_01__": + "$(clientSecretAccelizeAcceleratorTest1)", + "email__accelize_accelerator_test_01__": + "$(mailAccelizeAcceleratorTest1)", + + "client_id__accelize_accelerator_test_02__": + "$(clientIdAccelizeAcceleratorTest2)", + "client_secret__accelize_accelerator_test_02__": + "$(clientSecretAccelizeAcceleratorTest2)", + "email__accelize_accelerator_test_02__": + "$(mailAccelizeAcceleratorTest2)", + + "client_id__accelize_accelerator_test_03__": + "$(clientIdAccelizeAcceleratorTest3)", + "client_secret__accelize_accelerator_test_03__": + "$(clientSecretAccelizeAcceleratorTest3)", + "email__accelize_accelerator_test_03__": + "$(mailAccelizeAcceleratorTest3)", + + "client_id__accelize_accelerator_test_04__": + "$(clientIdAccelizeAcceleratorTest4)", + "client_secret__accelize_accelerator_test_04__": + "$(clientSecretAccelizeAcceleratorTest4)", + "email__accelize_accelerator_test_04__": + "$(mailAccelizeAcceleratorTest4)" + } + EOF + displayName: Create Accelize credentials file + + - script: sudo -E tox -p all -e + aws-build-debug,cpp-debug,c-debug,integration-debug,coverage-debug + -- --cred=$(Build.SourcesDirectory)/cred.json --server=$(meteringServer) --artifacts_dir=$(Build.SourcesDirectory)/artifacts ${{ config.tox_extra_option }} -rxs + displayName: Run tests with Tox + env: + CODECOV_TOKEN: $(codecovToken) + TOX_PARALLEL_NO_SPINNER: 1 + SDK_DIR: /opt/aws_fpga/sdk + + - publish: $(Build.SourcesDirectory)/artifacts + artifact: AWS_Artifacts_${{ config.os_distrib }} + displayName: Publish AWS Artifacts for ${{ config.os_distrib }} tests + condition: always() + + # Stop AWS agent + - template: agents/stop.yml@acid + parameters: + jobName: stopAgent_Aws_${{ config.os_distrib }} + provider: awsEc2 + agentDescription: AWS with ${{ config.os_distrib }} + acidDir: $(Build.SourcesDirectory)/deployment/acid + dependsOn: runTests_Aws_${{ config.os_distrib }} diff --git a/doc/drm_hardware_integration.rst b/doc/drm_hardware_integration.rst index 0fafa47c..e3e7960b 100644 --- a/doc/drm_hardware_integration.rst +++ b/doc/drm_hardware_integration.rst @@ -460,6 +460,18 @@ the error codes can help to debug (see error table below). .. image:: _static/behavior.png :target: _static/behavior.png +The `drm_activator_0xVVVVLLLLNNNNVVVV_sim_pkg.(vhdl|sv)` contains parameters used +to tune the simulation configuration and behavior. In particular, it allows you +to use a DRM Controller BFM directly embedded in the DRM Activator to unlock the DRM Activator +without the need for an Internet connection to the Accelize License Web Server. +At the opposite, the BFM can be disabled, especially for co-simulation (using C application +testbench). + +.. warning:: To run a cosimulation, you will need to: + - Disable the BFM + - Set the environment variable `DRM_CONTROLLER_TIMEOUT_IN_MICRO_SECONDS` to + 1000000000 because of the slowness of the simulation execution. + Signals for Debug ----------------- diff --git a/doc/drm_library_installation.rst b/doc/drm_library_installation.rst index 3890bb7d..71e1c4d3 100644 --- a/doc/drm_library_installation.rst +++ b/doc/drm_library_installation.rst @@ -54,13 +54,6 @@ Packages are hosted on the Accelize repository. .. note:: Packages and repositories metadata are signed for security. -Accelize provides *stable* and a *prerelease* channels. - -To install the prerelease channel simply replace ``stable`` by ``prerelease`` in the rest of this document. - -.. warning:: No support is provided for *prerelease* packages. - - Debian, Ubuntu: DEB repository :::::::::::::::::::::::::::::: @@ -445,18 +438,26 @@ To uninstall the Accelize DRM library when installed from sources: cd build -* Finally, uninstall files and directories using the CMake installation manifest +* Finally, uninstall files and directories -.. code-block:: bash + - For DRM library version >= 2.5.0, using the uninstall target: - for file in install_manifest*.txt - do - for name in $(cat $file) - do - sudo rm -f "$name" - sudo rmdir -p --ignore-fail-on-non-empty "$(dirname "$name")" - done - done + .. code-block:: bash + + sudo make uninstall + + - For older version, using the CMake installation manifest: + + .. code-block:: bash + + for file in install_manifest*.txt + do + for name in $(cat $file) + do + sudo rm -f "$name" + sudo rmdir -p --ignore-fail-on-non-empty "$(dirname "$name")" + done + done You may also uninstall packages you have installed to build the Accelize DRM. diff --git a/doc/drm_library_integration.rst b/doc/drm_library_integration.rst index ad66b185..e9b43f70 100644 --- a/doc/drm_library_integration.rst +++ b/doc/drm_library_integration.rst @@ -99,7 +99,7 @@ FPGA C library driver. // Instantiate DrmManager with previously defined functions and // configuration files - DrmManager *drm_manager = NULL; + DrmManager* drm_manager = NULL; int ctx = 0; if ( DrmManager_alloc( @@ -139,7 +139,7 @@ FPGA C library driver. "./cred.json", // Read/write register functions callbacks - [&](uint32_t offset, uint32_t * value) { + [&](uint32_t offset, uint32_t* value) { return fpga_read_register( drm_controller_base_addr + offset, value ); }, diff --git a/doc/drm_migration_description.rst b/doc/drm_migration_description.rst new file mode 100644 index 00000000..dd87a3b3 --- /dev/null +++ b/doc/drm_migration_description.rst @@ -0,0 +1,199 @@ +DRM Migration description +========================= + +DRM API upgrade +--------------- + +From v1.x to 2.x +~~~~~~~~~~~~~~~~ + +.. code-block:: c + :caption: In C + + #include "accelize/drmc.h" + + struct sUserContext user_ctx = ...; // sUserContext is any structure the User may want to create + + MeteringSessionManager* p_drm = NULL; + DRMLibErrorCode retcode; + + // Callbacks implementation + int read_fpga_register_callback( uint32_t register offset, uint32_t* returned data, void* user_p) {...} + int write_fpga_register_callback( uint32_t register offset, uint32_t data to write, void* user_p) {...} + void drm_error_callback( const char* error message, void* user_p ) {...} + + // API Methods + printf( "%s\n", DRMLib_get_version() ); + + MeteringSessionManager_alloc( &p_drm, + "path_to_conf_file", + "path_to_cred_file", + read_fpga_register_callback, + write_fpga_register_callback, + drm_error_callback, + &user_ctx + ); + retcode = MeteringSessionManager_start_session( p_drm ); + retcode = MeteringSessionManager_stop_session( p_drm ); + retcode = MeteringSessionManager_pause_session( p_drm ); + retcode = MeteringSessionManager_resume_session( p_drm ); + retcode = MeteringSessionManager_auto_start_session( p_drm ); + retcode = MeteringSessionManager_dump_drm_hw_report( p_drm ); + retcode = MeteringSessionManager_free( &p_drm ); + + +Shall be replaced by: + +.. code-block:: c + :caption: In C + + #include "accelize/drmc.h" + + struct sUserContext user_ctx = ...; // sUserContext is any structure the User may want to create + + DrmManager* p_drm = NULL; + DRM_ErrorCode retcode; + bool resume_pause_flag = false; // true=enable pause/resume mode, false=disable pause/resume flag + char* json_string = nullptr; + + // Callbacks implementation + int read_fpga_register_callback( uint32_t register offset, uint32_t* returned data, void* user_p) {...} + int write_fpga_register_callback( uint32_t register offset, uint32_t data to write, void* user_p) {...} + void drm_error_callback( const char* error message, void* user_p ) {...} + + // API Methods + printf( "%s\n", DrmManager_getApiVersion() ); + + DRM_ErrorCode DrmManager_alloc( &p_drm, + "path_to_conf_file", + "path_to_cred_file", + read_fpga_register_callback, + write_fpga_register_callback, + drm_error_callback, + &user_ctx + ); + retcode = DrmManager_activate( p_drm, resume_pause_flag ); + retcode = DrmManager_deactivate( p_drm, resume_pause_flag ); + retcode = DrmManager_get_json_string( p_drm, "{\"hw_report\":\"\"}", json_string ); + retcode = DrmManager_free( &p_drm ); + + delete json_string; + + +.. code-block:: c++ + :caption: In C++ + + #include + #include + #include "accelize/drm.h" + + namespace cpp = Accelize::DRMLib; + + struct sUserContext user_ctx = ...; // sUserContext is any structure the User may want to create + + // Callbacks implementation + int read_fpga_register_callback( uint32_t register offset, uint32_t* returned data, void* user_p) {...} + int write_fpga_register_callback( uint32_t register offset, uint32_t data to write, void* user_p) {...} + void drm_error_callback( const char* error message, void* user_p ) {...} + + // API Methods + try { + std::cout << cpp::getVersion() << std::endl; + + cpp::MeteringSessionManager* p_drm = new cpp::MeteringSessionManager( + "path_to_conf_file", + "path_to_cred_file", + [&]( uint32_t offset, uint32_t* value ) { return read_fpga_register_callback( offset, value, &user_ctx ); }, + [&]( uint32_t offset, uint32_t value ) { return write_fpga_register_callback( offset, value, &user_ctx ); }, + [&]( const std::string& msg ) { drm_error_callback( msg.c_str(), &user_ctx ); } + ); + p_drm->start_session(); + p_drm->auto_start_session(); + p_drm->resume_session(); + p_drm->pause_session(); + p_drm->stop_session(); + p_drm->dump_drm_hw_report( std::cout ); + + } catch( const cpp:Exception& e ) { + std::cout << e.what() << std::endl; + } + + +Shall be replaced by: + +.. code-block:: c++ + :caption: In C++ + + #include + #include + #include "accelize/drm.h" + + namespace cpp = Accelize::DRMLib; + + struct sUserContext user_ctx = ...; // sUserContext is any structure the User may want to create + bool resume_pause_flag = false; // true=enable pause/resume mode, false=disable pause/resume flag + char* json_string = nullptr; + + // Callback definition + int read_fpga_register_callback( uint32_t register offset, uint32_t* returned data, void* user_p) {...} + int write_fpga_register_callback( uint32_t register offset, uint32_t data to write, void* user_p) {...} + void drm_error_callback( const char* error message, void* user_p ) {...} + + // API Methods + try { + std::cout << cpp::getApiVersion() << std::endl; + + cpp::DrmManager* p_drm = new cpp::DrmManager( + "path_to_conf_file", + "path_to_cred_file", + [&]( uint32_t offset, uint32_t* value ) { return read_fpga_register_callback( offset, value, &user_ctx ); }, + [&]( uint32_t offset, uint32_t value ) { return write_fpga_register_callback( offset, value, &user_ctx ); }, + [&]( const std::string& msg ) { drm_error_callback( msg.c_str(), &user_ctx ); } + ); + p_drm->activate( resume_pause_flag ); + p_drm->deactivate( resume_pause_flag ); + p_drm->get( cpp::ParameterKey::hw_report ); + + } catch( const cpp:Exception& e ) { + std::cout << e.what() << std::endl; + } + + +For more information about the API in your favorite language, refer to :doc:`drm_library_api`. + + +DRM HDK upgrade +--------------- + +From v2.x to 3.x +~~~~~~~~~~~~~~~~ + +- All files and signals prepended with `lgdn_` have been replaced by `drm_`. +- The DRM Controller and Activator IPs have been wrapped to expose an AXI4-Stream communication channel. + +From v3.x to 4.x +~~~~~~~~~~~~~~~~ + +- `common` folder: + + - in the `common` folder there is now a specific source for xilinx simulator tool. + +- `activator` folder: + + - DRM Activator top-level files (VHDL and Verilog) have been prefixed with 'top_' and have been moved + to the `sim` et `syn` folder for the simulation and synthesis respectively. + - `simu` folder name has been replaced by `sim` and `rtl` has been replace by `core`. + - A DRM Controller BFM has been embedded directly in the Activator simulation model to unlock the IP without + the need for an Internet connection to the Accelize License Web Server. + - `drm_activator_0x1003000b00010001_sim_pkg.(vhdl|sv)` file has been created to configure the simulation + configuration and behavior. Parameters are detailed directly in the file. + - A `constraints.sdc` file has been added in the `core` folder. It is required when `drm_aclk` and `ip_core_aclk` + are different. + +- `controller` folder: + + - RTL source files have been moved to a `rtl` folder and split in 3 different sub-folders: `core` contains + the core of the IP, `sim` and `syn` contains the top level of the Controller IP in VHDL and SystemVerilog for + the simulation and synthesis respectively. Top level files are prefixed with 'top_'. + - `sdaccel` and `vitis` folders has been create: they contains the scirpt and makefile to generate the kernel + for those specific flows. diff --git a/doc/drm_sw_advanced_description.rst b/doc/drm_sw_advanced_description.rst index ca27d9ea..753d6df0 100644 --- a/doc/drm_sw_advanced_description.rst +++ b/doc/drm_sw_advanced_description.rst @@ -104,7 +104,7 @@ custom_field uint32_t Read-write No o mailbox_data string Read-write 32 * mailbox size only for testing, read or write values to Mailbox read-write memory in DRM Controller ws_retry_period_long uint32_t Read-write << license duration read and write the time in seconds before the next request attempt to the Web Server when the time left before timeout is long ws_retry_period_short uint32_t Read-write < ws_retry_period_long read and write the time in seconds before the next request attempt to the Web Server when the time left before timeout is short -ws_request_timeout uint32_t Read-write No read and write the web service request timeout in seconds during which the response is waited +ws_request_timeout uint32_t Read-write >0 read and write the web service request timeout in seconds during which the response is waited log_message_level int32_t Read-write No only for testing, read and write the log level used with log_message parameter to set the message level list_all string Read-only NA list all parameter keys available dump_all string Read-only NA read all parameter key values @@ -118,6 +118,10 @@ hw_report string Read-only NA r trigger_async_callback string Write-only No only for testing, call the asynchronous error callback with the given message log_message string Write-only No only for testing, insert a message with the value as content hdk_compatibility string Read-only NA only for testing, return the lower version of the HDK it is compatible with +health_period uint32_t Read-only >=0 return the current value of the health period. 0 means the asychronous feature is disabled +health_retry uint32_t Read-only >=0 return the current value of the health retry timeout. 0 means there will be no retry +health_retry_sleep uint32_t Read-only >=0 return the current value of the health retry sleep +ws_api_retry_duration uint32_t Read-write >=0 read and write the period of time in seconds during which retries occur on activate and deactivate functions ============================= ======== ============ ====================== ============================================= diff --git a/doc/index.rst b/doc/index.rst index 009df190..5d78fd6d 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -198,6 +198,7 @@ Glossary drm_library_build drm_sw_advanced_description + drm_migration_description .. toctree:: diff --git a/drm_controller_sdk/include/DrmControllerCommon.hpp b/drm_controller_sdk/include/DrmControllerCommon.hpp index 1cee967e..a78fde47 100644 --- a/drm_controller_sdk/include/DrmControllerCommon.hpp +++ b/drm_controller_sdk/include/DrmControllerCommon.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerCommon.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief This header file contains the common definitions * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/drm_controller_sdk/include/DrmControllerDataConverter.hpp b/drm_controller_sdk/include/DrmControllerDataConverter.hpp index ba182df0..f3765df2 100644 --- a/drm_controller_sdk/include/DrmControllerDataConverter.hpp +++ b/drm_controller_sdk/include/DrmControllerDataConverter.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerDataConverter.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerDataConverter provides base functions for data conversion. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/drm_controller_sdk/include/DrmControllerFunctionalityDisabledException.hpp b/drm_controller_sdk/include/DrmControllerFunctionalityDisabledException.hpp index 0a28f9cf..7fc2bc2d 100644 --- a/drm_controller_sdk/include/DrmControllerFunctionalityDisabledException.hpp +++ b/drm_controller_sdk/include/DrmControllerFunctionalityDisabledException.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerFunctionalityDisabledException.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerFunctionalityDisabledException defines procedures * for functionality disabled exceptions reporting, inherihts from std::exception. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/drm_controller_sdk/include/DrmControllerLicenseFileSizeException.hpp b/drm_controller_sdk/include/DrmControllerLicenseFileSizeException.hpp index 52dce96e..a379618d 100644 --- a/drm_controller_sdk/include/DrmControllerLicenseFileSizeException.hpp +++ b/drm_controller_sdk/include/DrmControllerLicenseFileSizeException.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerLicenseFileSizeException.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerLicenseFileSizeException defines procedures * for license file size exceptions reporting, inherihts from std::exception. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/drm_controller_sdk/include/DrmControllerLicenseTimerResetedException.hpp b/drm_controller_sdk/include/DrmControllerLicenseTimerResetedException.hpp index 7a0fb138..fe6d08e6 100644 --- a/drm_controller_sdk/include/DrmControllerLicenseTimerResetedException.hpp +++ b/drm_controller_sdk/include/DrmControllerLicenseTimerResetedException.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerLicenseTimerResetedException.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerLicenseTimerResetedException defines procedures * for time out exceptions reporting, inherihts from std::exception. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/drm_controller_sdk/include/DrmControllerTimeOutException.hpp b/drm_controller_sdk/include/DrmControllerTimeOutException.hpp index 3e3c4acd..5ab25c5b 100644 --- a/drm_controller_sdk/include/DrmControllerTimeOutException.hpp +++ b/drm_controller_sdk/include/DrmControllerTimeOutException.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerTimeOutException.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerTimeOutException defines procedures * for time out exceptions reporting, inherihts from std::exception. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/drm_controller_sdk/include/DrmControllerUnsupportedFeatureException.hpp b/drm_controller_sdk/include/DrmControllerUnsupportedFeatureException.hpp index 2a5176ac..508f9e18 100644 --- a/drm_controller_sdk/include/DrmControllerUnsupportedFeatureException.hpp +++ b/drm_controller_sdk/include/DrmControllerUnsupportedFeatureException.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerUnsupportedFeatureException.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerUnsupportedFeatureException defines procedures * for unsupported feature exceptions reporting, inherihts from std::exception. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/drm_controller_sdk/include/DrmControllerVersion.hpp b/drm_controller_sdk/include/DrmControllerVersion.hpp index 5b89a28d..a1179dea 100644 --- a/drm_controller_sdk/include/DrmControllerVersion.hpp +++ b/drm_controller_sdk/include/DrmControllerVersion.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerVersion.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerVersion defines procedures * for hardware versus SDK versions checks. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/drm_controller_sdk/include/DrmControllerVersionCheckException.hpp b/drm_controller_sdk/include/DrmControllerVersionCheckException.hpp index 94c06840..c123ab76 100644 --- a/drm_controller_sdk/include/DrmControllerVersionCheckException.hpp +++ b/drm_controller_sdk/include/DrmControllerVersionCheckException.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerVersionCheckException.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerVersionCheckException defines procedures * for version check exceptions reporting, inherihts from std::exception. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/drm_controller_sdk/include/HAL/DrmControllerOperations.hpp b/drm_controller_sdk/include/HAL/DrmControllerOperations.hpp index 4c7e1242..4cf446a4 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerOperations.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerOperations.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerOperations.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerOperations is an abstraction level to execute operations. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -89,6 +89,22 @@ namespace DrmControllerLibrary { * \return Returns the error code produced by the read/write register function. **/ unsigned int extractDrmVersion(std::string &drmVersion) const; + + /** extractAdaptiveProportionTestFailures + * \brief Extract the Adaptive Proportion Test Failures of the DRM controller. + * This method will access to the system bus to extract the Adaptive Proportion Test Failures. + * \param[out] adaptiveProportionTestFailures is the value of the Adaptive Proportion Test Failures. + * \return Returns the error code produced by the read/write register function. + **/ + unsigned int extractAdaptiveProportionTestFailures(std::string &adaptiveProportionTestFailures) const; + + /** extractRepetitionCountTestFailures + * \brief Extract the Repetition Count Test Failures of the DRM controller. + * This method will access to the system bus to extract the Repetition Count Test Failures. + * \param[out] repetitionCountTestFailures is the value of the Repetition Count Test Failures. + * \return Returns the error code produced by the read/write register function. + **/ + unsigned int extractRepetitionCountTestFailures(std::string &repetitionCountTestFailures) const; /** extractDna * \brief Extract the dna value. diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegisters.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegisters.hpp index d2d51d78..9d7fb222 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerRegisters.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerRegisters.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegisters.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegisters defines low level procedures * for access to all registers. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,6 +35,8 @@ #include #include #include +#include +#include /** * \namespace DrmControllerLibrary @@ -611,6 +613,28 @@ namespace DrmControllerLibrary { **/ unsigned int waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readSecurityAlertStatusRegister + * \brief Read the status register and get the Security Alert status bit. + * This method will access to the system bus to read the status register. + * \param[out] securityAlert is the value of the status bit Security Alert. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + unsigned int readSecurityAlertStatusRegister(bool &securityAlert) const; + + /** waitSecurityAlertStatusRegister + * \brief Wait Security Alert status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + unsigned int waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -979,6 +1003,42 @@ namespace DrmControllerLibrary { **/ unsigned int writeMailboxFileRegister(const std::vector &readWriteMailboxData, unsigned int &readWriteMailboxWordNumber) const; + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + unsigned int readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const; + + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + unsigned int readAdaptiveProportionTestFailuresRegister(std::string &adaptiveProportionTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + unsigned int readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + unsigned int readRepetitionCountTestFailuresRegister(std::string &repetitionCountTestFailures) const; + /** throwFunctionalityDisabledException * \param[in] expectedStatus is the value of the status to be expected. * \param[in] actualStatus is the value of the status read. diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegistersBase.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegistersBase.hpp index e6fa6c91..47cccf2f 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerRegistersBase.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerRegistersBase.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersBase.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersBase defines low level procedures for registers access. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegistersReport.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegistersReport.hpp index 6cbe7010..7667049e 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerRegistersReport.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerRegistersReport.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersReport.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersReport defines low level procedures for registers reporting. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategyInterface.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategyInterface.hpp index 528740ab..6a9cf669 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategyInterface.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategyInterface.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategyInterface.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategyInterface defines strategy interface for register access. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -604,6 +604,28 @@ namespace DrmControllerLibrary { **/ virtual unsigned int waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const = 0; + /** readSecurityAlertStatusRegister + * \brief Read the status register and get the Security Alert status bit. + * This method will access to the system bus to read the status register. + * \param[out] securityAlert is the value of the status bit Security Alert. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSecurityAlertStatusRegister(bool &securityAlert) const = 0; + + /** waitSecurityAlertStatusRegister + * \brief Wait Security Alert status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const = 0; + + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -785,6 +807,42 @@ namespace DrmControllerLibrary { * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. **/ unsigned int readDrmVersionRegister(std::string &drmVersion) const; + + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const = 0; + + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + unsigned int readAdaptiveProportionTestFailuresRegister(std::string &adaptiveProportionTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const = 0; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + unsigned int readRepetitionCountTestFailuresRegister(std::string &repetitionCountTestFailures) const; /** readLogsRegister * \brief Read the logs register and get the value. @@ -1119,6 +1177,7 @@ namespace DrmControllerLibrary { **/ unsigned int waitErrorRegister(const unsigned int &timeout, const unsigned int &position, const unsigned int &mask, const unsigned char &expected, unsigned char &actual) const; + // private members, functions ... private: @@ -1212,7 +1271,19 @@ namespace DrmControllerLibrary { * \param[in] file is the stream to use for the data print. **/ virtual void printMailBoxFileHwReport(std::ostream &file) const = 0; - + + /** printAdaptiveProportionTestFailures + * \brief Display the value of the Adaptive Proportion Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const = 0; + + /** printRepetitionCountTestFailuresHwReport; + * \brief Display the value of the Repetition Count Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printRepetitionCountTestFailuresHwReport(std::ostream &file) const = 0; + }; // class DrmControllerRegistersStrategyInterface } // namespace DrmControllerLibrary diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_0_0.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_0_0.hpp index 0fda6649..d7546a74 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_0_0.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_0_0.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v3_0_0.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v3_0_0 defines strategy for register access of drm controller v3.0.0. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -576,6 +576,27 @@ namespace DrmControllerLibrary { **/ virtual unsigned int waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readSecurityAlertStatusRegister + * \brief Read the status register and get the Security Alert bit. + * This method will access to the system bus to read the status register. + * \param[out] securityAlert is the value of the status bit Security Alert. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSecurityAlertStatusRegister(bool &securityAlert) const; + + /** waitSecurityAlertgStatusRegister + * \brief Wait Security Alert status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -911,6 +932,24 @@ namespace DrmControllerLibrary { **/ virtual const char* getDrmErrorRegisterMessage(const unsigned char &errorRegister) const; + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const; + // protected members, functions ... protected: @@ -1067,6 +1106,18 @@ namespace DrmControllerLibrary { * \param[in] file is the stream to use for the data print. **/ virtual void printMailBoxFileHwReport(std::ostream &file) const; + + /** printAdaptiveProportionTestFailures + * \brief Display the value of the Adaptive Proportion Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const; + + /** printRepetitionCountTestFailures + * \brief Display the value of the Repetition Count Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printRepetitionCountTestFailuresHwReport(std::ostream &file) const; // number of words per registers const unsigned int mCommandRegisterWordNumber; diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_1_0.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_1_0.hpp index 9ceb8a84..5668600e 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_1_0.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_1_0.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v3_1_0.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v3_1_0 defines strategy for register access of drm controller v3.1.0. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -578,6 +578,27 @@ namespace DrmControllerLibrary { **/ virtual unsigned int waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readSecurityAlertStatusRegister + * \brief Read the status register and get the Security Alert bit. + * This method will access to the system bus to read the status register. + * \param[out] securityAlert is the value of the status bit Security Alert. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSecurityAlertStatusRegister(bool &securityAlert) const; + + /** waitSecurityAlertgStatusRegister + * \brief Wait Security Alert status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -913,6 +934,24 @@ namespace DrmControllerLibrary { **/ virtual const char* getDrmErrorRegisterMessage(const unsigned char &errorRegister) const; + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const; + // protected members, functions ... protected: @@ -1069,6 +1108,19 @@ namespace DrmControllerLibrary { * \param[in] file is the stream to use for the data print. **/ virtual void printMailBoxFileHwReport(std::ostream &file) const; + + /** printAdaptiveProportionTestFailures + * \brief Display the value of the Adaptive Proportion Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const; + + /** printRepetitionCountTestFailures + * \brief Display the value of the Repetition Count Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printRepetitionCountTestFailuresHwReport(std::ostream &file) const; + // number of words per registers const unsigned int mCommandRegisterWordNumber; diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_2_0.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_2_0.hpp index f7c7a73a..0c83177c 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_2_0.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_2_0.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v3_2_0.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v3_2_0 defines strategy for register access of drm controller v3.1.0. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -584,6 +584,27 @@ namespace DrmControllerLibrary { **/ virtual unsigned int waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readSecurityAlertStatusRegister + * \brief Read the status register and get the Security Alert bit. + * This method will access to the system bus to read the status register. + * \param[out] securityAlert is the value of the status bit Security Alert. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSecurityAlertStatusRegister(bool &securityAlert) const; + + /** waitSecurityAlertgStatusRegister + * \brief Wait Security Alert status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -919,6 +940,24 @@ namespace DrmControllerLibrary { **/ virtual const char* getDrmErrorRegisterMessage(const unsigned char &errorRegister) const; + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const; + // protected members, functions ... protected: @@ -1075,6 +1114,18 @@ namespace DrmControllerLibrary { * \param[in] file is the stream to use for the data print. **/ virtual void printMailBoxFileHwReport(std::ostream &file) const; + + /** printAdaptiveProportionTestFailures + * \brief Display the value of the Adaptive Proportion Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const; + + /** printRepetitionCountTestFailures + * \brief Display the value of the Repetition Count Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printRepetitionCountTestFailuresHwReport(std::ostream &file) const; /** getMeteringFileHeader * \brief Get the header of the metering file. diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_2_1.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_2_1.hpp index 4ba98440..402ab1e4 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_2_1.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_2_1.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v3_2_1.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v3_2_1 defines strategy for register access of drm controller v3.2.1. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -584,6 +584,27 @@ namespace DrmControllerLibrary { **/ virtual unsigned int waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readSecurityAlertStatusRegister + * \brief Read the status register and get the Security Alert bit. + * This method will access to the system bus to read the status register. + * \param[out] securityAlert is the value of the status bit Security Alert. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSecurityAlertStatusRegister(bool &securityAlert) const; + + /** waitSecurityAlertgStatusRegister + * \brief Wait Security Alert status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -919,6 +940,24 @@ namespace DrmControllerLibrary { **/ virtual const char* getDrmErrorRegisterMessage(const unsigned char &errorRegister) const; + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const; + // protected members, functions ... protected: @@ -1075,6 +1114,18 @@ namespace DrmControllerLibrary { * \param[in] file is the stream to use for the data print. **/ virtual void printMailBoxFileHwReport(std::ostream &file) const; + + /** printAdaptiveProportionTestFailures + * \brief Display the value of the Adaptive Proportion Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const; + + /** printRepetitionCountTestFailures + * \brief Display the value of the Repetition Count Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printRepetitionCountTestFailuresHwReport(std::ostream &file) const; /** getMeteringFileHeader * \brief Get the header of the metering file. diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_2_2.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_2_2.hpp index 9b483e0d..b80e5bf1 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_2_2.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v3_2_2.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v3_2_2.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v3_2_2 defines strategy for register access of drm controller v3.2.2. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -584,6 +584,27 @@ namespace DrmControllerLibrary { **/ virtual unsigned int waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readSecurityAlertStatusRegister + * \brief Read the status register and get the Security Alert bit. + * This method will access to the system bus to read the status register. + * \param[out] securityAlert is the value of the status bit Security Alert. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSecurityAlertStatusRegister(bool &securityAlert) const; + + /** waitSecurityAlertgStatusRegister + * \brief Wait Security Alert status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -919,6 +940,24 @@ namespace DrmControllerLibrary { **/ virtual const char* getDrmErrorRegisterMessage(const unsigned char &errorRegister) const; + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const; + // protected members, functions ... protected: @@ -1075,6 +1114,18 @@ namespace DrmControllerLibrary { * \param[in] file is the stream to use for the data print. **/ virtual void printMailBoxFileHwReport(std::ostream &file) const; + + /** printAdaptiveProportionTestFailures + * \brief Display the value of the Adaptive Proportion Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const; + + /** printRepetitionCountTestFailures + * \brief Display the value of the Repetition Count Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printRepetitionCountTestFailuresHwReport(std::ostream &file) const; /** getMeteringFileHeader * \brief Get the header of the metering file. diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_0_0.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_0_0.hpp index 81ce1a8d..6288eaec 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_0_0.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_0_0.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v4_0_0.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v4_0_0 defines strategy for register access of drm controller v4.0.0. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -584,6 +584,27 @@ namespace DrmControllerLibrary { **/ virtual unsigned int waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readSecurityAlertStatusRegister + * \brief Read the status register and get the Security Alert bit. + * This method will access to the system bus to read the status register. + * \param[out] securityAlert is the value of the status bit Security Alert. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSecurityAlertStatusRegister(bool &securityAlert) const; + + /** waitSecurityAlertgStatusRegister + * \brief Wait Security Alert status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -919,6 +940,24 @@ namespace DrmControllerLibrary { **/ virtual const char* getDrmErrorRegisterMessage(const unsigned char &errorRegister) const; + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const; + // protected members, functions ... protected: @@ -1075,6 +1114,18 @@ namespace DrmControllerLibrary { * \param[in] file is the stream to use for the data print. **/ virtual void printMailBoxFileHwReport(std::ostream &file) const; + + /** printAdaptiveProportionTestFailures + * \brief Display the value of the Adaptive Proportion Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const; + + /** printRepetitionCountTestFailures + * \brief Display the value of the Repetition Count Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printRepetitionCountTestFailuresHwReport(std::ostream &file) const; /** getMeteringFileHeader * \brief Get the header of the metering file. diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_0_1.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_0_1.hpp index c1c2d0d1..2a53dff7 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_0_1.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_0_1.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v4_0_1.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v4_0_1 defines strategy for register access of drm controller v4.0.1. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -584,6 +584,27 @@ namespace DrmControllerLibrary { **/ virtual unsigned int waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readSecurityAlertStatusRegister + * \brief Read the status register and get the Security Alert bit. + * This method will access to the system bus to read the status register. + * \param[out] securityAlert is the value of the status bit Security Alert. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSecurityAlertStatusRegister(bool &securityAlert) const; + + /** waitSecurityAlertgStatusRegister + * \brief Wait Security Alert status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -919,6 +940,24 @@ namespace DrmControllerLibrary { **/ virtual const char* getDrmErrorRegisterMessage(const unsigned char &errorRegister) const; + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const; + // protected members, functions ... protected: @@ -1075,6 +1114,18 @@ namespace DrmControllerLibrary { * \param[in] file is the stream to use for the data print. **/ virtual void printMailBoxFileHwReport(std::ostream &file) const; + + /** printAdaptiveProportionTestFailures + * \brief Display the value of the Adaptive Proportion Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const; + + /** printRepetitionCountTestFailures + * \brief Display the value of the Repetition Count Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printRepetitionCountTestFailuresHwReport(std::ostream &file) const; /** getMeteringFileHeader * \brief Get the header of the metering file. diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_1_0.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_1_0.hpp index 9ee2c483..83d17784 100644 --- a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_1_0.hpp +++ b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_1_0.hpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v4_1_0.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v4_1_0 defines strategy for register access of drm controller v4.1.0. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -584,6 +584,28 @@ namespace DrmControllerLibrary { **/ virtual unsigned int waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + /** readSecurityAlertStatusRegister + * \brief Read the status register and get the Security Alert bit. + * This method will access to the system bus to read the status register. + * \param[out] securityAlert is the value of the status bit Security Alert. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSecurityAlertStatusRegister(bool &securityAlert) const; + + /** waitSecurityAlertgStatusRegister + * \brief Wait Security Alert status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -919,6 +941,24 @@ namespace DrmControllerLibrary { **/ virtual const char* getDrmErrorRegisterMessage(const unsigned char &errorRegister) const; + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const; + // protected members, functions ... protected: @@ -1075,6 +1115,18 @@ namespace DrmControllerLibrary { * \param[in] file is the stream to use for the data print. **/ virtual void printMailBoxFileHwReport(std::ostream &file) const; + + /** printAdaptiveProportionTestFailures + * \brief Display the value of the Adaptive Proportion Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const; + + /** printRepetitionCountTestFailures + * \brief Display the value of the Repetition Count Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printRepetitionCountTestFailuresHwReport(std::ostream &file) const; /** getMeteringFileHeader * \brief Get the header of the metering file. diff --git a/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_2_0.hpp b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_2_0.hpp new file mode 100644 index 00000000..d391b6fd --- /dev/null +++ b/drm_controller_sdk/include/HAL/DrmControllerRegistersStrategy_v4_2_0.hpp @@ -0,0 +1,1427 @@ +/** +* \file DrmControllerRegistersStrategy_v4_2_0.hpp +* \version 4.2.1.0 +* \date July 2020 +* \brief Class DrmControllerRegistersStrategy_v4_2_0 defines strategy for register access of drm controller v4.2.0. +* \copyright Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +#ifndef __DRM_CONTROLLER_REGISTERS_STRATEGY_V4_2_0_HPP__ +#define __DRM_CONTROLLER_REGISTERS_STRATEGY_V4_2_0_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +#include + +// version of the DRM Controller supported by this class +#define DRM_CONTROLLER_V4_2_0_SUPPORTED_VERSION "4.2.0" /** &licenseStartAddress) const; + + /** writeLicenseStartAddressRegister + * \brief Write the license start address register. + * This method will access to the system bus to write the license start address. + * \param[in] licenseStartAddress is a list of binary values for the license start address register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writeLicenseStartAddressRegister(const std::vector &licenseStartAddress) const; + + /** readLicenseTimerInitRegister + * \brief Read the license timer register. + * This method will access to the system bus to read the license timer. + * \param[out] licenseTimerInit is a list of binary values for the license timer register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerInitRegister(std::vector &licenseTimerInit) const; + + /** writeLicenseTimerInitRegister + * \brief Write the license start address register. + * This method will access to the system bus to write the license timer. + * \param[in] licenseTimerInit is a list of binary values for the license timer register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writeLicenseTimerInitRegister(const std::vector &licenseTimerInit) const; + + /** readDnaReadyStatusRegister + * \brief Read the status register and get the dna ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] dnaReady is the value of the status bit DNA Ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readDnaReadyStatusRegister(bool &dnaReady) const; + + /** waitDnaReadyStatusRegister + * \brief Wait dna ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitDnaReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readVlnvReadyStatusRegister + * \brief Read the status register and get the vlnv ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] vlnvReady is the value of the status bit VLNV Ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readVlnvReadyStatusRegister(bool &vlnvReady) const; + + /** waitVlnvReadyStatusRegister + * \brief Wait vlnv ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitVlnvReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readActivationDoneStatusRegister + * \brief Read the status register and get the activation done status bit. + * This method will access to the system bus to read the status register. + * \param[out] activationDone is the value of the status bit Activation Done. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readActivationDoneStatusRegister(bool &activationDone) const; + + /** waitActivationDoneStatusRegister + * \brief Wait activation done status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitActivationDoneStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readAutonomousControllerEnabledStatusRegister + * \brief Read the status register and get the autonomous controller enabled status bit. + * This method will access to the system bus to read the status register. + * \param[out] autoEnabled is the value of the status bit autonomous controller enabled. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAutonomousControllerEnabledStatusRegister(bool &autoEnabled) const; + + /** readAutonomousControllerBusyStatusRegister + * \brief Read the status register and get the autonomous controller busy status bit. + * This method will access to the system bus to read the status register. + * \param[out] autoBusy is the value of the status bit autonomous controller busy. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAutonomousControllerBusyStatusRegister(bool &autoBusy) const; + + /** waitAutonomousControllerBusyStatusRegister + * \brief Wait autonomous controller busy status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitAutonomousControllerBusyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readMeteringEnabledStatusRegister + * \brief Read the status register and get the metering enabled status bit. + * This method will access to the system bus to read the status register. + * \param[out] meteringEnabled is the value of the status bit metering enabled. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMeteringEnabledStatusRegister(bool &meteringEnabled) const; + + /** readMeteringReadyStatusRegister + * \brief Read the status register and get the metering ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] meteringReady is the value of the status bit metering ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMeteringReadyStatusRegister(bool &meteringReady) const; + + /** waitMeteringReadyStatusRegister + * \brief Wait metering ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitMeteringReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readSaasChallengeReadyStatusRegister + * \brief Read the status register and get the saas challenge ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] saasChallengeReady is the value of the status bit saas challenge ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSaasChallengeReadyStatusRegister(bool &saasChallengeReady) const; + + /** waitSaasChallengeReadyStatusRegister + * \brief Wait saas challenge ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSaasChallengeReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readLicenseTimerEnabledStatusRegister + * \brief Read the status register and get the license timer enabled status bit. + * This method will access to the system bus to read the status register. + * \param[out] licenseTimerEnabled is the value of the status bit license timer enabled. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerEnabledStatusRegister(bool &licenseTimerEnabled) const; + + /** readLicenseTimerInitLoadedStatusRegister + * \brief Read the status register and get the license timer init loaded status bit. + * This method will access to the system bus to read the status register. + * \param[out] licenseTimerInitLoaded is the value of the status bit license timer init load. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerInitLoadedStatusRegister(bool &licenseTimerInitLoaded) const; + + /** waitLicenseTimerInitLoadedStatusRegister + * \brief Wait license timer init loaded status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitLicenseTimerInitLoadedStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readEndSessionMeteringReadyStatusRegister + * \brief Read the status register and get the end session metering ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] endSessionMeteringReady is the value of the status bit end session metering ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readEndSessionMeteringReadyStatusRegister(bool &endSessionMeteringReady) const; + + /** waitEndSessionMeteringReadyStatusRegister + * \brief Wait end session metering ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitEndSessionMeteringReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readHeartBeatModeEnabledStatusRegister + * \brief Read the status register and get the heart beat mode enabled status bit. + * This method will access to the system bus to read the status register. + * \param[out] heartBeatModeEnabled is the value of the status bit heart beat mode enabled. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readHeartBeatModeEnabledStatusRegister(bool &heartBeatModeEnabled) const; + + /** readAsynchronousMeteringReadyStatusRegister + * \brief Read the status register and get the asynchronous metering ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] asynchronousMeteringReady is the value of the status bit asynchronous metering ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAsynchronousMeteringReadyStatusRegister(bool &asynchronousMeteringReady) const; + + /** waitAsynchronousMeteringReadyStatusRegister + * \brief Wait asynchronous metering ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitAsynchronousMeteringReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readLicenseTimerSampleReadyStatusRegister + * \brief Read the status register and get the license timer sample ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] licenseTimerSampleReady is the value of the status bit license timer sample ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerSampleReadyStatusRegister(bool &licenseTimerSampleReady) const; + + /** waitLicenseTimerSampleReadyStatusRegister + * \brief Wait license timer sample ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitLicenseTimerSampleReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readLicenseTimerCountEmptyStatusRegister + * \brief Read the status register and get the license timer count empty status bit. + * This method will access to the system bus to read the status register. + * \param[out] licenseTimerCounterEmpty is the value of the status bit license timer count empty. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerCountEmptyStatusRegister(bool &licenseTimerCounterEmpty) const; + + /** waitLicenseTimerCountEmptyStatusRegister + * \brief Wait license timer count empty status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitLicenseTimerCountEmptyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readSessionRunningStatusRegister + * \brief Read the status register and get the session running status bit. + * This method will access to the system bus to read the status register. + * \param[out] sessionRunning is the value of the status bit session running. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSessionRunningStatusRegister(bool &sessionRunning) const; + + /** waitSessionRunningStatusRegister + * \brief Wait session running status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSessionRunningStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readActivationCodesTransmittedStatusRegister + * \brief Read the status register and get the activation codes transmitted status bit. + * This method will access to the system bus to read the status register. + * \param[out] activationCodeTransmitted is the value of the status bit activation codes transmitted. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readActivationCodesTransmittedStatusRegister(bool &activationCodeTransmitted) const; + + /** waitActivationCodesTransmittedStatusRegister + * \brief Wait activation codes transmitted status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitActivationCodesTransmittedStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readLicenseNodeLockStatusRegister + * \brief Read the status register and get the license node lock status bit. + * This method will access to the system bus to read the status register. + * \param[out] licenseNodeLock is the value of the status bit license node lock. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseNodeLockStatusRegister(bool &licenseNodeLock) const; + + /** waitLicenseNodeLockStatusRegister + * \brief Wait license node lock status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitLicenseNodeLockStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readLicenseMeteringStatusRegister + * \brief Read the status register and get the license metering status bit. + * This method will access to the system bus to read the status register. + * \param[out] licenseMetering is the value of the status bit license metering. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseMeteringStatusRegister(bool &licenseMetering) const; + + /** waitLicenseMeteringStatusRegister + * \brief Wait license metering status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readSecurityAlertStatusRegister + * \brief Read the status register and get the Security Alert bit. + * This method will access to the system bus to read the status register. + * \param[out] securityAlert is the value of the status bit Security Alert. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSecurityAlertStatusRegister(bool &securityAlert) const; + + /** waitSecurityAlertgStatusRegister + * \brief Wait Security Alert status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + + /** readNumberOfLicenseTimerLoadedStatusRegister + * \brief Read the status register and get the number of license timer loaded. + * This method will access to the system bus to read the status register. + * \param[out] numberOfLicenseTimerLoaded is the number of license timer loaded retrieved from the status. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readNumberOfLicenseTimerLoadedStatusRegister(unsigned int &numberOfLicenseTimerLoaded) const; + + /** waitNumberOfLicenseTimerLoadedStatusRegister + * \brief Wait number of license timer loaded status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitNumberOfLicenseTimerLoadedStatusRegister(const unsigned int &timeout, const unsigned int &expected, unsigned int &actual) const; + + /** readNumberOfDetectedIpsStatusRegister + * \brief Read the status register and get the number of detected IPs. + * This method will access to the system bus to read the status register. + * \param[out] numberOfDetectedIps is the number of detected ips retrieved from the status. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readNumberOfDetectedIpsStatusRegister(unsigned int &numberOfDetectedIps) const; + + /** readExtractDnaErrorRegister + * \brief Read the error register and get the error code related to dna extraction. + * This method will access to the system bus to read the error register. + * \param[out] dnaExtractError is the error code related to dna extraction. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readExtractDnaErrorRegister(unsigned char &dnaExtractError) const; + + /** waitExtractDnaErrorRegister + * \brief Wait error to reach specified value. + * This method will access to the system bus to read the error register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the error to be expected. + * \param[out] actual is the value of the error read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitExtractDnaErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const; + + /** readExtractVlnvErrorRegister + * \brief Read the error register and get the error code related to vlnv extraction. + * This method will access to the system bus to read the error register. + * \param[out] vlnvExtractError is the error code related to vlnv extraction. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readExtractVlnvErrorRegister(unsigned char &vlnvExtractError) const; + + /** waitExtractVlnvErrorRegister + * \brief Wait error to reach specified value. + * This method will access to the system bus to read the error register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the error to be expected. + * \param[out] actual is the value of the error read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitExtractVlnvErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const; + + /** readActivationErrorRegister + * \brief Read the error register and get the error code related to activation. + * This method will access to the system bus to read the error register. + * \param[out] activationError is the error code related to activation. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readActivationErrorRegister(unsigned char &activationError) const; + + /** waitActivationErrorRegister + * \brief Wait error to reach specified value. + * This method will access to the system bus to read the error register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the error to be expected. + * \param[out] actual is the value of the error read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitActivationErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const; + + /** readLicenseTimerLoadErrorRegister + * \brief Read the error register and get the error code related to license timer loading. + * This method will access to the system bus to read the error register. + * \param[out] licenseTimerLoadError is the error code related to license timer loading. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerLoadErrorRegister(unsigned char &licenseTimerLoadError) const; + + /** waitActivationErrorRegister + * \brief Wait error to reach specified value. + * This method will access to the system bus to read the error register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the error to be expected. + * \param[out] actual is the value of the error read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitLicenseTimerLoadErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const; + + /** readDnaRegister + * \brief Read the dna register and get the value. + * This method will access to the system bus to read the dna register. + * \param[out] dna is the dna value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readDnaRegister(std::vector &dna) const; + + /** readSaasChallengeRegister + * \brief Read the Saas Challenge register and get the value. + * This method will access to the system bus to read the Saas Challenge register. + * \param[out] saasChallenge is the saas challenge value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSaasChallengeRegister(std::vector &saasChallenge) const; + + /** readLicenseTimerCounterRegister + * \brief Read the License Timer Counter register and get the value. + * This method will access to the system bus to read the License Timer Counter register. + * \param[out] licenseTimerCounter is the License Timer Counter value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerCounterRegister(std::vector &licenseTimerCounter) const; + + /** readDrmVersionRegister + * \brief Read the drm version register and get the value. + * This method will access to the system bus to read the drm version register. + * \param[out] drmVersion is the drm version value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readDrmVersionRegister(unsigned int &drmVersion) const; + + /** readLogsRegister + * \brief Read the logs register and get the value. + * This method will access to the system bus to read the logs register. + * \param[in] numberOfIps is the total number of IPs. + * \param[out] logs is the logs value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLogsRegister(const unsigned int &numberOfIps, std::vector &logs) const; + + /** readVlnvFileRegister + * \brief Read the vlnv file and get the value. + * This method will access to the system bus to read the vlnv file. + * The vlnv file will contains numberOfIps+1 words. The first one + * is dedicated to the drm controller, the others correspond for + * the IPs connected to the drm controller. + * \param[in] numberOfIps is the total number of IPs. + * \param[out] vlnvFile is the vlnv file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readVlnvFileRegister(const unsigned int &numberOfIps, std::vector &vlnvFile) const; + + /** readVlnvFileRegister + * \brief Read the vlnv file and get the value. + * This method will access to the system bus to read the vlnv file. + * The vlnv file will contains numberOfIps+1 elements. The first one + * is dedicated to the drm controller, the others correspond for + * the IPs connected to the drm controller. + * \param[in] numberOfIPs is the total number of IPs. + * \param[out] vlnvFile is the vlnv file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readVlnvFileRegister(const unsigned int &numberOfIPs, std::vector &vlnvFile) const; + + /** readLicenseFileRegister + * \brief Read the license file and get the value. + * This method will access to the system bus to read the license file. + * \param[in] licenseFileSize is the number of 128 bits words to read. + * \param[out] licenseFile is the license file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseFileRegister(const unsigned int &licenseFileSize, std::vector &licenseFile) const; + + /** readLicenseFileRegister + * \brief Read the license file and get the value. + * This method will access to the system bus to read the license file. + * The license file is a string using a hexadecimal representation. + * \param[in] licenseFileSize is the number of 128 bits words to read. + * \param[out] licenseFile is the license file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseFileRegister(const unsigned int &licenseFileSize, std::string &licenseFile) const; + + /** writeLicenseFile + * \brief Write the license file. + * This method will access to the system bus to write the license file. + * \param[in] licenseFileSize is the number of 128 bits words to read. + * \param[in] licenseFile is the license file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writeLicenseFileRegister(const unsigned int &licenseFileSize, const std::vector &licenseFile) const; + + /** writeLicenseFileRegister + * \brief Write the license file. + * This method will access to the system bus to write the license file. + * The license file is a string using a hexadecimal representation. + * \param[in] licenseFile is the license file. + * \return Returns mDrmApi_NO_ERROR if no error, + * mDrmApi_LICENSE_FILE_SIZE_ERROR if the license file size is lower than the minimum required, + * or the error code produced by the read/write register function. + * \throw DrmControllerLicenseFileSizeException whenever a check on license file size is bad. DrmControllerLicenseFileSizeException::what() + * should be called to get the exception description. + **/ + virtual unsigned int writeLicenseFileRegister(const std::string &licenseFile) const; + + /** readTraceFileRegister + * \brief Read the trace file and get the value. + * This method will access to the system bus to read the trace file. + * \param[in] numberOfIps is the total number of IPs. + * \param[out] traceFile is the trace file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readTraceFileRegister(const unsigned int &numberOfIps, std::vector &traceFile) const; + + /** readTraceFileRegister + * \brief Read the trace file and get the value. + * This method will access to the system bus to read the trace file. + * \param[in] numberOfIPs is the total number of IPs. + * \param[out] traceFile is the trace file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readTraceFileRegister(const unsigned int &numberOfIPs, std::vector &traceFile) const; + + /** readMeteringFileRegister + * \brief Read the metering file and get the value. + * This method will access to the system bus to read the metering file. + * \param[in] numberOfIps is the total number of IPs. + * \param[out] meteringFile is the metering file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMeteringFileRegister(const unsigned int &numberOfIps, std::vector &meteringFile) const; + + /** readMeteringFileRegister + * \brief Read the metering file and get the value. + * This method will access to the system bus to read the metering file. + * \param[in] numberOfIPs is the total number of IPs. + * \param[out] meteringFile is the metering file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMeteringFileRegister(const unsigned int &numberOfIPs, std::vector &meteringFile) const; + + /** readMailboxFileSizeRegister + * \brief Read the mailbox file word numbers. + * This method will access to the system bus to read the mailbox file. + * \param[out] readOnlyMailboxWordNumber is the number of words in the read-only mailbox. + * \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMailboxFileSizeRegister(unsigned int &readOnlyMailboxWordNumber, unsigned int &readWriteMailboxWordNumber) const; + + /** readMailboxFileRegister + * \brief Read the mailbox file. + * This method will access to the system bus to read the mailbox file. + * \param[out] readOnlyMailboxWordNumber is the number of words in the read-only mailbox. + * \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. + * \param[out] readOnlyMailboxData is the data read from the read-only mailbox. + * \param[out] readWriteMailboxData is the data read from the read-write mailbox. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMailboxFileRegister(unsigned int &readOnlyMailboxWordNumber, unsigned int &readWriteMailboxWordNumber, + std::vector &readOnlyMailboxData, std::vector &readWriteMailboxData) const; + + /** readMailboxFileRegister + * \brief Read the mailbox file. + * This method will access to the system bus to read the mailbox file. + * \param[out] readOnlyMailboxWordNumber is the number of words in the read-only mailbox. + * \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. + * \param[out] readOnlyMailboxData is the data read from the read-only mailbox. + * \param[out] readWriteMailboxData is the data read from the read-write mailbox. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMailboxFileRegister(unsigned int &readOnlyMailboxWordNumber, unsigned int &readWriteMailboxWordNumber, + std::vector &readOnlyMailboxData, std::vector &readWriteMailboxData) const; + + /** writeMailboxFileRegister + * \brief Write the mailbox file. + * This method will access to the system bus to write the mailbox file. + * \param[in] readWriteMailboxData is the data to write into the read-write mailbox. + * \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writeMailboxFileRegister(const std::vector &readWriteMailboxData, unsigned int &readWriteMailboxWordNumber) const; + + /** writeMailboxFileRegister + * \brief Write the mailbox file. + * This method will access to the system bus to write the mailbox file. + * \param[in] readWriteMailboxData is the data to write into the read-write mailbox. + * \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writeMailboxFileRegister(const std::vector &readWriteMailboxData, unsigned int &readWriteMailboxWordNumber) const; + + /** printMeteringFile + * \brief Display the value of the metering file. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printMeteringFileHwReport(std::ostream &file) const; + + /** getDrmErrorRegisterMessage + * \brief Get the error message from the error register value. + * \param[in] errorRegister is the value of the error register. + * \return Returns the error message. + **/ + virtual const char* getDrmErrorRegisterMessage(const unsigned char &errorRegister) const; + + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const; + + // protected members, functions ... + protected: + + /** readPageRegister + * \brief Read and get the value of the page register from the hardware. + * This method will access to the system bus to read the page register. + * \param[out] page is the value of the page register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readPageRegister(unsigned int &page) const; + + /** writePageRegister + * \brief Write the value of the page register into the hardware. + * This method will access to the system bus to write the page register. + * \param[in] page is the value of the page register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writePageRegister(const unsigned int &page) const; + + /** readCommandRegister + * \brief Read and get the value of the command register from the hardware. + * This method will access to the system bus to read the command register. + * \param[out] command is the value of the command register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readCommandRegister(unsigned int &command) const; + + /** writeCommandRegister + * \brief Write the value of the command register into the hardware. + * This method will access to the system bus to write the command register. + * \param[in] command is the value of the command register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writeCommandRegister(const unsigned int &command) const; + + /** readStatusRegister + * \brief Read the status register. + * This method will access to the system bus to read the status register. + * \param[out] status is the binary value of the status register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readStatusRegister(unsigned int &status) const; + + /** readErrorRegister + * \brief Read the error register. + * This method will access to the system bus to read the error register. + * \param[out] error is the binary value of the error register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readErrorRegister(unsigned int &error) const; + + // private members, functions ... + private: + + /** checkLicenseFileSize + * \brief Verify that the size of the license file is correct. + * \param[in] licenseFile is the license file. + * \return Returns true if license file size is correct, false otherwize. + * \throw DrmControllerLicenseFileSizeException whenever a check on license file size is bad. DrmControllerLicenseFileSizeException::what() should be called to get the exception description. + **/ + bool checkLicenseFileSize(const std::vector &licenseFile) const; + + /** printPage + * \brief Display the value of the page register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printPageHwReport(std::ostream &file) const; + + /** printCommand + * \brief Display the value of the command register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printCommandHwReport(std::ostream &file) const; + + /** printLicenseStartAddress + * \brief Display the value of the license start address register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printLicenseStartAddressHwReport(std::ostream &file) const; + + /** printLicenseTimer + * \brief Display the value of the license timer register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printLicenseTimerHwReport(std::ostream &file) const; + + /** printStatus + * \brief Display the value of the status register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printStatusHwReport(std::ostream &file) const; + + /** printError + * \brief Display the value of the error register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printErrorHwReport(std::ostream &file) const; + + /** printDrmVersion + * \brief Display the value of the drm version. + **/ + virtual void printDrmVersionHwReport(std::ostream &file) const; + + /** printDna + * \brief Display the value of the dna. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printDnaHwReport(std::ostream &file) const; + + /** printSaasChallenge + * \brief Display the value of the saas challenge. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printSaasChallengeHwReport(std::ostream &file) const; + + /** printLicenseTimerCounter + * \brief Display the value of the license timer counter. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printLicenseTimerCounterHwReport(std::ostream &file) const; + + /** printLogs + * \brief Display the value of the logs register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printLogsHwReport(std::ostream &file) const; + + /** printVlnvFile + * \brief Display the value of the vlnv file. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printVlnvFileHwReport(std::ostream &file) const; + + /** printLicenseFile + * \brief Display the license file. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printLicenseFileHwReport(std::ostream &file) const; + + /** printTraceFile + * \brief Display the trace file. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printTraceFileHwReport(std::ostream &file) const; + + /** printMailBoxFile + * \brief Display the value of the mailbox file. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printMailBoxFileHwReport(std::ostream &file) const; + + /** printAdaptiveProportionTestFailures + * \brief Display the value of the Adaptive Proportion Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const; + + /** printRepetitionCountTestFailures + * \brief Display the value of the Repetition Count Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printRepetitionCountTestFailuresHwReport(std::ostream &file) const; + + /** getMeteringFileHeader + * \brief Get the header of the metering file. + * \param[in] meteringFile is a list containing the metering file to retrieve the header from. + * \return Returns a list containing the metering file header. + **/ + std::vector getMeteringFileHeader(const std::vector &meteringFile) const; + + /** getMeteringFileHeaderSessionId + * \brief Get the session id from the metering file header. + * \param[in] meteringFileHeader is a list containing the metering file header to retrieve the session id from. + * \return Returns a list containing the metering file session id. + **/ + std::vector getMeteringFileHeaderSessionId(const std::vector &meteringFileHeader) const; + + /** getMeteringFileHeaderEncryptedMeteringFlag + * \brief Get the encrypted metering flag from the metering file header. + * \param[in] meteringFileHeader is a list containing the metering file header to retrieve the encrypted metering flag from. + * \return Returns true if the metering file is encrypted, false otherwize. + **/ + bool getMeteringFileHeaderEncryptedMeteringFlag(const std::vector &meteringFileHeader) const; + + /** getMeteringFileHeaderEndSessionMeteringFlag + * \brief Get the end session metering flag from the metering file header. + * \param[in] meteringFileHeader is a list containing the metering file header to retrieve the end session metering flag from. + * \return Returns true if the metering file is for an end session, false otherwize. + **/ + bool getMeteringFileHeaderEndSessionMeteringFlag(const std::vector &meteringFileHeader) const; + + /** getMeteringFileHeaderEnvironmentId + * \brief Get the environment id from the metering file header. + * \param[in] meteringFileHeader is a list containing the metering file header to retrieve the environment id from. + * \return Returns the environment id. + **/ + unsigned int getMeteringFileHeaderEnvironmentId(const std::vector &meteringFileHeader) const; + + /** getMeteringFileHeaderSegmentIndex + * \brief Get the segment index from the metering file header. + * \param[in] meteringFileHeader is a list containing the metering file header to retrieve the segment index from. + * \return Returns the segment index. + **/ + unsigned int getMeteringFileHeaderSegmentIndex(const std::vector &meteringFileHeader) const; + + /** getMeteringFileLicenseTimer + * \brief Get the license timer from the metering file. + * \param[in] meteringFile is a list containing the metering file to retrieve the license timer from. + * \return Returns a list containing the license timer retrieved from metering file. + **/ + std::vector getMeteringFileLicenseTimer(const std::vector &meteringFile) const; + + /** getMeteringFileIpMeteringData + * \brief Get the ip metering data from the metering file. + * \param[in] meteringFile is a list containing the metering file to retrieve the ip metering data from. + * \return Returns a list containing the ip metering retrieved from metering file. + **/ + std::vector getMeteringFileIpMeteringData(const std::vector &meteringFile) const; + + /** getMeteringFileMac + * \brief Get the mac from the metering file. + * \param[in] meteringFile is a list containing the metering file to retrieve the mac from. + * \return Returns a list containing the mac retrieved from metering file. + **/ + std::vector getMeteringFileMac(const std::vector &meteringFile) const; + + // number of words per registers + const unsigned int mCommandRegisterWordNumber; + const unsigned int mLicenseStartAddressRegisterWordNumber; + const unsigned int mLicenseTimerRegisterWordNumber; + const unsigned int mStatusRegisterWordNumber; + const unsigned int mErrorRegisterWordNumber; + const unsigned int mDnaRegisterWordNumber; + const unsigned int mSaasChallengeRegisterWordNumber; + const unsigned int mSampledLicenseTimerCountRegisterWordNumber; + const unsigned int mVersionRegisterWordNumber; + const unsigned int mAdaptiveProportionTestFailuresRegisterWordNumber; + const unsigned int mRepetitionCountTestFailuresRegisterWordNumber; + const unsigned int mVlnvWordRegisterWordNumber; + const unsigned int mLicenseWordRegisterWordNumber; + const unsigned int mTraceWordRegisterWordNumber; + const unsigned int mMeteringWordRegisterWordNumber; + const unsigned int mMailboxWordRegisterWordNumber; + + + // start index of each registers + const unsigned int mCommandRegisterStartIndex; + const unsigned int mLicenseStartAddressRegisterStartIndex; + const unsigned int mLicenseTimerRegisterStartIndex; + const unsigned int mStatusRegisterStartIndex; + const unsigned int mErrorRegisterStartIndex; + const unsigned int mDnaRegisterStartIndex; + const unsigned int mSaasChallengeRegisterStartIndex; + const unsigned int mSampledLicenseTimerCountRegisterStartIndex; + const unsigned int mVersionRegisterStartIndex; + const unsigned int mAdaptiveProportionTestFailuresRegisterStartIndex; + const unsigned int mRepetitionCountTestFailuresRegisterStartIndex; + const unsigned int mLogsRegisterStartIndex; + const unsigned int mVlnvWordRegisterStartIndex; + const unsigned int mLicenseWordRegisterStartIndex; + const unsigned int mTraceWordRegisterStartIndex; + const unsigned int mMeteringWordRegisterStartIndex; + const unsigned int mMailboxWordRegisterStartIndex; + + // number of traces per ip + const unsigned int mNumberOfTracesPerIp; + + // number of additional words + const unsigned int mVlnvNumberOfAdditionalWords; + const unsigned int mMeteringNumberOfAdditionalWords; + const unsigned int mMailboxNumberOfAdditionalWords; + + // number of words in license + const unsigned int mLicenseFileHeaderWordNumber; + const unsigned int mLicenseFileIpBlockWordNumber; + const unsigned int mLicenseFileMinimumWordNumber; + + // metering file words positions + const unsigned int mMeteringFileHeaderWordPosition; + const unsigned int mMeteringFileLicenseTimerCountWordPosition; + const unsigned int mMeteringFileFirstIpMeteringDataWordPosition; + const unsigned int mMeteringFileMacWordFromEndPosition; + + /** + * \enum tDrmPageRegisterEnumValues + * \brief Enumeration for page codes. + **/ + typedef enum tDrmPageRegisterEnumValues { + mDrmPageRegisters = 0x00, /** +#include +#include +#include +#include +#include +#include + +#include + +// version of the DRM Controller supported by this class +#define DRM_CONTROLLER_V4_2_1_SUPPORTED_VERSION "4.2.1" /** &licenseStartAddress) const; + + /** writeLicenseStartAddressRegister + * \brief Write the license start address register. + * This method will access to the system bus to write the license start address. + * \param[in] licenseStartAddress is a list of binary values for the license start address register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writeLicenseStartAddressRegister(const std::vector &licenseStartAddress) const; + + /** readLicenseTimerInitRegister + * \brief Read the license timer register. + * This method will access to the system bus to read the license timer. + * \param[out] licenseTimerInit is a list of binary values for the license timer register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerInitRegister(std::vector &licenseTimerInit) const; + + /** writeLicenseTimerInitRegister + * \brief Write the license start address register. + * This method will access to the system bus to write the license timer. + * \param[in] licenseTimerInit is a list of binary values for the license timer register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writeLicenseTimerInitRegister(const std::vector &licenseTimerInit) const; + + /** readDnaReadyStatusRegister + * \brief Read the status register and get the dna ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] dnaReady is the value of the status bit DNA Ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readDnaReadyStatusRegister(bool &dnaReady) const; + + /** waitDnaReadyStatusRegister + * \brief Wait dna ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitDnaReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readVlnvReadyStatusRegister + * \brief Read the status register and get the vlnv ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] vlnvReady is the value of the status bit VLNV Ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readVlnvReadyStatusRegister(bool &vlnvReady) const; + + /** waitVlnvReadyStatusRegister + * \brief Wait vlnv ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitVlnvReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readActivationDoneStatusRegister + * \brief Read the status register and get the activation done status bit. + * This method will access to the system bus to read the status register. + * \param[out] activationDone is the value of the status bit Activation Done. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readActivationDoneStatusRegister(bool &activationDone) const; + + /** waitActivationDoneStatusRegister + * \brief Wait activation done status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitActivationDoneStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readAutonomousControllerEnabledStatusRegister + * \brief Read the status register and get the autonomous controller enabled status bit. + * This method will access to the system bus to read the status register. + * \param[out] autoEnabled is the value of the status bit autonomous controller enabled. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAutonomousControllerEnabledStatusRegister(bool &autoEnabled) const; + + /** readAutonomousControllerBusyStatusRegister + * \brief Read the status register and get the autonomous controller busy status bit. + * This method will access to the system bus to read the status register. + * \param[out] autoBusy is the value of the status bit autonomous controller busy. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAutonomousControllerBusyStatusRegister(bool &autoBusy) const; + + /** waitAutonomousControllerBusyStatusRegister + * \brief Wait autonomous controller busy status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitAutonomousControllerBusyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readMeteringEnabledStatusRegister + * \brief Read the status register and get the metering enabled status bit. + * This method will access to the system bus to read the status register. + * \param[out] meteringEnabled is the value of the status bit metering enabled. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMeteringEnabledStatusRegister(bool &meteringEnabled) const; + + /** readMeteringReadyStatusRegister + * \brief Read the status register and get the metering ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] meteringReady is the value of the status bit metering ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMeteringReadyStatusRegister(bool &meteringReady) const; + + /** waitMeteringReadyStatusRegister + * \brief Wait metering ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitMeteringReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readSaasChallengeReadyStatusRegister + * \brief Read the status register and get the saas challenge ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] saasChallengeReady is the value of the status bit saas challenge ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSaasChallengeReadyStatusRegister(bool &saasChallengeReady) const; + + /** waitSaasChallengeReadyStatusRegister + * \brief Wait saas challenge ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSaasChallengeReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readLicenseTimerEnabledStatusRegister + * \brief Read the status register and get the license timer enabled status bit. + * This method will access to the system bus to read the status register. + * \param[out] licenseTimerEnabled is the value of the status bit license timer enabled. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerEnabledStatusRegister(bool &licenseTimerEnabled) const; + + /** readLicenseTimerInitLoadedStatusRegister + * \brief Read the status register and get the license timer init loaded status bit. + * This method will access to the system bus to read the status register. + * \param[out] licenseTimerInitLoaded is the value of the status bit license timer init load. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerInitLoadedStatusRegister(bool &licenseTimerInitLoaded) const; + + /** waitLicenseTimerInitLoadedStatusRegister + * \brief Wait license timer init loaded status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitLicenseTimerInitLoadedStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readEndSessionMeteringReadyStatusRegister + * \brief Read the status register and get the end session metering ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] endSessionMeteringReady is the value of the status bit end session metering ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readEndSessionMeteringReadyStatusRegister(bool &endSessionMeteringReady) const; + + /** waitEndSessionMeteringReadyStatusRegister + * \brief Wait end session metering ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitEndSessionMeteringReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readHeartBeatModeEnabledStatusRegister + * \brief Read the status register and get the heart beat mode enabled status bit. + * This method will access to the system bus to read the status register. + * \param[out] heartBeatModeEnabled is the value of the status bit heart beat mode enabled. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readHeartBeatModeEnabledStatusRegister(bool &heartBeatModeEnabled) const; + + /** readAsynchronousMeteringReadyStatusRegister + * \brief Read the status register and get the asynchronous metering ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] asynchronousMeteringReady is the value of the status bit asynchronous metering ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAsynchronousMeteringReadyStatusRegister(bool &asynchronousMeteringReady) const; + + /** waitAsynchronousMeteringReadyStatusRegister + * \brief Wait asynchronous metering ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitAsynchronousMeteringReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readLicenseTimerSampleReadyStatusRegister + * \brief Read the status register and get the license timer sample ready status bit. + * This method will access to the system bus to read the status register. + * \param[out] licenseTimerSampleReady is the value of the status bit license timer sample ready. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerSampleReadyStatusRegister(bool &licenseTimerSampleReady) const; + + /** waitLicenseTimerSampleReadyStatusRegister + * \brief Wait license timer sample ready status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitLicenseTimerSampleReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readLicenseTimerCountEmptyStatusRegister + * \brief Read the status register and get the license timer count empty status bit. + * This method will access to the system bus to read the status register. + * \param[out] licenseTimerCounterEmpty is the value of the status bit license timer count empty. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerCountEmptyStatusRegister(bool &licenseTimerCounterEmpty) const; + + /** waitLicenseTimerCountEmptyStatusRegister + * \brief Wait license timer count empty status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitLicenseTimerCountEmptyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readSessionRunningStatusRegister + * \brief Read the status register and get the session running status bit. + * This method will access to the system bus to read the status register. + * \param[out] sessionRunning is the value of the status bit session running. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSessionRunningStatusRegister(bool &sessionRunning) const; + + /** waitSessionRunningStatusRegister + * \brief Wait session running status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSessionRunningStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readActivationCodesTransmittedStatusRegister + * \brief Read the status register and get the activation codes transmitted status bit. + * This method will access to the system bus to read the status register. + * \param[out] activationCodeTransmitted is the value of the status bit activation codes transmitted. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readActivationCodesTransmittedStatusRegister(bool &activationCodeTransmitted) const; + + /** waitActivationCodesTransmittedStatusRegister + * \brief Wait activation codes transmitted status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitActivationCodesTransmittedStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readLicenseNodeLockStatusRegister + * \brief Read the status register and get the license node lock status bit. + * This method will access to the system bus to read the status register. + * \param[out] licenseNodeLock is the value of the status bit license node lock. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseNodeLockStatusRegister(bool &licenseNodeLock) const; + + /** waitLicenseNodeLockStatusRegister + * \brief Wait license node lock status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitLicenseNodeLockStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readLicenseMeteringStatusRegister + * \brief Read the status register and get the license metering status bit. + * This method will access to the system bus to read the status register. + * \param[out] licenseMetering is the value of the status bit license metering. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseMeteringStatusRegister(bool &licenseMetering) const; + + /** waitLicenseMeteringStatusRegister + * \brief Wait license metering status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + /** readSecurityAlertStatusRegister + * \brief Read the status register and get the Security Alert bit. + * This method will access to the system bus to read the status register. + * \param[out] securityAlert is the value of the status bit Security Alert. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSecurityAlertStatusRegister(bool &securityAlert) const; + + /** waitSecurityAlertgStatusRegister + * \brief Wait Security Alert status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status bit read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const; + + + /** readNumberOfLicenseTimerLoadedStatusRegister + * \brief Read the status register and get the number of license timer loaded. + * This method will access to the system bus to read the status register. + * \param[out] numberOfLicenseTimerLoaded is the number of license timer loaded retrieved from the status. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readNumberOfLicenseTimerLoadedStatusRegister(unsigned int &numberOfLicenseTimerLoaded) const; + + /** waitNumberOfLicenseTimerLoadedStatusRegister + * \brief Wait number of license timer loaded status register to reach specified value. + * This method will access to the system bus to read the status register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the status to be expected. + * \param[out] actual is the value of the status read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitNumberOfLicenseTimerLoadedStatusRegister(const unsigned int &timeout, const unsigned int &expected, unsigned int &actual) const; + + /** readNumberOfDetectedIpsStatusRegister + * \brief Read the status register and get the number of detected IPs. + * This method will access to the system bus to read the status register. + * \param[out] numberOfDetectedIps is the number of detected ips retrieved from the status. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readNumberOfDetectedIpsStatusRegister(unsigned int &numberOfDetectedIps) const; + + /** readExtractDnaErrorRegister + * \brief Read the error register and get the error code related to dna extraction. + * This method will access to the system bus to read the error register. + * \param[out] dnaExtractError is the error code related to dna extraction. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readExtractDnaErrorRegister(unsigned char &dnaExtractError) const; + + /** waitExtractDnaErrorRegister + * \brief Wait error to reach specified value. + * This method will access to the system bus to read the error register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the error to be expected. + * \param[out] actual is the value of the error read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitExtractDnaErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const; + + /** readExtractVlnvErrorRegister + * \brief Read the error register and get the error code related to vlnv extraction. + * This method will access to the system bus to read the error register. + * \param[out] vlnvExtractError is the error code related to vlnv extraction. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readExtractVlnvErrorRegister(unsigned char &vlnvExtractError) const; + + /** waitExtractVlnvErrorRegister + * \brief Wait error to reach specified value. + * This method will access to the system bus to read the error register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the error to be expected. + * \param[out] actual is the value of the error read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitExtractVlnvErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const; + + /** readActivationErrorRegister + * \brief Read the error register and get the error code related to activation. + * This method will access to the system bus to read the error register. + * \param[out] activationError is the error code related to activation. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readActivationErrorRegister(unsigned char &activationError) const; + + /** waitActivationErrorRegister + * \brief Wait error to reach specified value. + * This method will access to the system bus to read the error register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the error to be expected. + * \param[out] actual is the value of the error read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitActivationErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const; + + /** readLicenseTimerLoadErrorRegister + * \brief Read the error register and get the error code related to license timer loading. + * This method will access to the system bus to read the error register. + * \param[out] licenseTimerLoadError is the error code related to license timer loading. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerLoadErrorRegister(unsigned char &licenseTimerLoadError) const; + + /** waitActivationErrorRegister + * \brief Wait error to reach specified value. + * This method will access to the system bus to read the error register. + * \param[in] timeout is the timeout value in micro seconds. + * \param[in] expected is the value of the error to be expected. + * \param[out] actual is the value of the error read. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. + * \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. + **/ + virtual unsigned int waitLicenseTimerLoadErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const; + + /** readDnaRegister + * \brief Read the dna register and get the value. + * This method will access to the system bus to read the dna register. + * \param[out] dna is the dna value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readDnaRegister(std::vector &dna) const; + + /** readSaasChallengeRegister + * \brief Read the Saas Challenge register and get the value. + * This method will access to the system bus to read the Saas Challenge register. + * \param[out] saasChallenge is the saas challenge value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readSaasChallengeRegister(std::vector &saasChallenge) const; + + /** readLicenseTimerCounterRegister + * \brief Read the License Timer Counter register and get the value. + * This method will access to the system bus to read the License Timer Counter register. + * \param[out] licenseTimerCounter is the License Timer Counter value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseTimerCounterRegister(std::vector &licenseTimerCounter) const; + + /** readDrmVersionRegister + * \brief Read the drm version register and get the value. + * This method will access to the system bus to read the drm version register. + * \param[out] drmVersion is the drm version value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readDrmVersionRegister(unsigned int &drmVersion) const; + + /** readLogsRegister + * \brief Read the logs register and get the value. + * This method will access to the system bus to read the logs register. + * \param[in] numberOfIps is the total number of IPs. + * \param[out] logs is the logs value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLogsRegister(const unsigned int &numberOfIps, std::vector &logs) const; + + /** readVlnvFileRegister + * \brief Read the vlnv file and get the value. + * This method will access to the system bus to read the vlnv file. + * The vlnv file will contains numberOfIps+1 words. The first one + * is dedicated to the drm controller, the others correspond for + * the IPs connected to the drm controller. + * \param[in] numberOfIps is the total number of IPs. + * \param[out] vlnvFile is the vlnv file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readVlnvFileRegister(const unsigned int &numberOfIps, std::vector &vlnvFile) const; + + /** readVlnvFileRegister + * \brief Read the vlnv file and get the value. + * This method will access to the system bus to read the vlnv file. + * The vlnv file will contains numberOfIps+1 elements. The first one + * is dedicated to the drm controller, the others correspond for + * the IPs connected to the drm controller. + * \param[in] numberOfIPs is the total number of IPs. + * \param[out] vlnvFile is the vlnv file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readVlnvFileRegister(const unsigned int &numberOfIPs, std::vector &vlnvFile) const; + + /** readLicenseFileRegister + * \brief Read the license file and get the value. + * This method will access to the system bus to read the license file. + * \param[in] licenseFileSize is the number of 128 bits words to read. + * \param[out] licenseFile is the license file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseFileRegister(const unsigned int &licenseFileSize, std::vector &licenseFile) const; + + /** readLicenseFileRegister + * \brief Read the license file and get the value. + * This method will access to the system bus to read the license file. + * The license file is a string using a hexadecimal representation. + * \param[in] licenseFileSize is the number of 128 bits words to read. + * \param[out] licenseFile is the license file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readLicenseFileRegister(const unsigned int &licenseFileSize, std::string &licenseFile) const; + + /** writeLicenseFile + * \brief Write the license file. + * This method will access to the system bus to write the license file. + * \param[in] licenseFileSize is the number of 128 bits words to read. + * \param[in] licenseFile is the license file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writeLicenseFileRegister(const unsigned int &licenseFileSize, const std::vector &licenseFile) const; + + /** writeLicenseFileRegister + * \brief Write the license file. + * This method will access to the system bus to write the license file. + * The license file is a string using a hexadecimal representation. + * \param[in] licenseFile is the license file. + * \return Returns mDrmApi_NO_ERROR if no error, + * mDrmApi_LICENSE_FILE_SIZE_ERROR if the license file size is lower than the minimum required, + * or the error code produced by the read/write register function. + * \throw DrmControllerLicenseFileSizeException whenever a check on license file size is bad. DrmControllerLicenseFileSizeException::what() + * should be called to get the exception description. + **/ + virtual unsigned int writeLicenseFileRegister(const std::string &licenseFile) const; + + /** readTraceFileRegister + * \brief Read the trace file and get the value. + * This method will access to the system bus to read the trace file. + * \param[in] numberOfIps is the total number of IPs. + * \param[out] traceFile is the trace file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readTraceFileRegister(const unsigned int &numberOfIps, std::vector &traceFile) const; + + /** readTraceFileRegister + * \brief Read the trace file and get the value. + * This method will access to the system bus to read the trace file. + * \param[in] numberOfIPs is the total number of IPs. + * \param[out] traceFile is the trace file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readTraceFileRegister(const unsigned int &numberOfIPs, std::vector &traceFile) const; + + /** readMeteringFileRegister + * \brief Read the metering file and get the value. + * This method will access to the system bus to read the metering file. + * \param[in] numberOfIps is the total number of IPs. + * \param[out] meteringFile is the metering file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMeteringFileRegister(const unsigned int &numberOfIps, std::vector &meteringFile) const; + + /** readMeteringFileRegister + * \brief Read the metering file and get the value. + * This method will access to the system bus to read the metering file. + * \param[in] numberOfIPs is the total number of IPs. + * \param[out] meteringFile is the metering file. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMeteringFileRegister(const unsigned int &numberOfIPs, std::vector &meteringFile) const; + + /** readMailboxFileSizeRegister + * \brief Read the mailbox file word numbers. + * This method will access to the system bus to read the mailbox file. + * \param[out] readOnlyMailboxWordNumber is the number of words in the read-only mailbox. + * \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMailboxFileSizeRegister(unsigned int &readOnlyMailboxWordNumber, unsigned int &readWriteMailboxWordNumber) const; + + /** readMailboxFileRegister + * \brief Read the mailbox file. + * This method will access to the system bus to read the mailbox file. + * \param[out] readOnlyMailboxWordNumber is the number of words in the read-only mailbox. + * \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. + * \param[out] readOnlyMailboxData is the data read from the read-only mailbox. + * \param[out] readWriteMailboxData is the data read from the read-write mailbox. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMailboxFileRegister(unsigned int &readOnlyMailboxWordNumber, unsigned int &readWriteMailboxWordNumber, + std::vector &readOnlyMailboxData, std::vector &readWriteMailboxData) const; + + /** readMailboxFileRegister + * \brief Read the mailbox file. + * This method will access to the system bus to read the mailbox file. + * \param[out] readOnlyMailboxWordNumber is the number of words in the read-only mailbox. + * \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. + * \param[out] readOnlyMailboxData is the data read from the read-only mailbox. + * \param[out] readWriteMailboxData is the data read from the read-write mailbox. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readMailboxFileRegister(unsigned int &readOnlyMailboxWordNumber, unsigned int &readWriteMailboxWordNumber, + std::vector &readOnlyMailboxData, std::vector &readWriteMailboxData) const; + + /** writeMailboxFileRegister + * \brief Write the mailbox file. + * This method will access to the system bus to write the mailbox file. + * \param[in] readWriteMailboxData is the data to write into the read-write mailbox. + * \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writeMailboxFileRegister(const std::vector &readWriteMailboxData, unsigned int &readWriteMailboxWordNumber) const; + + /** writeMailboxFileRegister + * \brief Write the mailbox file. + * This method will access to the system bus to write the mailbox file. + * \param[in] readWriteMailboxData is the data to write into the read-write mailbox. + * \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writeMailboxFileRegister(const std::vector &readWriteMailboxData, unsigned int &readWriteMailboxWordNumber) const; + + /** printMeteringFile + * \brief Display the value of the metering file. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printMeteringFileHwReport(std::ostream &file) const; + + /** getDrmErrorRegisterMessage + * \brief Get the error message from the error register value. + * \param[in] errorRegister is the value of the error register. + * \return Returns the error message. + **/ + virtual const char* getDrmErrorRegisterMessage(const unsigned char &errorRegister) const; + + /** readAdaptiveProportionTestFailuresRegister + * \brief Read the Adaptive Proportion Test Failures register and get the value. + * This method will access to the system bus to read the Adaptive Proportion Test Failures register. + * \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const; + + /** readRepetitionCountTestFailuresRegister + * \brief Read the Repetition Count Test Failures register and get the value. + * This method will access to the system bus to read the Repetition Count Test Failures register. + * \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwise. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const; + + // protected members, functions ... + protected: + + /** readPageRegister + * \brief Read and get the value of the page register from the hardware. + * This method will access to the system bus to read the page register. + * \param[out] page is the value of the page register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readPageRegister(unsigned int &page) const; + + /** writePageRegister + * \brief Write the value of the page register into the hardware. + * This method will access to the system bus to write the page register. + * \param[in] page is the value of the page register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writePageRegister(const unsigned int &page) const; + + /** readCommandRegister + * \brief Read and get the value of the command register from the hardware. + * This method will access to the system bus to read the command register. + * \param[out] command is the value of the command register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readCommandRegister(unsigned int &command) const; + + /** writeCommandRegister + * \brief Write the value of the command register into the hardware. + * This method will access to the system bus to write the command register. + * \param[in] command is the value of the command register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int writeCommandRegister(const unsigned int &command) const; + + /** readStatusRegister + * \brief Read the status register. + * This method will access to the system bus to read the status register. + * \param[out] status is the binary value of the status register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readStatusRegister(unsigned int &status) const; + + /** readErrorRegister + * \brief Read the error register. + * This method will access to the system bus to read the error register. + * \param[out] error is the binary value of the error register. + * \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. + * \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. + **/ + virtual unsigned int readErrorRegister(unsigned int &error) const; + + // private members, functions ... + private: + + /** checkLicenseFileSize + * \brief Verify that the size of the license file is correct. + * \param[in] licenseFile is the license file. + * \return Returns true if license file size is correct, false otherwize. + * \throw DrmControllerLicenseFileSizeException whenever a check on license file size is bad. DrmControllerLicenseFileSizeException::what() should be called to get the exception description. + **/ + bool checkLicenseFileSize(const std::vector &licenseFile) const; + + /** printPage + * \brief Display the value of the page register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printPageHwReport(std::ostream &file) const; + + /** printCommand + * \brief Display the value of the command register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printCommandHwReport(std::ostream &file) const; + + /** printLicenseStartAddress + * \brief Display the value of the license start address register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printLicenseStartAddressHwReport(std::ostream &file) const; + + /** printLicenseTimer + * \brief Display the value of the license timer register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printLicenseTimerHwReport(std::ostream &file) const; + + /** printStatus + * \brief Display the value of the status register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printStatusHwReport(std::ostream &file) const; + + /** printError + * \brief Display the value of the error register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printErrorHwReport(std::ostream &file) const; + + /** printDrmVersion + * \brief Display the value of the drm version. + **/ + virtual void printDrmVersionHwReport(std::ostream &file) const; + + /** printDna + * \brief Display the value of the dna. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printDnaHwReport(std::ostream &file) const; + + /** printSaasChallenge + * \brief Display the value of the saas challenge. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printSaasChallengeHwReport(std::ostream &file) const; + + /** printLicenseTimerCounter + * \brief Display the value of the license timer counter. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printLicenseTimerCounterHwReport(std::ostream &file) const; + + /** printLogs + * \brief Display the value of the logs register. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printLogsHwReport(std::ostream &file) const; + + /** printVlnvFile + * \brief Display the value of the vlnv file. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printVlnvFileHwReport(std::ostream &file) const; + + /** printLicenseFile + * \brief Display the license file. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printLicenseFileHwReport(std::ostream &file) const; + + /** printTraceFile + * \brief Display the trace file. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printTraceFileHwReport(std::ostream &file) const; + + /** printMailBoxFile + * \brief Display the value of the mailbox file. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printMailBoxFileHwReport(std::ostream &file) const; + + /** printAdaptiveProportionTestFailures + * \brief Display the value of the Adaptive Proportion Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const; + + /** printRepetitionCountTestFailures + * \brief Display the value of the Repetition Count Test Failures. + * \param[in] file is the stream to use for the data print. + **/ + virtual void printRepetitionCountTestFailuresHwReport(std::ostream &file) const; + + /** getMeteringFileHeader + * \brief Get the header of the metering file. + * \param[in] meteringFile is a list containing the metering file to retrieve the header from. + * \return Returns a list containing the metering file header. + **/ + std::vector getMeteringFileHeader(const std::vector &meteringFile) const; + + /** getMeteringFileHeaderSessionId + * \brief Get the session id from the metering file header. + * \param[in] meteringFileHeader is a list containing the metering file header to retrieve the session id from. + * \return Returns a list containing the metering file session id. + **/ + std::vector getMeteringFileHeaderSessionId(const std::vector &meteringFileHeader) const; + + /** getMeteringFileHeaderEncryptedMeteringFlag + * \brief Get the encrypted metering flag from the metering file header. + * \param[in] meteringFileHeader is a list containing the metering file header to retrieve the encrypted metering flag from. + * \return Returns true if the metering file is encrypted, false otherwize. + **/ + bool getMeteringFileHeaderEncryptedMeteringFlag(const std::vector &meteringFileHeader) const; + + /** getMeteringFileHeaderEndSessionMeteringFlag + * \brief Get the end session metering flag from the metering file header. + * \param[in] meteringFileHeader is a list containing the metering file header to retrieve the end session metering flag from. + * \return Returns true if the metering file is for an end session, false otherwize. + **/ + bool getMeteringFileHeaderEndSessionMeteringFlag(const std::vector &meteringFileHeader) const; + + /** getMeteringFileHeaderEnvironmentId + * \brief Get the environment id from the metering file header. + * \param[in] meteringFileHeader is a list containing the metering file header to retrieve the environment id from. + * \return Returns the environment id. + **/ + unsigned int getMeteringFileHeaderEnvironmentId(const std::vector &meteringFileHeader) const; + + /** getMeteringFileHeaderSegmentIndex + * \brief Get the segment index from the metering file header. + * \param[in] meteringFileHeader is a list containing the metering file header to retrieve the segment index from. + * \return Returns the segment index. + **/ + unsigned int getMeteringFileHeaderSegmentIndex(const std::vector &meteringFileHeader) const; + + /** getMeteringFileLicenseTimer + * \brief Get the license timer from the metering file. + * \param[in] meteringFile is a list containing the metering file to retrieve the license timer from. + * \return Returns a list containing the license timer retrieved from metering file. + **/ + std::vector getMeteringFileLicenseTimer(const std::vector &meteringFile) const; + + /** getMeteringFileIpMeteringData + * \brief Get the ip metering data from the metering file. + * \param[in] meteringFile is a list containing the metering file to retrieve the ip metering data from. + * \return Returns a list containing the ip metering retrieved from metering file. + **/ + std::vector getMeteringFileIpMeteringData(const std::vector &meteringFile) const; + + /** getMeteringFileMac + * \brief Get the mac from the metering file. + * \param[in] meteringFile is a list containing the metering file to retrieve the mac from. + * \return Returns a list containing the mac retrieved from metering file. + **/ + std::vector getMeteringFileMac(const std::vector &meteringFile) const; + + // number of words per registers + const unsigned int mCommandRegisterWordNumber; + const unsigned int mLicenseStartAddressRegisterWordNumber; + const unsigned int mLicenseTimerRegisterWordNumber; + const unsigned int mStatusRegisterWordNumber; + const unsigned int mErrorRegisterWordNumber; + const unsigned int mDnaRegisterWordNumber; + const unsigned int mSaasChallengeRegisterWordNumber; + const unsigned int mSampledLicenseTimerCountRegisterWordNumber; + const unsigned int mVersionRegisterWordNumber; + const unsigned int mAdaptiveProportionTestFailuresRegisterWordNumber; + const unsigned int mRepetitionCountTestFailuresRegisterWordNumber; + const unsigned int mVlnvWordRegisterWordNumber; + const unsigned int mLicenseWordRegisterWordNumber; + const unsigned int mTraceWordRegisterWordNumber; + const unsigned int mMeteringWordRegisterWordNumber; + const unsigned int mMailboxWordRegisterWordNumber; + + + // start index of each registers + const unsigned int mCommandRegisterStartIndex; + const unsigned int mLicenseStartAddressRegisterStartIndex; + const unsigned int mLicenseTimerRegisterStartIndex; + const unsigned int mStatusRegisterStartIndex; + const unsigned int mErrorRegisterStartIndex; + const unsigned int mDnaRegisterStartIndex; + const unsigned int mSaasChallengeRegisterStartIndex; + const unsigned int mSampledLicenseTimerCountRegisterStartIndex; + const unsigned int mVersionRegisterStartIndex; + const unsigned int mAdaptiveProportionTestFailuresRegisterStartIndex; + const unsigned int mRepetitionCountTestFailuresRegisterStartIndex; + const unsigned int mLogsRegisterStartIndex; + const unsigned int mVlnvWordRegisterStartIndex; + const unsigned int mLicenseWordRegisterStartIndex; + const unsigned int mTraceWordRegisterStartIndex; + const unsigned int mMeteringWordRegisterStartIndex; + const unsigned int mMailboxWordRegisterStartIndex; + + // number of traces per ip + const unsigned int mNumberOfTracesPerIp; + + // number of additional words + const unsigned int mVlnvNumberOfAdditionalWords; + const unsigned int mMeteringNumberOfAdditionalWords; + const unsigned int mMailboxNumberOfAdditionalWords; + + // number of words in license + const unsigned int mLicenseFileHeaderWordNumber; + const unsigned int mLicenseFileIpBlockWordNumber; + const unsigned int mLicenseFileMinimumWordNumber; + + // metering file words positions + const unsigned int mMeteringFileHeaderWordPosition; + const unsigned int mMeteringFileLicenseTimerCountWordPosition; + const unsigned int mMeteringFileFirstIpMeteringDataWordPosition; + const unsigned int mMeteringFileMacWordFromEndPosition; + + /** + * \enum tDrmPageRegisterEnumValues + * \brief Enumeration for page codes. + **/ + typedef enum tDrmPageRegisterEnumValues { + mDrmPageRegisters = 0x00, /**waitLicenseMeteringStatusRegister(timeout, expected, actual); } +/** readSecurityAlertStatusRegister +* \brief Read the status register and get the Security Alert status bit. +* This method will access to the system bus to read the status register. +* \param[out] securityAlert is the value of the status bit Security Alert. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegisters::readSecurityAlertStatusRegister(bool &securityAlert) const { + return mDrmControllerRegistersStrategyInterface->readSecurityAlertStatusRegister(securityAlert); +} + +/** waitSecurityAlertStatusRegister +* \brief Wait Security Alert status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegisters::waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + return mDrmControllerRegistersStrategyInterface->waitSecurityAlertStatusRegister(timeout, expected, actual); +} + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -925,6 +950,50 @@ unsigned int DrmControllerRegisters::readDrmVersionRegister(std::string &drmVers return mDrmControllerRegistersStrategyInterface->readDrmVersionRegister(drmVersion); } +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegisters::readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const { + return mDrmControllerRegistersStrategyInterface->readAdaptiveProportionTestFailuresRegister(adaptiveProportionTestFailures); +} + +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegisters::readAdaptiveProportionTestFailuresRegister(std::string &adaptiveProportionTestFailures) const { + return mDrmControllerRegistersStrategyInterface->readAdaptiveProportionTestFailuresRegister(adaptiveProportionTestFailures); +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition CountTest Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegisters::readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const { + return mDrmControllerRegistersStrategyInterface->readRepetitionCountTestFailuresRegister(repetitionCountTestFailures); +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition Count Test Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegisters::readRepetitionCountTestFailuresRegister(std::string &repetitionCountTestFailures) const { + return mDrmControllerRegistersStrategyInterface->readRepetitionCountTestFailuresRegister(repetitionCountTestFailures); +} + /** readLogsRegister * \brief Read the logs register and get the value. * This method will access to the system bus to read the logs register. @@ -1318,6 +1387,8 @@ DrmControllerRegisters::tDrmControllerRegistersStrategyDictionary DrmControllerR strategies[DRM_CONTROLLER_V4_0_0_SUPPORTED_VERSION] = new DrmControllerRegistersStrategy_v4_0_0(readRegisterFunction, writeRegisterFunction); strategies[DRM_CONTROLLER_V4_0_1_SUPPORTED_VERSION] = new DrmControllerRegistersStrategy_v4_0_1(readRegisterFunction, writeRegisterFunction); strategies[DRM_CONTROLLER_V4_1_0_SUPPORTED_VERSION] = new DrmControllerRegistersStrategy_v4_1_0(readRegisterFunction, writeRegisterFunction); + strategies[DRM_CONTROLLER_V4_2_0_SUPPORTED_VERSION] = new DrmControllerRegistersStrategy_v4_2_0(readRegisterFunction, writeRegisterFunction); + strategies[DRM_CONTROLLER_V4_2_1_SUPPORTED_VERSION] = new DrmControllerRegistersStrategy_v4_2_1(readRegisterFunction, writeRegisterFunction); return strategies; } diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersBase.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersBase.cpp index a05f64a0..2afaa171 100644 --- a/drm_controller_sdk/source/HAL/DrmControllerRegistersBase.cpp +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersBase.cpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersBase.cpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersBase defines low level procedures for registers access. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersReport.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersReport.cpp index 908eac3d..2a515433 100644 --- a/drm_controller_sdk/source/HAL/DrmControllerRegistersReport.cpp +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersReport.cpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersReport.hpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersReport defines low level procedures for registers reporting. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategyInterface.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategyInterface.cpp index 2787cde2..d4fa3ee0 100644 --- a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategyInterface.cpp +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategyInterface.cpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategyInterface.cpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersBase defines low level procedures for registers access. * \copyright Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -156,6 +156,36 @@ unsigned int DrmControllerRegistersStrategyInterface::readSaasChallengeRegister( return errorCode; } +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategyInterface::readAdaptiveProportionTestFailuresRegister(std::string &adaptiveProportionTestFailures) const { + std::vector tmpAdaptiveProportionTestFailures; + unsigned int errorCode = readAdaptiveProportionTestFailuresRegister(tmpAdaptiveProportionTestFailures); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + adaptiveProportionTestFailures = DrmControllerDataConverter::binaryToHexString(tmpAdaptiveProportionTestFailures); + return errorCode; +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition Count Test Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_Unsupported_Feature if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategyInterface::readRepetitionCountTestFailuresRegister(std::string &repetitionCountTestFailures) const { + std::vector tmpRepetitionCountTestFailures; + unsigned int errorCode = readRepetitionCountTestFailuresRegister(tmpRepetitionCountTestFailures); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + repetitionCountTestFailures = DrmControllerDataConverter::binaryToHexString(tmpRepetitionCountTestFailures); + return errorCode; +} + /** readLicenseTimerCounterRegister * \brief Read the license timer counter register and get the value. * This method will access to the system bus to read the license timer counter register. @@ -227,6 +257,8 @@ void DrmControllerRegistersStrategyInterface::printHwReport(std::ostream &file) printTraceFileHwReport(file); printMeteringFileHwReport(file); printMailBoxFileHwReport(file); + printAdaptiveProportionTestFailuresHwReport(file); + printRepetitionCountTestFailuresHwReport(file); file << std::endl << footer() << std::endl << std::endl; } diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_0_0.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_0_0.cpp index c6596e97..a0fa5ced 100644 --- a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_0_0.cpp +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_0_0.cpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v3_0_0.cpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v3_0_0 defines strategy for register access of drm controller v3.0.0. * \copyright Licensed under the Apache License, Version 2.0 (the "License") { @@ -751,6 +751,33 @@ unsigned int DrmControllerRegistersStrategy_v3_0_0::waitLicenseMeteringStatusReg return mDrmApi_UNSUPPORTED_FEATURE_ERROR; } +/** readSecurityAlertStatusRegister +* \brief Read the status register and get the Security Alert status bit. +* This method will access to the system bus to read the status register. +* \param[out] securityAlert is the value of the status bit Security Alert. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_0_0::readSecurityAlertStatusRegister(bool &securityAlert) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V3_0_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** waitSecurityAlertStatusRegister +* \brief Wait Security Alert status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_0_0::waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V3_0_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -1169,6 +1196,30 @@ unsigned int DrmControllerRegistersStrategy_v3_0_0::readMailboxFileRegister(unsi return mDrmApi_UNSUPPORTED_FEATURE_ERROR; } +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_0_0::readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const { + throwUnsupportedFeatureException("Adaptive Proportion Test Failures Registers", DRM_CONTROLLER_V3_0_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition Count Test Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_0_0::readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const { + throwUnsupportedFeatureException("Repetition Count Test Failures Registers", DRM_CONTROLLER_V3_0_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + /** writeMailboxFileRegister * \brief Write the mailbox file. * This method will access to the system bus to write the mailbox file. @@ -1548,3 +1599,17 @@ void DrmControllerRegistersStrategy_v3_0_0::printTraceFileHwReport(std::ostream * \param[in] file is the stream to use for the data print. **/ void DrmControllerRegistersStrategy_v3_0_0::printMailBoxFileHwReport(std::ostream &file) const { } + +/** printAdaptiveProportionTestFailures +* \brief Display the value of the Adaptive Proportion Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v3_0_0::printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const { } + + +/** printRepetitionCountTestFailures +* \brief Display the value of the Repetition Count Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v3_0_0::printRepetitionCountTestFailuresHwReport(std::ostream &file) const { } + \ No newline at end of file diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_1_0.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_1_0.cpp index 8b5dbd4f..efcf92c7 100644 --- a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_1_0.cpp +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_1_0.cpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v3_1_0.cpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v3_1_0 defines strategy for register access of drm controller v3.0.0. * \copyright Licensed under the Apache License, Version 2.0 (the "License") { @@ -759,6 +759,34 @@ unsigned int DrmControllerRegistersStrategy_v3_1_0::waitLicenseMeteringStatusReg return errorCode; } +/** readSecurityAlertStatusRegister +* \brief Read the status register and get the Security Alert status bit. +* This method will access to the system bus to read the status register. +* \param[out] securityAlert is the value of the status bit Security Alert. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_1_0::readSecurityAlertStatusRegister(bool &securityAlert) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V3_1_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** waitSecurityAlertStatusRegister +* \brief Wait Security Alert status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_1_0::waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V3_1_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -1198,6 +1226,30 @@ unsigned int DrmControllerRegistersStrategy_v3_1_0::readMailboxFileRegister(unsi return errorCode; } +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_1_0::readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const { + throwUnsupportedFeatureException("Adaptive Proportion Test Failures Registers", DRM_CONTROLLER_V3_1_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition Count Test Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_1_0::readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const { + throwUnsupportedFeatureException("Repetition Count Test Failures Registers", DRM_CONTROLLER_V3_1_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + /** writeMailboxFileRegister * \brief Write the mailbox file. * This method will access to the system bus to write the mailbox file. @@ -1623,4 +1675,17 @@ void DrmControllerRegistersStrategy_v3_1_0::printMailBoxFileHwReport(std::ostrea file << registerValue(readOnlyMailboxData, "READ-ONLY MAILBOX", 0) << std::endl; file << registerValue(readWriteMailboxWordNumber, "READ-WRITE MAILBOX WORD NUMBER") << std::endl; file << registerValue(readWriteMailboxData, "READ-WRITE MAILBOX", 0) << std::endl; -} \ No newline at end of file +} + +/** printAdaptiveProportionTestFailures +* \brief Display the value of the Adaptive Proportion Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v3_1_0::printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const { } + +/** printRepetitionCountTestFailures +* \brief Display the value of the Repetition Count Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v3_1_0::printRepetitionCountTestFailuresHwReport(std::ostream &file) const { } + \ No newline at end of file diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_2_0.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_2_0.cpp index 5a2b376e..a4d24516 100644 --- a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_2_0.cpp +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_2_0.cpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v3_2_0.cpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v3_2_0 defines strategy for register access of drm controller v3.0.0. * \copyright Licensed under the Apache License, Version 2.0 (the "License") { @@ -763,6 +763,34 @@ unsigned int DrmControllerRegistersStrategy_v3_2_0::waitLicenseMeteringStatusReg return errorCode; } +/** readSecurityAlertStatusRegister +* \brief Read the status register and get the Security Alert status bit. +* This method will access to the system bus to read the status register. +* \param[out] securityAlert is the value of the status bit Security Alert. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_2_0::readSecurityAlertStatusRegister(bool &securityAlert) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V3_2_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** waitSecurityAlertStatusRegister +* \brief Wait Security Alert status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_2_0::waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V3_2_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -1202,6 +1230,30 @@ unsigned int DrmControllerRegistersStrategy_v3_2_0::readMailboxFileRegister(unsi return errorCode; } +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_2_0::readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const { + throwUnsupportedFeatureException("Adaptive Proportion Test Failures Registers", DRM_CONTROLLER_V3_2_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition Count Test Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_2_0::readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const { + throwUnsupportedFeatureException("Repetition Count Test Failures Registers", DRM_CONTROLLER_V3_2_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + /** writeMailboxFileRegister * \brief Write the mailbox file. * This method will access to the system bus to write the mailbox file. @@ -1736,3 +1788,17 @@ std::vector DrmControllerRegistersStrategy_v3_2_0::getMeteringFile return std::vector(prev(meteringFile.end(),(mMeteringFileMacWordFromEndPosition+1)*mMeteringWordRegisterWordNumber), prev(meteringFile.end(),mMeteringFileMacWordFromEndPosition*mMeteringWordRegisterWordNumber)); } + + +/** printAdaptiveProportionTestFailures +* \brief Display the value of the Adaptive Proportion Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v3_2_0::printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const { } + +/** printRepetitionCountTestFailures +* \brief Display the value of the Repetition Count Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v3_2_0::printRepetitionCountTestFailuresHwReport(std::ostream &file) const { } + diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_2_1.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_2_1.cpp index acf9decf..df3c8e6b 100644 --- a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_2_1.cpp +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_2_1.cpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v3_2_1.cpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v3_2_1 defines strategy for register access of drm controller v3.2.1. * \copyright Licensed under the Apache License, Version 2.0 (the "License") { @@ -763,6 +763,34 @@ unsigned int DrmControllerRegistersStrategy_v3_2_1::waitLicenseMeteringStatusReg return errorCode; } +/** readSecurityAlertStatusRegister +* \brief Read the status register and get the Security Alert status bit. +* This method will access to the system bus to read the status register. +* \param[out] securityAlert is the value of the status bit Security Alert. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_2_1::readSecurityAlertStatusRegister(bool &securityAlert) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V3_2_1_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** waitSecurityAlertStatusRegister +* \brief Wait Security Alert status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_2_1::waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V3_2_1_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -1202,6 +1230,30 @@ unsigned int DrmControllerRegistersStrategy_v3_2_1::readMailboxFileRegister(unsi return errorCode; } +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_2_1::readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const { + throwUnsupportedFeatureException("Adaptive Proportion Test Failures Registers", DRM_CONTROLLER_V3_2_1_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition Count Test Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_2_1::readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const { + throwUnsupportedFeatureException("Repetition Count Test Failures Registers", DRM_CONTROLLER_V3_2_1_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + /** writeMailboxFileRegister * \brief Write the mailbox file. * This method will access to the system bus to write the mailbox file. @@ -1736,3 +1788,16 @@ std::vector DrmControllerRegistersStrategy_v3_2_1::getMeteringFile return std::vector(prev(meteringFile.end(),(mMeteringFileMacWordFromEndPosition+1)*mMeteringWordRegisterWordNumber), prev(meteringFile.end(),mMeteringFileMacWordFromEndPosition*mMeteringWordRegisterWordNumber)); } + +/** printAdaptiveProportionTestFailures +* \brief Display the value of the Adaptive Proportion Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v3_2_1::printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const { } + +/** printRepetitionCountTestFailures +* \brief Display the value of the Repetition Count Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v3_2_1::printRepetitionCountTestFailuresHwReport(std::ostream &file) const { } + diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_2_2.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_2_2.cpp index b34d035e..6298a096 100644 --- a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_2_2.cpp +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v3_2_2.cpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v3_2_2.cpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v3_2_2 defines strategy for register access of drm controller v3.2.2. * \copyright Licensed under the Apache License, Version 2.0 (the "License") { @@ -763,6 +763,34 @@ unsigned int DrmControllerRegistersStrategy_v3_2_2::waitLicenseMeteringStatusReg return errorCode; } +/** readSecurityAlertStatusRegister +* \brief Read the status register and get the Security Alert status bit. +* This method will access to the system bus to read the status register. +* \param[out] securityAlert is the value of the status bit Security Alert. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_2_2::readSecurityAlertStatusRegister(bool &securityAlert) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V3_2_2_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** waitSecurityAlertStatusRegister +* \brief Wait Security Alert status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_2_2::waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V3_2_2_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -1202,6 +1230,30 @@ unsigned int DrmControllerRegistersStrategy_v3_2_2::readMailboxFileRegister(unsi return errorCode; } +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_2_2::readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const { + throwUnsupportedFeatureException("Adaptive Proportion Test Failures Registers", DRM_CONTROLLER_V3_2_2_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition Count Test Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v3_2_2::readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const { + throwUnsupportedFeatureException("Repetition Count Test Failures Registers", DRM_CONTROLLER_V3_2_2_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + /** writeMailboxFileRegister * \brief Write the mailbox file. * This method will access to the system bus to write the mailbox file. @@ -1736,3 +1788,16 @@ std::vector DrmControllerRegistersStrategy_v3_2_2::getMeteringFile return std::vector(prev(meteringFile.end(),(mMeteringFileMacWordFromEndPosition+1)*mMeteringWordRegisterWordNumber), prev(meteringFile.end(),mMeteringFileMacWordFromEndPosition*mMeteringWordRegisterWordNumber)); } + +/** printAdaptiveProportionTestFailures +* \brief Display the value of the Adaptive Proportion Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v3_2_2::printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const { } + +/** printRepetitionCountTestFailures +* \brief Display the value of the Repetition Count Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v3_2_2::printRepetitionCountTestFailuresHwReport(std::ostream &file) const { } + diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_0_0.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_0_0.cpp index aa003caf..8d32f4c9 100644 --- a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_0_0.cpp +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_0_0.cpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v4_0_0.cpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v4_0_0 defines strategy for register access of drm controller v4.0.0. * \copyright Licensed under the Apache License, Version 2.0 (the "License") { @@ -763,6 +763,34 @@ unsigned int DrmControllerRegistersStrategy_v4_0_0::waitLicenseMeteringStatusReg return errorCode; } +/** readSecurityAlertStatusRegister +* \brief Read the status register and get the Security Alert status bit. +* This method will access to the system bus to read the status register. +* \param[out] securityAlert is the value of the status bit Security Alert. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_0_0::readSecurityAlertStatusRegister(bool &securityAlert) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V4_0_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** waitSecurityAlertStatusRegister +* \brief Wait Security Alert status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_0_0::waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V4_0_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -1202,6 +1230,30 @@ unsigned int DrmControllerRegistersStrategy_v4_0_0::readMailboxFileRegister(unsi return errorCode; } +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_0_0::readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const { + throwUnsupportedFeatureException("Adaptive Proportion Test Failures Registers", DRM_CONTROLLER_V4_0_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition Count Test Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_0_0::readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const { + throwUnsupportedFeatureException("Repetition Count Test Failures Registers", DRM_CONTROLLER_V4_0_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + /** writeMailboxFileRegister * \brief Write the mailbox file. * This method will access to the system bus to write the mailbox file. @@ -1736,3 +1788,17 @@ std::vector DrmControllerRegistersStrategy_v4_0_0::getMeteringFile return std::vector(prev(meteringFile.end(),(mMeteringFileMacWordFromEndPosition+1)*mMeteringWordRegisterWordNumber), prev(meteringFile.end(),mMeteringFileMacWordFromEndPosition*mMeteringWordRegisterWordNumber)); } + +/** printAdaptiveProportionTestFailures +* \brief Display the value of the Adaptive Proportion Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_0_0::printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const { } + +/** printRepetitionCountTestFailures +* \brief Display the value of the Repetition Count Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_0_0::printRepetitionCountTestFailuresHwReport(std::ostream &file) const { } + + diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_0_1.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_0_1.cpp index 45536276..49801e31 100644 --- a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_0_1.cpp +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_0_1.cpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v4_0_1.cpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v4_0_1 defines strategy for register access of drm controller v4.0.1. * \copyright Licensed under the Apache License, Version 2.0 (the "License") { @@ -757,6 +757,34 @@ unsigned int DrmControllerRegistersStrategy_v4_0_1::waitLicenseMeteringStatusReg return errorCode; } +/** readSecurityAlertStatusRegister +* \brief Read the status register and get the Security Alert status bit. +* This method will access to the system bus to read the status register. +* \param[out] securityAlert is the value of the status bit Security Alert. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_0_1::readSecurityAlertStatusRegister(bool &securityAlert) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V4_0_1_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** waitSecurityAlertStatusRegister +* \brief Wait Security Alert status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_0_1::waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V4_0_1_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -1193,6 +1221,30 @@ unsigned int DrmControllerRegistersStrategy_v4_0_1::readMailboxFileRegister(unsi return errorCode; } +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_0_1::readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const { + throwUnsupportedFeatureException("Adaptive Proportion Test Failures Registers", DRM_CONTROLLER_V4_0_1_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition Count Test Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_0_1::readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const { + throwUnsupportedFeatureException("Repetition Count Test Failures Registers", DRM_CONTROLLER_V4_0_1_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + /** writeMailboxFileRegister * \brief Write the mailbox file. * This method will access to the system bus to write the mailbox file. @@ -1721,3 +1773,17 @@ std::vector DrmControllerRegistersStrategy_v4_0_1::getMeteringFile return std::vector(prev(meteringFile.end(),(mMeteringFileMacWordFromEndPosition+1)*mMeteringWordRegisterWordNumber), prev(meteringFile.end(),mMeteringFileMacWordFromEndPosition*mMeteringWordRegisterWordNumber)); } + +/** printAdaptiveProportionTestFailures +* \brief Display the value of the Adaptive Proportion Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_0_1::printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const { } + +/** printRepetitionCountTestFailures +* \brief Display the value of the Repetition Count Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_0_1::printRepetitionCountTestFailuresHwReport(std::ostream &file) const { } + + diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_1_0.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_1_0.cpp index 3d144dcd..12cdd799 100644 --- a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_1_0.cpp +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_1_0.cpp @@ -1,7 +1,7 @@ /** * \file DrmControllerRegistersStrategy_v4_1_0.cpp -* \version 4.1.0.0 -* \date March 2020 +* \version 4.2.1.0 +* \date July 2020 * \brief Class DrmControllerRegistersStrategy_v4_1_0 defines strategy for register access of drm controller v4.1.0. * \copyright Licensed under the Apache License, Version 2.0 (the "License") { @@ -757,6 +757,34 @@ unsigned int DrmControllerRegistersStrategy_v4_1_0::waitLicenseMeteringStatusReg return errorCode; } +/** readSecurityAlertStatusRegister +* \brief Read the status register and get the Security Alert status bit. +* This method will access to the system bus to read the status register. +* \param[out] securityAlert is the value of the status bit Security Alert. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_1_0::readSecurityAlertStatusRegister(bool &securityAlert) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V4_1_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** waitSecurityAlertStatusRegister +* \brief Wait Security Alert status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_1_0::waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V4_1_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + + /** readNumberOfLicenseTimerLoadedStatusRegister * \brief Read the status register and get the number of license timer loaded. * This method will access to the system bus to read the status register. @@ -1193,6 +1221,30 @@ unsigned int DrmControllerRegistersStrategy_v4_1_0::readMailboxFileRegister(unsi return errorCode; } +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_1_0::readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const { + throwUnsupportedFeatureException("Adaptive Proportion Test Failures Registers", DRM_CONTROLLER_V4_1_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition Count Test Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_1_0::readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const { + throwUnsupportedFeatureException("Repetition Count Test Failures Registers", DRM_CONTROLLER_V4_1_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + /** writeMailboxFileRegister * \brief Write the mailbox file. * This method will access to the system bus to write the mailbox file. @@ -1721,3 +1773,16 @@ std::vector DrmControllerRegistersStrategy_v4_1_0::getMeteringFile return std::vector(prev(meteringFile.end(),(mMeteringFileMacWordFromEndPosition+1)*mMeteringWordRegisterWordNumber), prev(meteringFile.end(),mMeteringFileMacWordFromEndPosition*mMeteringWordRegisterWordNumber)); } + +/** printAdaptiveProportionTestFailures +* \brief Display the value of the Adaptive Proportion Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_1_0::printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const { } + +/** printRepetitionCountTestFailures +* \brief Display the value of the Repetition Count Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_1_0::printRepetitionCountTestFailuresHwReport(std::ostream &file) const { } + diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_2_0.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_2_0.cpp new file mode 100644 index 00000000..803aefbc --- /dev/null +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_2_0.cpp @@ -0,0 +1,1803 @@ +/** +* \file DrmControllerRegistersStrategy_v4_2_0.cpp +* \version 4.2.1.0 +* \date July 2020 +* \brief Class DrmControllerRegistersStrategy_v4_2_0 defines strategy for register access of drm controller v4.2.0. +* \copyright Licensed under the Apache License, Version 2.0 (the "License") { + +} +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +#include + +// name space usage +using namespace DrmControllerLibrary; + +/************************************************************/ +/** PUBLIC MEMBER FUNCTIONS **/ +/************************************************************/ + +/** DrmControllerRegistersStrategy_v4_2_0 +* \brief Class constructor. +* \param[in] readRegisterFunction function pointer to read 32 bits register. +* The function pointer shall have the following prototype "unsigned int f(const std::string&, unsigned int&)". +* \param[in] writeRegisterFunction function pointer to write 32 bits register. +* The function pointer shall have the following prototype "unsigned int f(const std::string&, unsigned int)". +**/ +DrmControllerRegistersStrategy_v4_2_0::DrmControllerRegistersStrategy_v4_2_0(tDrmReadRegisterFunction readRegisterFunction, + tDrmWriteRegisterFunction writeRegisterFunction) +: DrmControllerRegistersStrategyInterface(readRegisterFunction, writeRegisterFunction), + mCommandRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_COMMAND_SIZE)), + mLicenseStartAddressRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_LICENSE_START_ADDRESS_SIZE)), + mLicenseTimerRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_LICENSE_TIMER_SIZE)), + mStatusRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_STATUS_SIZE)), + mErrorRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_ERROR_SIZE)), + mDnaRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_DEVICE_DNA_SIZE)), + mSaasChallengeRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_SAAS_CHALLENGE_SIZE)), + mSampledLicenseTimerCountRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_LICENSE_TIMER_COUNTER_SIZE)), + mVersionRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_VERSION_SIZE)), + mAdaptiveProportionTestFailuresRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_ADAPTIVE_PROPORTION_TEST_FAILURES_SIZE)), + mRepetitionCountTestFailuresRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_REPETITION_COUNT_TEST_FAILURES_SIZE)), + mVlnvWordRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_VLNV_WORD_SIZE)), + mLicenseWordRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_LICENSE_WORD_SIZE)), + mTraceWordRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_TRACE_WORD_SIZE)), + mMeteringWordRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_METERING_WORD_SIZE)), + mMailboxWordRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_0_MAILBOX_WORD_SIZE)), + mCommandRegisterStartIndex(0), + mLicenseStartAddressRegisterStartIndex(mCommandRegisterStartIndex+mCommandRegisterWordNumber), + mLicenseTimerRegisterStartIndex(mLicenseStartAddressRegisterStartIndex+mLicenseStartAddressRegisterWordNumber), + mStatusRegisterStartIndex(mLicenseTimerRegisterStartIndex+mLicenseTimerRegisterWordNumber), + mErrorRegisterStartIndex(mStatusRegisterStartIndex+mStatusRegisterWordNumber), + mDnaRegisterStartIndex(mErrorRegisterStartIndex+mErrorRegisterWordNumber), + mSaasChallengeRegisterStartIndex(mDnaRegisterStartIndex+mDnaRegisterWordNumber), + mSampledLicenseTimerCountRegisterStartIndex(mSaasChallengeRegisterStartIndex+mSaasChallengeRegisterWordNumber), + mVersionRegisterStartIndex(mSampledLicenseTimerCountRegisterStartIndex+mSampledLicenseTimerCountRegisterWordNumber), + mAdaptiveProportionTestFailuresRegisterStartIndex(mVersionRegisterStartIndex+mVersionRegisterWordNumber), + mRepetitionCountTestFailuresRegisterStartIndex(mAdaptiveProportionTestFailuresRegisterStartIndex+mAdaptiveProportionTestFailuresRegisterWordNumber), + mLogsRegisterStartIndex(mRepetitionCountTestFailuresRegisterStartIndex+mRepetitionCountTestFailuresRegisterWordNumber), + mVlnvWordRegisterStartIndex(0), + mLicenseWordRegisterStartIndex(0), + mTraceWordRegisterStartIndex(0), + mMeteringWordRegisterStartIndex(0), + mMailboxWordRegisterStartIndex(0), + mNumberOfTracesPerIp(DRM_CONTROLLER_V4_2_0_NUMBER_OF_TRACES_PER_IP), + mVlnvNumberOfAdditionalWords(DRM_CONTROLLER_V4_2_0_VLNV_NUMBER_OF_ADDITIONAL_WORDS), + mMeteringNumberOfAdditionalWords(DRM_CONTROLLER_V4_2_0_METERING_NUMBER_OF_ADDITIONAL_WORDS), + mMailboxNumberOfAdditionalWords(DRM_CONTROLLER_V4_2_0_MAILBOX_NUMBER_OF_ADDITIONAL_WORDS), + mLicenseFileHeaderWordNumber(DRM_CONTROLLER_V4_2_0_LICENSE_HEADER_BLOCK_SIZE), + mLicenseFileIpBlockWordNumber(DRM_CONTROLLER_V4_2_0_LICENSE_IP_BLOCK_SIZE), + mLicenseFileMinimumWordNumber((mLicenseFileHeaderWordNumber+mLicenseFileIpBlockWordNumber)*mLicenseWordRegisterWordNumber), + mMeteringFileHeaderWordPosition(DRM_CONTROLLER_V4_2_0_METERING_FILE_HEADER_POSITION), + mMeteringFileLicenseTimerCountWordPosition(DRM_CONTROLLER_V4_2_0_METERING_FILE_LICENSE_TIMER_COUNT_POSITION), + mMeteringFileFirstIpMeteringDataWordPosition(DRM_CONTROLLER_V4_2_0_METERING_FILE_FIRST_IP_METERING_DATA_POSITION), + mMeteringFileMacWordFromEndPosition(DRM_CONTROLLER_V4_2_0_METERING_FILE_MAC_FROM_END_POSITION), + mDrmErrorRegisterMessagesArraySize(DRM_CONTROLLER_V4_2_0_NUMBER_OF_ERROR_CODES), + mDrmErrorRegisterMessagesArray({ + { mDrmErrorNotReady, "Not ready" }, + { mDrmErrorNoError, "No error" }, + { mDrmErrorBusReadAuthenticatorDrmVersionTimeOutError, "Bus read authenticator drm version timeout error" }, + { mDrmErrorAuthenticatorDrmVersionError, "Authenticator drm version error" }, + { mDrmErrorDnaAuthenticationError, "Authenticator authentication error" }, + { mDrmErrorBusWriteAuthenticatorCommandTimeOutError, "Bus write authenticator command timeout error" }, + { mDrmErrorBusReadAuthenticatorStatusTimeOutError, "Bus read authenticator status timeout error" }, + { mDrmErrorBusWriteAuthenticatorChallengeTimeOutError, "Bus write authenticator challenge timeout error" }, + { mDrmErrorBusReadAuthenticatorResponseTimeOutError, "Bus read authenticator response timeout error" }, + { mDrmErrorBusReadAuthenticatorDnaTimeOutError, "Bus read authenticator dna timeout error" }, + { mDrmErrorBusReadActivatorDrmVersionTimeOutError, "Bus read activator drm version timeout error" }, + { mDrmErrorActivatorDrmVersionError, "Activator drm version error" }, + { mDrmErrorLicenseHeaderCheckError, "License header check error" }, + { mDrmErrorLicenseDrmVersionError, "License drm version error" }, + { mDrmErrorLicenseDnaDeltaError, "License dna delta error" }, + { mDrmErrorLicenseMacCheckError, "License MAC check error" }, + { mDrmErrorBusWriteActivatorCommandTimeOutError, "Bus write activator command timeout error" }, + { mDrmErrorBusReadActivatorStatusTimeOutError, "Bus read activator status timeout error" }, + { mDrmErrorBusReadActivatorChallengeTimeOutError, "Bus read activator challenge timeout error" }, + { mDrmErrorBusWriteActivatorResponseTimeOutError, "Bus write activator response timeout error" }, + { mDrmErrorBusReadInterruptTimeOutError, "Bus read interrupt timeout error" }, + { mDrmErrorBusReadExpectedStatusError, "Bus read expected status error" } + }) +{ + setIndexedRegisterName(DRM_CONTROLLER_V4_2_0_INDEXED_REGISTER_NAME); +} + +/** ~DrmControllerRegistersStrategy_v4_2_0 +* \brief Class destructor. +**/ +DrmControllerRegistersStrategy_v4_2_0::~DrmControllerRegistersStrategy_v4_2_0() +{} + +/** writeRegistersPageRegister +* \brief Write the page register to select the registers page. +* This method will access to the system bus to write into the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeRegistersPageRegister() const { + return writePageRegister(mDrmPageRegisters); +} + +/** writeVlnvFilePageRegister +* \brief Write the page register to select the vlnv file page. +* This method will access to the system bus to write into the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeVlnvFilePageRegister() const { + return writePageRegister(mDrmPageVlnvFile); +} + +/** writeLicenseFilePageRegister +* \brief Write the page register to select the license file page. +* This method will access to the system bus to write into the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeLicenseFilePageRegister() const { + return writePageRegister(mDrmPageLicenseFile); +} + +/** writeTraceFilePageRegister +* \brief Write the page register to select the trace file page. +* This method will access to the system bus to write into the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeTraceFilePageRegister() const { + return writePageRegister(mDrmPageTraceFile); +} + +/** writeMeteringFilePageRegister +* \brief Write the page register to select the metering file page. +* This method will access to the system bus to write into the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeMeteringFilePageRegister() const { + return writePageRegister(mDrmPageMeteringFile); +} + +/** writeMailBoxFilePageRegister +* \brief Write the page register to select the mailbox file page. +* This method will access to the system bus to write into the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeMailBoxFilePageRegister() const { + return writePageRegister(mDrmPageMailboxFile); +} + +/** writeNopCommandRegister +* \brief Write the command register to the NOP Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeNopCommandRegister() const { + return writeCommandRegister(mDrmCommandNop); +} + +/** writeDnaExtractCommandRegister +* \brief Write the command register to the DNA Extract Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeDnaExtractCommandRegister() const { + return writeCommandRegister(mDrmCommandExtractDna); +} + +/** writeVlnvExtractCommandRegister +* \brief Write the command register to the VLNV Extract Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeVlnvExtractCommandRegister() const { + return writeCommandRegister(mDrmCommandExtractVlnv); +} + +/** writeActivateCommandRegister +* \brief Write the command register to the Activate Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeActivateCommandRegister() const { + return writeCommandRegister(mDrmCommandActivate); +} + +/** writeEndSessionMeteringExtractCommandRegister +* \brief Write the command register to the end session extract metering Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeEndSessionMeteringExtractCommandRegister() const { + return writeCommandRegister(mDrmCommandEndSessionExtractMetering); +} + +/** writeMeteringExtractCommandRegister +* \brief Write the command register to the extract metering Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeMeteringExtractCommandRegister() const { + return writeCommandRegister(mDrmCommandExtractMetering); +} + +/** writeSampleLicenseTimerCounterCommandRegister +* \brief Write the command register to the sample license timer counter Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeSampleLicenseTimerCounterCommandRegister() const { + return writeCommandRegister(mDrmCommandSampleLicenseTimerCounter); +} + +/** readLicenseStartAddressRegister +* \brief Read the license start address register. +* This method will access to the system bus to read the license start address. +* \param[out] licenseStartAddress is a list of binary values for the license start address register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLicenseStartAddressRegister(std::vector &licenseStartAddress) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mLicenseStartAddressRegisterStartIndex, mLicenseStartAddressRegisterWordNumber, licenseStartAddress); +} + +/** writeLicenseStartAddressRegister +* \brief Write the license start address register. +* This method will access to the system bus to write the license start address. +* \param[in] licenseStartAddress is a list of binary values for the license start address register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeLicenseStartAddressRegister(const std::vector &licenseStartAddress) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return writeRegisterListFromIndex(mLicenseStartAddressRegisterStartIndex, mLicenseStartAddressRegisterWordNumber, licenseStartAddress); +} + +/** readLicenseTimerInitRegister +* \brief Read the license timer register. +* This method will access to the system bus to read the license timer. +* \param[out] licenseTimerInit is a list of binary values for the license timer register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLicenseTimerInitRegister(std::vector &licenseTimerInit) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mLicenseTimerRegisterStartIndex, mLicenseTimerRegisterWordNumber, licenseTimerInit); +} + +/** writeLicenseTimerInitRegister +* \brief Write the license start address register. +* This method will access to the system bus to write the license timer. +* \param[in] licenseTimerInit is a list of binary values for the license timer register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeLicenseTimerInitRegister(const std::vector &licenseTimerInit) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return writeRegisterListFromIndex(mLicenseTimerRegisterStartIndex, mLicenseTimerRegisterWordNumber, licenseTimerInit); +} + +/** readDnaReadyStatusRegister +* \brief Read the status register and get the dna ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] dnaReady is the value of the status bit DNA Ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readDnaReadyStatusRegister(bool &dnaReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusDnaReady, mDrmStatusMaskDnaReady, dnaReady); +} + +/** waitDnaReadyStatusRegister +* \brief Wait dna ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitDnaReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusDnaReady, mDrmStatusMaskDnaReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Dna Ready Status is in timeout", "Expected Dna Ready Status", "Actual Dna Ready Status", expected, actual); + return errorCode; +} + +/** readVlnvReadyStatusRegister +* \brief Read the status register and get the vlnv ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] vlnvReady is the value of the status bit VLNV Ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readVlnvReadyStatusRegister(bool &vlnvReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusVlnvReady, mDrmStatusMaskVlnvReady, vlnvReady); +} + +/** waitVlnvReadyStatusRegister +* \brief Wait vlnv ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitVlnvReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusVlnvReady, mDrmStatusMaskVlnvReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Vlnv Ready Status is in timeout", "Expected Vlnv Ready Status", "Actual Vlnv Ready Status", expected, actual); + return errorCode; +} + +/** readActivationDoneStatusRegister +* \brief Read the status register and get the activation done status bit. +* This method will access to the system bus to read the status register. +* \param[out] activationDone is the value of the status bit Activation Done. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readActivationDoneStatusRegister(bool &activationDone) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusActivationDone, mDrmStatusMaskActivationDone, activationDone); +} + +/** waitActivationDoneStatusRegister +* \brief Wait activation done status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitActivationDoneStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusActivationDone, mDrmStatusMaskActivationDone, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Activation Done Status is in timeout", "Expected Activation Done Status", "Actual Activation Done Status", expected, actual); + return errorCode; +} + +/** readAutonomousControllerEnabledStatusRegister +* \brief Read the status register and get the autonomous controller enabled status bit. +* This method will access to the system bus to read the status register. +* \param[out] autoEnabled is the value of the status bit autonomous controller enabled. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readAutonomousControllerEnabledStatusRegister(bool &autoEnabled) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusAutoEnabled, mDrmStatusMaskAutoEnabled, autoEnabled); + +} + +/** readAutonomousControllerBusyStatusRegister +* \brief Read the status register and get the autonomous controller busy status bit. +* This method will access to the system bus to read the status register. +* \param[out] autoBusy is the value of the status bit autonomous controller busy. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readAutonomousControllerBusyStatusRegister(bool &autoBusy) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusAutoBusy, mDrmStatusMaskAutoBusy, autoBusy); +} + +/** waitAutonomousControllerBusyStatusRegister +* \brief Wait autonomous controller busy status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitAutonomousControllerBusyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusAutoBusy, mDrmStatusMaskAutoBusy, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Autonomous Controller Busy Status is in timeout", "Expected Autonomous Controller Busy Status", "Actual Autonomous Controller Busy Status", expected, actual); + return errorCode; +} + +/** readMeteringEnabledStatusRegister +* \brief Read the status register and get the metering enabled status bit. +* This method will access to the system bus to read the status register. +* \param[out] meteringEnabled is the value of the status bit metering enabled. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readMeteringEnabledStatusRegister(bool &meteringEnabled) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusMeteringEnabled, mDrmStatusMaskMeteringEnabled, meteringEnabled); + +} + +/** readMeteringReadyStatusRegister +* \brief Read the status register and get the metering ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] meteringReady is the value of the status bit metering ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readMeteringReadyStatusRegister(bool &meteringReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusMeteringReady, mDrmStatusMaskMeteringReady, meteringReady); +} + +/** waitMeteringReadyStatusRegister +* \brief Wait metering ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitMeteringReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusMeteringReady, mDrmStatusMaskMeteringReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Metering Ready Status is in timeout", "Expected Metering Ready Status", "Actual Metering Ready Status", expected, actual); + return errorCode; +} + +/** readSaasChallengeReadyStatusRegister +* \brief Read the status register and get the saas challenge ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] saasChallengeReady is the value of the status bit saas challenge ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readSaasChallengeReadyStatusRegister(bool &saasChallengeReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusSaasChallengeReady, mDrmStatusMaskSaasChallengeReady, saasChallengeReady); +} + +/** waitSaasChallengeReadyStatusRegister +* \brief Wait saas challenge ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitSaasChallengeReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusSaasChallengeReady, mDrmStatusMaskSaasChallengeReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Saas Challenge Ready Status is in timeout", "Expected Saas Challenge Ready Status", "Actual Saas Challenge Ready Status", expected, actual); + return errorCode; +} + +/** readLicenseTimerEnabledStatusRegister +* \brief Read the status register and get the license timer enabled status bit. +* This method will access to the system bus to read the status register. +* \param[out] licenseTimerEnabled is the value of the status bit license timer enabled. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLicenseTimerEnabledStatusRegister(bool &licenseTimerEnabled) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseTimerEnabled, mDrmStatusMaskLicenseTimerEnabled, licenseTimerEnabled); +} + +/** readLicenseTimerInitLoadedStatusRegister +* \brief Read the status register and get the license timer init loaded status bit. +* This method will access to the system bus to read the status register. +* \param[out] licenseTimerInitLoaded is the value of the status bit license timer init load. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLicenseTimerInitLoadedStatusRegister(bool &licenseTimerInitLoaded) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseTimerInitLoaded, mDrmStatusMaskLicenseTimerInitLoaded, licenseTimerInitLoaded); +} + +/** waitLicenseTimerInitLoadedStatusRegister +* \brief Wait license timer init loaded status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitLicenseTimerInitLoadedStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusLicenseTimerInitLoaded, mDrmStatusMaskLicenseTimerInitLoaded, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait License Timer Init Loaded Status is in timeout", "Expected License Timer Init Loaded Status", "Actual License Timer Init Loaded Status", expected, actual); + return errorCode; +} + +/** readEndSessionMeteringReadyStatusRegister +* \brief Read the status register and get the end session metering ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] endSessionMeteringReady is the value of the status bit end session metering ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readEndSessionMeteringReadyStatusRegister(bool &endSessionMeteringReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusEndSessionMeteringReady, mDrmStatusMaskEndSessionMeteringReady, endSessionMeteringReady); +} + +/** waitEndSessionMeteringReadyStatusRegister +* \brief Wait end session metering ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitEndSessionMeteringReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusEndSessionMeteringReady, mDrmStatusMaskEndSessionMeteringReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait End Session Metering Ready Status is in timeout", "Expected End Session Metering Ready Status", "Actual End Session Metering Ready Status", expected, actual); + return errorCode; +} + +/** readHeartBeatModeEnabledStatusRegister +* \brief Read the status register and get the heart beat mode enabled status bit. +* This method will access to the system bus to read the status register. +* \param[out] heartBeatModeEnabled is the value of the status bit heart beat mode enabled. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readHeartBeatModeEnabledStatusRegister(bool &heartBeatModeEnabled) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusHeartBeatModeEnabled, mDrmStatusMaskHeartBeatModeEnabled, heartBeatModeEnabled); +} + +/** readAsynchronousMeteringReadyStatusRegister +* \brief Read the status register and get the asynchronous metering ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] asynchronousMeteringReady is the value of the status bit asynchronous metering ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readAsynchronousMeteringReadyStatusRegister(bool &asynchronousMeteringReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusAsynchronousMeteringReady, mDrmStatusMaskAsynchronousMeteringReady, asynchronousMeteringReady); +} + +/** waitAsynchronousMeteringReadyStatusRegister +* \brief Wait asynchronous metering ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitAsynchronousMeteringReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusAsynchronousMeteringReady, mDrmStatusMaskAsynchronousMeteringReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Asynchronous Metering Ready Status is in timeout", "Expected Asynchronous Metering Ready Status", "Actual Asynchronous Metering Ready Status", expected, actual); + return errorCode; +} + +/** readLicenseTimerSampleReadyStatusRegister +* \brief Read the status register and get the license timer sample ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] licenseTimerSampleReady is the value of the status bit license timer sample ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLicenseTimerSampleReadyStatusRegister(bool &licenseTimerSampleReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseTimerSampleReady, mDrmStatusMaskLicenseTimerSampleReady, licenseTimerSampleReady); +} + +/** waitLicenseTimerSampleReadyStatusRegister +* \brief Wait license timer sample ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitLicenseTimerSampleReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusLicenseTimerSampleReady, mDrmStatusMaskLicenseTimerSampleReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait License Timer Sample Ready Status is in timeout", "Expected License Timer Sample Ready Status", "Actual License Timer Sample Ready Status", expected, actual); + return errorCode; +} + +/** readLicenseTimerCountEmptyStatusRegister +* \brief Read the status register and get the license timer count empty status bit. +* This method will access to the system bus to read the status register. +* \param[out] licenseTimerCounterEmpty is the value of the status bit license timer count empty. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLicenseTimerCountEmptyStatusRegister(bool &licenseTimerCounterEmpty) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseTimerCountEmpty, mDrmStatusMaskLicenseTimerCountEmpty, licenseTimerCounterEmpty); +} + +/** waitLicenseTimerCountEmptyStatusRegister +* \brief Wait license timer count empty status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitLicenseTimerCountEmptyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusLicenseTimerCountEmpty, mDrmStatusMaskLicenseTimerCountEmpty, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait License Timer Count Empty Status is in timeout", "Expected License Timer Count Empty Status", "Actual License Timer Count Empty Status", expected, actual); + return errorCode; +} + +/** readSessionRunningStatusRegister +* \brief Read the status register and get the session running status bit. +* This method will access to the system bus to read the status register. +* \param[out] sessionRunning is the value of the status bit session running. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readSessionRunningStatusRegister(bool &sessionRunning) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusSessionRunning, mDrmStatusMaskSessionRunning, sessionRunning); +} + +/** waitSessionRunningStatusRegister +* \brief Wait session running status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitSessionRunningStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusSessionRunning, mDrmStatusMaskSessionRunning, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Session Running Status is in timeout", "Expected Session Running Status", "Actual Session Running Status", expected, actual); + return errorCode; +} + +/** readActivationCodesTransmittedStatusRegister +* \brief Read the status register and get the activation codes transmitted status bit. +* This method will access to the system bus to read the status register. +* \param[out] activationCodeTransmitted is the value of the status bit activation codes transmitted. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readActivationCodesTransmittedStatusRegister(bool &activationCodeTransmitted) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusActivationCodesTransmitted, mDrmStatusMaskActivationCodesTransmitted, activationCodeTransmitted); +} + +/** waitActivationCodesTransmittedStatusRegister +* \brief Wait activation codes transmitted status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitActivationCodesTransmittedStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusActivationCodesTransmitted, mDrmStatusMaskActivationCodesTransmitted, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Activation Codes Transmitted Status is in timeout", "Expected Activation Codes Transmitted Status", "Actual Activation Codes Transmitted Status", expected, actual); + return errorCode; +} + +/** readLicenseNodeLockStatusRegister +* \brief Read the status register and get the license node lock status bit. +* This method will access to the system bus to read the status register. +* \param[out] licenseNodeLock is the value of the status bit license node lock. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLicenseNodeLockStatusRegister(bool &licenseNodeLock) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseNodeLock, mDrmStatusMaskLicenseNodeLock, licenseNodeLock); +} + +/** waitLicenseNodeLockStatusRegister +* \brief Wait license node lock status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitLicenseNodeLockStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusLicenseNodeLock, mDrmStatusMaskLicenseNodeLock, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait License Node Lock Status is in timeout", "Expected License Node Lock Status", "Actual License Node Lock Status", expected, actual); + return errorCode; +} + +/** readLicenseMeteringStatusRegister +* \brief Read the status register and get the license metering status bit. +* This method will access to the system bus to read the status register. +* \param[out] licenseMetering is the value of the status bit license metering. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLicenseMeteringStatusRegister(bool &licenseMetering) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseMetering, mDrmStatusMaskLicenseMetering, licenseMetering); +} + +/** waitLicenseMeteringStatusRegister +* \brief Wait license metering status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusLicenseMetering, mDrmStatusMaskLicenseMetering, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait License Metering Status is in timeout", "Expected License Metering Status", "Actual License Metering Status", expected, actual); + return errorCode; +} + +/** readSecurityAlertStatusRegister +* \brief Read the status register and get the Security Alert status bit. +* This method will access to the system bus to read the status register. +* \param[out] securityAlert is the value of the status bit Security Alert. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readSecurityAlertStatusRegister(bool &securityAlert) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V4_2_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + +/** waitSecurityAlertStatusRegister +* \brief Wait Security Alert status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + throwUnsupportedFeatureException("Security Alert status", DRM_CONTROLLER_V4_2_0_SUPPORTED_VERSION); + return mDrmApi_UNSUPPORTED_FEATURE_ERROR; +} + + +/** readNumberOfLicenseTimerLoadedStatusRegister +* \brief Read the status register and get the number of license timer loaded. +* This method will access to the system bus to read the status register. +* \param[out] numberOfLicenseTimerLoaded is the number of license timer loaded retrieved from the status. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readNumberOfLicenseTimerLoadedStatusRegister(unsigned int &numberOfLicenseTimerLoaded) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseTimerLoadedNumberLsb, mDrmStatusMaskLicenseTimerLoadedNumber, numberOfLicenseTimerLoaded); +} + +/** waitNumberOfLicenseTimerLoadedStatusRegister +* \brief Wait number of license timer loaded status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitNumberOfLicenseTimerLoadedStatusRegister(const unsigned int &timeout, const unsigned int &expected, unsigned int &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusLicenseTimerLoadedNumberLsb, mDrmStatusMaskLicenseTimerLoadedNumber, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Number Of License Timer Loaded Status is in timeout", "Expected Number Of License Timer Loaded Status", "Actual Number Of License Timer Loaded Status", expected, actual); + return errorCode; +} + +/** readNumberOfDetectedIpsStatusRegister +* \brief Read the status register and get the number of detected IPs. +* This method will access to the system bus to read the status register. +* \param[out] numberOfDetectedIps is the number of detected ips retrieved from the status. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readNumberOfDetectedIpsStatusRegister(unsigned int &numberOfDetectedIps) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusIpActivatorNumberLsb, mDrmStatusMaskIpActivatorNumber, numberOfDetectedIps); +} + +/** readExtractDnaErrorRegister +* \brief Read the error register and get the error code related to dna extraction. +* This method will access to the system bus to read the error register. +* \param[out] dnaExtractError is the error code related to dna extraction. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readExtractDnaErrorRegister(unsigned char &dnaExtractError) const { + return DrmControllerRegistersStrategyInterface::readErrorRegister(mDrmDnaExtractErrorPosition, mDrmDnaExtractErrorMask, dnaExtractError); +} + +/** waitExtractDnaErrorRegister +* \brief Wait error to reach specified value. +* This method will access to the system bus to read the error register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the error to be expected. +* \param[out] actual is the value of the error read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitExtractDnaErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitErrorRegister(timeout, mDrmDnaExtractErrorPosition, mDrmDnaExtractErrorMask, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Extract Dna Error is in timeout", "Expected Extract Dna Error", "Actual Extract Dna Error", expected, actual, getDrmErrorRegisterMessage(expected), getDrmErrorRegisterMessage(actual)); + return errorCode; +} + +/** readExtractVlnvErrorRegister +* \brief Read the error register and get the error code related to vlnv extraction. +* This method will access to the system bus to read the error register. +* \param[out] vlnvExtractError is the error code related to vlnv extraction. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readExtractVlnvErrorRegister(unsigned char &vlnvExtractError) const { + return DrmControllerRegistersStrategyInterface::readErrorRegister(mDrmVlnvExtractErrorPosition, mDrmVlnvExtractErrorMask, vlnvExtractError); +} + +/** waitExtractVlnvErrorRegister +* \brief Wait error to reach specified value. +* This method will access to the system bus to read the error register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the error to be expected. +* \param[out] actual is the value of the error read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitExtractVlnvErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitErrorRegister(timeout, mDrmVlnvExtractErrorPosition, mDrmVlnvExtractErrorMask, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Extract Vlnv Error is in timeout", "Expected Extract Vlnv Error", "Actual Extract Vlnv Error", expected, actual, getDrmErrorRegisterMessage(expected), getDrmErrorRegisterMessage(actual)); + return errorCode; +} + +/** readActivationErrorRegister +* \brief Read the error register and get the error code related to activation. +* This method will access to the system bus to read the error register. +* \param[out] activationError is the error code related to activation. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readActivationErrorRegister(unsigned char &activationError) const { + return DrmControllerRegistersStrategyInterface::readErrorRegister(mDrmActivationErrorPosition, mDrmActivationErrorMask, activationError); +} + +/** waitActivationErrorRegister +* \brief Wait error to reach specified value. +* This method will access to the system bus to read the error register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the error to be expected. +* \param[out] actual is the value of the error read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitActivationErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitErrorRegister(timeout, mDrmActivationErrorPosition, mDrmActivationErrorMask, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Activation Error is in timeout", "Expected Activation Error", "Actual Activation Error", expected, actual, getDrmErrorRegisterMessage(expected), getDrmErrorRegisterMessage(actual)); + return errorCode; +} + +/** readLicenseTimerLoadErrorRegister +* \brief Read the error register and get the error code related to license timer loading. +* This method will access to the system bus to read the error register. +* \param[out] licenseTimerLoadError is the error code related to license timer loading. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLicenseTimerLoadErrorRegister(unsigned char &licenseTimerLoadError) const { + return DrmControllerRegistersStrategyInterface::readErrorRegister(mDrmLicenseTimerLoadErrorPosition, mDrmLicenseTimerLoadErrorMask, licenseTimerLoadError); +} + +/** waitActivationErrorRegister +* \brief Wait error to reach specified value. +* This method will access to the system bus to read the error register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the error to be expected. +* \param[out] actual is the value of the error read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::waitLicenseTimerLoadErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitErrorRegister(timeout, mDrmLicenseTimerLoadErrorPosition, mDrmLicenseTimerLoadErrorMask, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait License Timer Load Error is in timeout", "Expected License Timer Load Error", "Actual License Timer Load Error", expected, actual, getDrmErrorRegisterMessage(expected), getDrmErrorRegisterMessage(actual)); + return errorCode; +} + +/** readDnaRegister +* \brief Read the dna register and get the value. +* This method will access to the system bus to read the dna register. +* \param[out] dna is the dna value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readDnaRegister(std::vector &dna) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mDnaRegisterStartIndex, mDnaRegisterWordNumber, dna); +} + +/** readSaasChallengeRegister +* \brief Read the Saas Challenge register and get the value. +* This method will access to the system bus to read the Saas Challenge register. +* \param[out] saasChallenge is the saas challenge value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readSaasChallengeRegister(std::vector &saasChallenge) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mSaasChallengeRegisterStartIndex, mSaasChallengeRegisterWordNumber, saasChallenge); +} + +/** readLicenseTimerCounterRegister +* \brief Read the License Timer Counter register and get the value. +* This method will access to the system bus to read the License Timer Counter register. +* \param[out] licenseTimerCounter is the License Timer Counter value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLicenseTimerCounterRegister(std::vector &licenseTimerCounter) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mSampledLicenseTimerCountRegisterStartIndex, mSampledLicenseTimerCountRegisterWordNumber, licenseTimerCounter); +} + +/** readDrmVersionRegister +* \brief Read the drm version register and get the value. +* This method will access to the system bus to read the drm version register. +* \param[out] drmVersion is the drm version value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readDrmVersionRegister(unsigned int &drmVersion) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterAtIndex(mVersionRegisterStartIndex, drmVersion); +} + +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mAdaptiveProportionTestFailuresRegisterStartIndex, mAdaptiveProportionTestFailuresRegisterWordNumber, adaptiveProportionTestFailures); +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition Count Test Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mRepetitionCountTestFailuresRegisterStartIndex, mRepetitionCountTestFailuresRegisterWordNumber, repetitionCountTestFailures); +} + +/** readLogsRegister +* \brief Read the logs register and get the value. +* This method will access to the system bus to read the logs register. +* \param[in] numberOfIps is the total number of IPs. +* \param[out] logs is the logs value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLogsRegister(const unsigned int &numberOfIps, std::vector &logs) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mLogsRegisterStartIndex, numberOfWords(numberOfIps), logs); +} + +/** readVlnvFileRegister +* \brief Read the vlnv file and get the value. +* This method will access to the system bus to read the vlnv file. +* The vlnv file will contains numberOfIps+1 words. The first one +* is dedicated to the drm controller, the others correspond for +* the IPs connected to the drm controller. +* \param[in] numberOfIps is the total number of IPs. +* \param[out] vlnvFile is the vlnv file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readVlnvFileRegister(const unsigned int &numberOfIps, std::vector &vlnvFile) const { + unsigned int errorCode = writeVlnvFilePageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mVlnvWordRegisterStartIndex, mVlnvWordRegisterWordNumber*(numberOfIps+mVlnvNumberOfAdditionalWords), vlnvFile); +} + +/** readVlnvFileRegister +* \brief Read the vlnv file and get the value. +* This method will access to the system bus to read the vlnv file. +* The vlnv file will contains numberOfIps+1 elements. The first one +* is dedicated to the drm controller, the others correspond for +* the IPs connected to the drm controller. +* \param[in] numberOfIPs is the total number of IPs. +* \param[out] vlnvFile is the vlnv file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readVlnvFileRegister(const unsigned int &numberOfIPs, std::vector &vlnvFile) const { + std::vector tmpVlnvFile; + unsigned int errorCode = readVlnvFileRegister(numberOfIPs, tmpVlnvFile); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + vlnvFile = DrmControllerDataConverter::binaryToHexStringList(tmpVlnvFile, mVlnvWordRegisterWordNumber); + return errorCode; +} + +/** readLicenseFileRegister +* \brief Read the license file and get the value. +* This method will access to the system bus to read the license file. +* \param[in] licenseFileSize is the number of 128 bits words to read. +* \param[out] licenseFile is the license file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLicenseFileRegister(const unsigned int &licenseFileSize, std::vector &licenseFile) const { + unsigned int errorCode = writeLicenseFilePageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mLicenseWordRegisterStartIndex, mLicenseWordRegisterWordNumber*licenseFileSize, licenseFile); +} + +/** readLicenseFileRegister +* \brief Read the license file and get the value. +* This method will access to the system bus to read the license file. +* The license file is a string using a hexadecimal representation. +* \param[in] licenseFileSize is the number of 128 bits words to read. +* \param[out] licenseFile is the license file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readLicenseFileRegister(const unsigned int &licenseFileSize, std::string &licenseFile) const { + std::vector tmpLicense; + unsigned int errorCode = readLicenseFileRegister(licenseFileSize, tmpLicense); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + licenseFile = DrmControllerDataConverter::binaryToHexString(tmpLicense); + return errorCode; +} + +/** writeLicenseFile +* \brief Write the license file. +* This method will access to the system bus to write the license file. +* \param[in] licenseFileSize is the number of 128 bits words to read. +* \param[in] licenseFile is the license file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeLicenseFileRegister(const unsigned int &licenseFileSize, const std::vector &licenseFile) const { + unsigned int errorCode = writeLicenseFilePageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return writeRegisterListFromIndex(mLicenseWordRegisterStartIndex, mLicenseWordRegisterWordNumber*licenseFileSize, licenseFile); +} + +/** writeLicenseFileRegister +* \brief Write the license file. +* This method will access to the system bus to write the license file. +* The license file is a string using a hexadecimal representation. +* \param[in] licenseFile is the license file. +* \return Returns mDrmApi_NO_ERROR if no error, +* mDrmApi_LICENSE_FILE_SIZE_ERROR if the license file size is lower than the minimum required, +* or the error code produced by the read/write register function. +* \throw DrmControllerLicenseFileSizeException whenever a check on license file size is bad. DrmControllerLicenseFileSizeException::what() +* should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeLicenseFileRegister(const std::string &licenseFile) const { + std::vector tmpLicenseFile = DrmControllerDataConverter::hexStringToBinary(licenseFile); + if (checkLicenseFileSize(tmpLicenseFile) == false) return mDrmApi_LICENSE_FILE_SIZE_ERROR; + unsigned int licenseFileSize = tmpLicenseFile.size()/mLicenseWordRegisterWordNumber; + return writeLicenseFileRegister(licenseFileSize, tmpLicenseFile); +} + +/** readTraceFileRegister +* \brief Read the trace file and get the value. +* This method will access to the system bus to read the trace file. +* \param[in] numberOfIps is the total number of IPs. +* \param[out] traceFile is the trace file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readTraceFileRegister(const unsigned int &numberOfIps, std::vector &traceFile) const { + unsigned int errorCode = writeTraceFilePageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mTraceWordRegisterStartIndex, mTraceWordRegisterWordNumber*numberOfIps*mNumberOfTracesPerIp, traceFile); +} + +/** readTraceFileRegister +* \brief Read the trace file and get the value. +* This method will access to the system bus to read the trace file. +* \param[in] numberOfIPs is the total number of IPs. +* \param[out] traceFile is the trace file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readTraceFileRegister(const unsigned int &numberOfIPs, std::vector &traceFile) const { + std::vector tmpTraceFile; + unsigned int errorCode = readTraceFileRegister(numberOfIPs, tmpTraceFile); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + traceFile = DrmControllerDataConverter::binaryToHexStringList(tmpTraceFile, mTraceWordRegisterWordNumber); + return errorCode; +} + +/** readMeteringFileRegister +* \brief Read the metering file and get the value. +* This method will access to the system bus to read the metering file. +* \param[in] numberOfIps is the total number of IPs. +* \param[out] meteringFile is the metering file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readMeteringFileRegister(const unsigned int &numberOfIps, std::vector &meteringFile) const { + unsigned int errorCode = writeMeteringFilePageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mMeteringWordRegisterStartIndex, mMeteringWordRegisterWordNumber*(numberOfIps+mMeteringNumberOfAdditionalWords), meteringFile); +} + +/** readMeteringFileRegister +* \brief Read the metering file and get the value. +* This method will access to the system bus to read the metering file. +* \param[in] numberOfIPs is the total number of IPs. +* \param[out] meteringFile is the metering file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readMeteringFileRegister(const unsigned int &numberOfIPs, std::vector &meteringFile) const { + std::vector tmpMeteringFile; + unsigned int errorCode = readMeteringFileRegister(numberOfIPs, tmpMeteringFile); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + meteringFile = DrmControllerDataConverter::binaryToHexStringList(tmpMeteringFile, mMeteringWordRegisterWordNumber); + return errorCode; +} + +/** readMailboxFileSizeRegister +* \brief Read the mailbox file word numbers. +* This method will access to the system bus to read the mailbox file. +* \param[out] readOnlyMailboxWordNumber is the number of words in the read-only mailbox. +* \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readMailboxFileSizeRegister(unsigned int &readOnlyMailboxWordNumber, unsigned int &readWriteMailboxWordNumber) const { + unsigned int errorCode = writeMailBoxFilePageRegister(); + // read data at file start index + unsigned int mailboxSize; + errorCode = readRegisterAtIndex(mMailboxWordRegisterStartIndex, mailboxSize); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + // update sizes + readOnlyMailboxWordNumber = bits((unsigned int)mDrmMailboxFileReadOnlyMailboxWordNumberLsb, (unsigned int)mDrmMailboxFileMaskReadOnlyMailboxWordNumber, mailboxSize); + readWriteMailboxWordNumber = bits((unsigned int)mDrmMailboxFileReadWriteMailboxWordNumberLsb, (unsigned int)mDrmMailboxFileMaskReadWriteMailboxWordNumber, mailboxSize); + // return error result + return errorCode; +} + +/** readMailboxFileRegister +* \brief Read the mailbox file. +* This method will access to the system bus to read the mailbox file. +* \param[out] readOnlyMailboxWordNumber is the number of words in the read-only mailbox. +* \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. +* \param[out] readOnlyMailboxData is the data read from the read-only mailbox. +* \param[out] readWriteMailboxData is the data read from the read-write mailbox. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readMailboxFileRegister(unsigned int &readOnlyMailboxWordNumber, unsigned int &readWriteMailboxWordNumber, + std::vector &readOnlyMailboxData, std::vector &readWriteMailboxData) const { + // get mailbox sizes + unsigned int errorCode = readMailboxFileSizeRegister(readOnlyMailboxWordNumber, readWriteMailboxWordNumber); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + // read the read only mailbox + errorCode = readRegisterListFromIndex(mMailboxWordRegisterStartIndex + mMailboxNumberOfAdditionalWords, readOnlyMailboxWordNumber * mMailboxWordRegisterWordNumber, readOnlyMailboxData); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + // read the read write mailbox + return readRegisterListFromIndex(mMailboxWordRegisterStartIndex + readOnlyMailboxWordNumber * mMailboxWordRegisterWordNumber + mMailboxNumberOfAdditionalWords, + readWriteMailboxWordNumber * mMailboxWordRegisterWordNumber, readWriteMailboxData); +} + +/** readMailboxFileRegister +* \brief Read the mailbox file. +* This method will access to the system bus to read the mailbox file. +* \param[out] readOnlyMailboxWordNumber is the number of words in the read-only mailbox. +* \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. +* \param[out] readOnlyMailboxData is the data read from the read-only mailbox. +* \param[out] readWriteMailboxData is the data read from the read-write mailbox. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readMailboxFileRegister(unsigned int &readOnlyMailboxWordNumber, unsigned int &readWriteMailboxWordNumber, + std::vector &readOnlyMailboxData, std::vector &readWriteMailboxData) const { + std::vector tmpReadOnlyMailboxData, tmpReadWriteMailboxData; + unsigned int errorCode = readMailboxFileRegister(readOnlyMailboxWordNumber, readWriteMailboxWordNumber, tmpReadOnlyMailboxData, tmpReadWriteMailboxData); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + readOnlyMailboxData = DrmControllerDataConverter::binaryToHexStringList(tmpReadOnlyMailboxData, mMailboxWordRegisterWordNumber); + readWriteMailboxData = DrmControllerDataConverter::binaryToHexStringList(tmpReadWriteMailboxData, mMailboxWordRegisterWordNumber); + return errorCode; +} + +/** writeMailboxFileRegister +* \brief Write the mailbox file. +* This method will access to the system bus to write the mailbox file. +* \param[in] readWriteMailboxData is the data to write into the read-write mailbox. +* \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeMailboxFileRegister(const std::vector &readWriteMailboxData, unsigned int &readWriteMailboxWordNumber) const { + // read mailbox + unsigned int tmpReadOnlyMailboxWordNumber; + std::vector tmpReadOnlyMailboxData, tmpReadWriteMailboxData; + unsigned int errorCode = readMailboxFileRegister(tmpReadOnlyMailboxWordNumber, readWriteMailboxWordNumber, tmpReadOnlyMailboxData, tmpReadWriteMailboxData); + if (errorCode != mDrmApi_NO_ERROR || tmpReadWriteMailboxData == readWriteMailboxData) return errorCode; + // write the read write mailbox + return writeRegisterListFromIndex(mMailboxWordRegisterStartIndex + tmpReadOnlyMailboxWordNumber * mMailboxWordRegisterWordNumber + mMailboxNumberOfAdditionalWords, + readWriteMailboxWordNumber * mMailboxWordRegisterWordNumber, readWriteMailboxData); +} + +/** writeMailboxFileRegister +* \brief Write the mailbox file. +* This method will access to the system bus to write the mailbox file. +* \param[in] readWriteMailboxData is the data to write into the read-write mailbox. +* \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeMailboxFileRegister(const std::vector &readWriteMailboxData, unsigned int &readWriteMailboxWordNumber) const { + return writeMailboxFileRegister(DrmControllerDataConverter::hexStringListToBinary(readWriteMailboxData), readWriteMailboxWordNumber); +} + +/** printMeteringFile +* \brief Display the value of the metering file. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printMeteringFileHwReport(std::ostream &file) const { + unsigned int numberOfDetectedIps; + std::vector meteringFile; + if (readNumberOfDetectedIpsStatusRegister(numberOfDetectedIps) != mDrmApi_NO_ERROR) return; + if (readMeteringFileRegister(numberOfDetectedIps, meteringFile) != mDrmApi_NO_ERROR) return; + bool meteringFileEncrypted(getMeteringFileHeaderEncryptedMeteringFlag(getMeteringFileHeader(meteringFile))); + std::string environmentId(DrmControllerDataConverter::binaryToHexString(getMeteringFileHeaderEnvironmentId(getMeteringFileHeader(meteringFile)))); + if (meteringFileEncrypted == true) + file << fileName("ENCRYPTED METERING") << std::endl; + else + file << fileName("PLAIN METERING") << std::endl; + file << registerValue(DrmControllerDataConverter::binaryToHexString(getMeteringFileHeaderSessionId(getMeteringFileHeader(meteringFile))), "SESSION ID") << std::endl; + file << registerValue(meteringFileEncrypted, "ENCRYPTED METERING FLAG") << std::endl; + file << registerValue(getMeteringFileHeaderEndSessionMeteringFlag(getMeteringFileHeader(meteringFile)), "END SESSION METERING FLAG") << std::endl; + file << registerValue(environmentId.substr(4), "ENVIRONMENT ID") << std::endl; + file << registerValue(DrmControllerDataConverter::binaryToHexString(getMeteringFileHeaderSegmentIndex(getMeteringFileHeader(meteringFile))), "SEGMENT INDEX") << std::endl; + file << registerValue(DrmControllerDataConverter::binaryToHexString(getMeteringFileLicenseTimer(meteringFile)), "LICENSE TIMER COUNT") << std::endl; + if (meteringFileEncrypted == false) { + std::vector ipMeteringData(getMeteringFileIpMeteringData(meteringFile)); + for (unsigned int ii = 0; ii < numberOfDetectedIps; ii++) { + std::vector ipIndex(next(ipMeteringData.begin(),ii*mMeteringWordRegisterWordNumber),next(ipMeteringData.begin(),ii*mMeteringWordRegisterWordNumber+mMeteringWordRegisterWordNumber/2)); + std::vector ipMetering(next(ipMeteringData.begin(),ii*mMeteringWordRegisterWordNumber+mMeteringWordRegisterWordNumber/2),next(ipMeteringData.begin(),(ii+1)*mMeteringWordRegisterWordNumber)); + std::ostringstream writter; + writter << "IP INDEX 0x" << DrmControllerDataConverter::binaryToHexString(ipIndex) << " PLAIN METERING"; + file << registerValue(DrmControllerDataConverter::binaryToHexString(ipMetering), writter.str()) << std::endl; + } + } + else + file << registerValue(DrmControllerDataConverter::binaryToHexStringList(getMeteringFileIpMeteringData(meteringFile),mMeteringWordRegisterWordNumber), "ENCRYPTED IP METERING DATA", 0) << std::endl; + file << registerValue(DrmControllerDataConverter::binaryToHexString(getMeteringFileMac(meteringFile)), "MAC") << std::endl; +} + +/** getDrmErrorRegisterMessage +* \brief Get the error message from the error register value. +* \param[in] errorRegister is the value of the error register. +* \return Returns the error message. +**/ +const char* DrmControllerRegistersStrategy_v4_2_0::getDrmErrorRegisterMessage(const unsigned char &errorRegister) const { + for (unsigned int ii = 0; ii < mDrmErrorRegisterMessagesArraySize; ii++) { + if (mDrmErrorRegisterMessagesArray[ii].mDrmErrorCode == errorRegister) { + return mDrmErrorRegisterMessagesArray[ii].mDrmErrorMessage.c_str(); + } + } + return "Unknown error"; +} + +/************************************************************/ +/** PROTECTED MEMBER FUNCTIONS **/ +/************************************************************/ + +/** readPageRegister +* \brief Read and get the value of the page register from the hardware. +* This method will access to the system bus to read the page register. +* \param[out] page is the value of the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readPageRegister(unsigned int &page) const { + return readRegister(DRM_CONTROLLER_V4_2_0_PAGE_REGISTER_NAME, page); +} + +/** writePageRegister +* \brief Write the value of the page register into the hardware. +* This method will access to the system bus to write the page register. +* \param[in] page is the value of the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writePageRegister(const unsigned int &page) const { + return writeRegister(DRM_CONTROLLER_V4_2_0_PAGE_REGISTER_NAME, page); +} + +/** readCommandRegister +* \brief Read and get the value of the command register from the hardware. +* This method will access to the system bus to read the command register. +* \param[out] command is the value of the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readCommandRegister(unsigned int &command) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterAtIndex(mCommandRegisterStartIndex, command); +} + +/** writeCommandRegister +* \brief Write the value of the command register into the hardware. +* This method will access to the system bus to write the command register. +* \param[in] command is the value of the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::writeCommandRegister(const unsigned int &command) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return writeRegisterAtIndex(mCommandRegisterStartIndex, command); +} + +/** readStatusRegister +* \brief Read the status register. +* This method will access to the system bus to read the status register. +* \param[out] status is the binary value of the status register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readStatusRegister(unsigned int &status) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterAtIndex(mStatusRegisterStartIndex, status); +} + +/** readErrorRegister +* \brief Read the error register. +* This method will access to the system bus to read the error register. +* \param[out] error is the binary value of the error register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::readErrorRegister(unsigned int &error) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterAtIndex(mErrorRegisterStartIndex, error); +} + +/************************************************************/ +/** PRIVATE MEMBER FUNCTIONS **/ +/************************************************************/ + +/** checkLicenseFileSize +* \brief Verify that the size of the license file is correct. +* \param[in] licenseFile is the license file. +* \return Returns true if license file size is correct, false otherwize. +* \throw DrmControllerLicenseFileSizeException whenever a check on license file size is bad. DrmControllerLicenseFileSizeException::what() should be called to get the exception description. +**/ +bool DrmControllerRegistersStrategy_v4_2_0::checkLicenseFileSize(const std::vector &licenseFile) const { + if (licenseFile.size() >= mLicenseFileMinimumWordNumber) return true; + throwLicenseFileSizeException(mLicenseFileMinimumWordNumber, licenseFile.size()); + return false; +} + +/** printPage +* \brief Display the value of the page register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printPageHwReport(std::ostream &file) const { + unsigned int page(0); + if (readPageRegister(page) != mDrmApi_NO_ERROR) return; + file << registerName("PAGE") << std::endl; + file << registerValue(page, "PAGE", 1) << std::endl; +} + +/** printCommand +* \brief Display the value of the command register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printCommandHwReport(std::ostream &file) const { + unsigned int command(0); + if (readCommandRegister(command) != mDrmApi_NO_ERROR) return; + file << registerName("COMMAND") << std::endl; + file << registerValue(command, "COMMAND", 3) << std::endl; +} + +/** printLicenseStartAddress +* \brief Display the value of the license start address register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printLicenseStartAddressHwReport(std::ostream &file) const { + std::string licenseStartAddress(""); + if (DrmControllerRegistersStrategyInterface::readLicenseStartAddressRegister(licenseStartAddress) != mDrmApi_NO_ERROR) return; + file << registerName("LICENSE START ADDRESS") << std::endl; + file << registerValue(licenseStartAddress, "LICENSE START ADDRESS") << std::endl; +} + +/** printLicenseTimer +* \brief Display the value of the license timer register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printLicenseTimerHwReport(std::ostream &file) const { + std::string licenseTimerInit(""); + if (DrmControllerRegistersStrategyInterface::readLicenseTimerInitRegister(licenseTimerInit) != mDrmApi_NO_ERROR) return; + file << registerName("LICENSE TIMER INIT") << std::endl; + file << registerValue(licenseTimerInit.substr(0, 32), "LICENSE TIMER INIT WORD 0") << std::endl; + file << registerValue(licenseTimerInit.substr(32, 32), "LICENSE TIMER INIT WORD 0") << std::endl; + file << registerValue(licenseTimerInit.substr(64, 32), "LICENSE TIMER INIT WORD 0") << std::endl; +} + +/** printStatus +* \brief Display the value of the status register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printStatusHwReport(std::ostream &file) const { + bool bitStatus(false); + unsigned int intStatus(0); + file << registerName("STATUS") << std::endl; + // + if (readDnaReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "DNA READY STATUS") << std::endl; + // + if (readVlnvReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "VLNV READY STATUS") << std::endl; + // + if (readActivationDoneStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "ACTIVATION DONE STATUS") << std::endl; + // + if (readAutonomousControllerEnabledStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "AUTONOMOUS CONTROLLER ENABLED STATUS") << std::endl; + // + if (readAutonomousControllerBusyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "AUTONOMOUS CONTROLLER BUSY STATUS") << std::endl; + // + if (readMeteringEnabledStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "METERING ENABLED STATUS") << std::endl; + // + if (readMeteringReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "METERING READY STATUS") << std::endl; + // + if (readSaasChallengeReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "SAAS CHALLENGE READY STATUS") << std::endl; + // + if (readLicenseTimerEnabledStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "LICENSE TIMER ENABLED STATUS") << std::endl; + // + if (readLicenseTimerInitLoadedStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "LICENSE TIMER INIT LOADED STATUS") << std::endl; + // + if (readEndSessionMeteringReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "END SESSION METERING READY STATUS") << std::endl; + // + if (readHeartBeatModeEnabledStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "HEART BEAT MODE ENABLED STATUS") << std::endl; + // + if (readAsynchronousMeteringReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "ASYNCHRONOUS METERING READY STATUS") << std::endl; + // + if (readLicenseTimerSampleReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "LICENSE TIMER SAMPLE READY STATUS") << std::endl; + // + if (readLicenseTimerCountEmptyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "LICENSE TIMER COUNTER EMPTY STATUS") << std::endl; + // + if (readSessionRunningStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "SESSION RUNNING STATUS") << std::endl; + // + if (readActivationCodesTransmittedStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "ACTIVATION CODES TRANSMITTED STATUS") << std::endl; + // + if (readLicenseNodeLockStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "LICENSE NODE LOCK STATUS") << std::endl; + // + if (readLicenseMeteringStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "LICENSE METERING STATUS") << std::endl; + // + if (readNumberOfLicenseTimerLoadedStatusRegister(intStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(intStatus, "NUMBER OF LICENSE TIMER LOADED STATUS") << std::endl; + // + if (readNumberOfDetectedIpsStatusRegister(intStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(intStatus, "NUMBER OF DETECTED IPS STATUS") << std::endl; +} + +/** printError +* \brief Display the value of the error register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printErrorHwReport(std::ostream &file) const { + unsigned char errorCode(0); + file << registerName("STATUS") << std::endl; + // + if (readExtractDnaErrorRegister(errorCode) != mDrmApi_NO_ERROR) return; + file << registerValue((unsigned int)errorCode, "DNA EXTRACT ERROR", 2) << std::endl; + file << stringValue(getDrmErrorRegisterMessage(errorCode), "DNA EXTRACT ERROR MESSAGE") << std::endl; + // + if (readExtractVlnvErrorRegister(errorCode) != mDrmApi_NO_ERROR) return; + file << registerValue((unsigned int)errorCode, "VLNV EXTRACT ERROR", 2) << std::endl; + file << stringValue(getDrmErrorRegisterMessage(errorCode), "VLNV EXTRACT ERROR MESSAGE") << std::endl; + // + if (readLicenseTimerLoadErrorRegister(errorCode) != mDrmApi_NO_ERROR) return; + file << registerValue((unsigned int)errorCode, "LICENSE TIMER LOAD ERROR", 2) << std::endl; + file << stringValue(getDrmErrorRegisterMessage(errorCode), "LICENSE TIMER LOAD ERROR MESSAGE") << std::endl; + // + if (readActivationErrorRegister(errorCode) != mDrmApi_NO_ERROR) return; + file << registerValue((unsigned int)errorCode, "ACTIVATION ERROR", 2) << std::endl; + file << stringValue(getDrmErrorRegisterMessage(errorCode), "ACTIVATION ERROR MESSAGE") << std::endl; +} + +/** printDrmVersion +* \brief Display the value of the drm version. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printDrmVersionHwReport(std::ostream &file) const { + std::string drmVersion; + if (DrmControllerRegistersStrategyInterface::readDrmVersionRegister(drmVersion) != mDrmApi_NO_ERROR) return; + file << versionName("SOFTWARE") << std::endl; + file << stringValue(DRM_CONTROLLER_SDK_VERSION, "SDK VERSION") << std::endl; + // display the hardware version + std::string drmVersionDot = DrmControllerDataConverter::binaryToVersionString(DrmControllerDataConverter::hexStringToBinary(drmVersion)[0]); + file << versionName("HARDWARE") << std::endl; + file << stringValue(drmVersionDot, "HDK VERSION") << std::endl; +} + +/** printDna +* \brief Display the value of the dna. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printDnaHwReport(std::ostream &file) const { + std::string dna; + if (DrmControllerRegistersStrategyInterface::readDnaRegister(dna) != mDrmApi_NO_ERROR) return; + file << registerName("DNA") << std::endl; + file << registerValue(dna, "DNA") << std::endl; +} + +/** printSaasChallenge +* \brief Display the value of the saas challenge. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printSaasChallengeHwReport(std::ostream &file) const { + std::string saasChallenge; + if (DrmControllerRegistersStrategyInterface::readSaasChallengeRegister(saasChallenge) != mDrmApi_NO_ERROR) return; + file << registerName("SAAS CHALLENGE") << std::endl; + file << registerValue(saasChallenge, "SAAS CHALLENGE") << std::endl; +} + +/** printAdaptiveProportionTestFailures +* \brief Display the value of the Adaptive Proportion Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const { + std::string adaptiveProportionTestFailures; + if (DrmControllerRegistersStrategyInterface::readAdaptiveProportionTestFailuresRegister(adaptiveProportionTestFailures) != mDrmApi_NO_ERROR) return; + file << registerName("ADAPTIVE PROPORTION TEST FAILURES") << std::endl; + file << registerValue(adaptiveProportionTestFailures, "ADAPTIVE PROPORTION TEST FAILURES") << std::endl; +} + +/** printRepetitionCountTestFailures +* \brief Display the value of the Repetition Count Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printRepetitionCountTestFailuresHwReport(std::ostream &file) const { + std::string repetitionCountTestFailures; + if (DrmControllerRegistersStrategyInterface::readRepetitionCountTestFailuresRegister(repetitionCountTestFailures) != mDrmApi_NO_ERROR) return; + file << registerName("REPETITION COUNT TEST FAILURES") << std::endl; + file << registerValue(repetitionCountTestFailures, "REPETITION COUNT TEST FAILURES") << std::endl; +} + +/** printLicenseTimerCounter +* \brief Display the value of the license timer counter. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printLicenseTimerCounterHwReport(std::ostream &file) const { + std::string licenseTimerCounter; + if (DrmControllerRegistersStrategyInterface::readLicenseTimerCounterRegister(licenseTimerCounter) != mDrmApi_NO_ERROR) return; + file << registerName("LICENSE TIMER COUNTER") << std::endl; + file << registerValue(licenseTimerCounter, "LICENSE TIMER COUNTER") << std::endl; +} + +/** printLogs +* \brief Display the value of the logs register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printLogsHwReport(std::ostream &file) const { + unsigned int numberOfDetectedIps; + std::string logs; + if (readNumberOfDetectedIpsStatusRegister(numberOfDetectedIps) != mDrmApi_NO_ERROR) return; + if (DrmControllerRegistersStrategyInterface::readLogsRegister(numberOfDetectedIps, logs) != mDrmApi_NO_ERROR) return; + file << registerName("LOGS") << std::endl; + file << registerValue(concat("0b", logs), "LOGS") << std::endl; +} + +/** printVlnvFile +* \brief Display the value of the vlnv file. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printVlnvFileHwReport(std::ostream &file) const { + unsigned int numberOfDetectedIps; + std::vector vlnvFile; + if (readNumberOfDetectedIpsStatusRegister(numberOfDetectedIps) != mDrmApi_NO_ERROR) return; + if (readVlnvFileRegister(numberOfDetectedIps, vlnvFile) != mDrmApi_NO_ERROR) return; + file << fileName("VLNV") << std::endl; + file << registerValue(vlnvFile, "VLNV", -1) << std::endl; +} + +/** printLicenseFile +* \brief Display the license file. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printLicenseFileHwReport(std::ostream &file) const { + unsigned int numberOfDetectedIps; + std::string licenseFile; + unsigned int licenseFileSize = mLicenseFileHeaderWordNumber; + if (readNumberOfDetectedIpsStatusRegister(numberOfDetectedIps) != mDrmApi_NO_ERROR) return; + licenseFileSize += numberOfDetectedIps*mLicenseFileIpBlockWordNumber; + if (readLicenseFileRegister(licenseFileSize, licenseFile) != mDrmApi_NO_ERROR) return; + file << fileName("LICENSE") << std::endl; + file << registerValue(licenseFile, "LICENSE WORD", (DRM_CONTROLLER_SYSTEM_BUS_DATA_SIZE/DRM_CONTROLLER_NIBBLE_SIZE)*mLicenseWordRegisterWordNumber, 0) << std::endl; +} + +/** printTraceFile +* \brief Display the trace file. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printTraceFileHwReport(std::ostream &file) const { + unsigned int numberOfDetectedIps; + std::vector traceFile; + if (readNumberOfDetectedIpsStatusRegister(numberOfDetectedIps) != mDrmApi_NO_ERROR) return; + if (readTraceFileRegister(numberOfDetectedIps, traceFile) != mDrmApi_NO_ERROR) return; + // the number of digits to show the ip index + std::ostringstream writter; + writter << numberOfDetectedIps-1; + const unsigned int digits = writter.str().size(); + file << fileName("TRACE") << std::endl; + for (unsigned int ii = 0; ii < numberOfDetectedIps; ii++) { + // get the trace part for the current ip + std::vector currentTraceFile(traceFile.begin()+ii*mNumberOfTracesPerIp, traceFile.begin()+(ii+1)*mNumberOfTracesPerIp); + file << registerValue(currentTraceFile, concat(wsConcat("IP", padRight('0', digits, (int)ii)), " - Trace "), 0) << std::endl; + } +} + +/** printMailBoxFile +* \brief Display the value of the mailbox file. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_0::printMailBoxFileHwReport(std::ostream &file) const { + // read mailbox file + unsigned int readOnlyMailboxWordNumber, readWriteMailboxWordNumber; + std::vector readOnlyMailboxData, readWriteMailboxData; + if (readMailboxFileRegister(readOnlyMailboxWordNumber, readWriteMailboxWordNumber, readOnlyMailboxData, readWriteMailboxData) != mDrmApi_NO_ERROR) return; + file << fileName("MAILBOX") << std::endl; + file << registerValue(readOnlyMailboxWordNumber, "READ-ONLY MAILBOX WORD NUMBER") << std::endl; + file << registerValue(readOnlyMailboxData, "READ-ONLY MAILBOX", 0) << std::endl; + file << registerValue(readWriteMailboxWordNumber, "READ-WRITE MAILBOX WORD NUMBER") << std::endl; + file << registerValue(readWriteMailboxData, "READ-WRITE MAILBOX", 0) << std::endl; +} + +/** getMeteringFileHeader +* \brief Get the header of the metering file. +* \param[in] meteringFile is a list containing the metering file to retrieve the header from. +* \return Returns a list containing the metering file header. +**/ +std::vector DrmControllerRegistersStrategy_v4_2_0::getMeteringFileHeader(const std::vector &meteringFile) const { + return std::vector(next(meteringFile.begin(),mMeteringFileHeaderWordPosition*mMeteringWordRegisterWordNumber), + next(meteringFile.begin(),(mMeteringFileHeaderWordPosition+1)*mMeteringWordRegisterWordNumber)); +} + +/** getMeteringFileHeaderSessionId +* \brief Get the session id from the metering file header. +* \param[in] meteringFileHeader is a list containing the metering file header to retrieve the session id from. +* \return Returns a list containing the metering file session id. +**/ +std::vector DrmControllerRegistersStrategy_v4_2_0::getMeteringFileHeaderSessionId(const std::vector &meteringFileHeader) const { + return std::vector(meteringFileHeader.begin(), next(meteringFileHeader.begin(), 2)); +} + +/** getMeteringFileHeaderEncryptedMeteringFlag +* \brief Get the encrypted metering flag from the metering file header. +* \param[in] meteringFileHeader is a list containing the metering file header to retrieve the encrypted metering flag from. +* \return Returns true if the metering file is encrypted, false otherwize. +**/ +bool DrmControllerRegistersStrategy_v4_2_0::getMeteringFileHeaderEncryptedMeteringFlag(const std::vector &meteringFileHeader) const { + return (bits(17,0x00020000,*(prev(meteringFileHeader.end(),2))) == 1 ? true : false); +} + +/** getMeteringFileHeaderEndSessionMeteringFlag +* \brief Get the end session metering flag from the metering file header. +* \param[in] meteringFileHeader is a list containing the metering file header to retrieve the end session metering flag from. +* \return Returns true if the metering file is for an end session, false otherwize. +**/ +bool DrmControllerRegistersStrategy_v4_2_0::getMeteringFileHeaderEndSessionMeteringFlag(const std::vector &meteringFileHeader) const { + return (bits(16,0x00010000,*(prev(meteringFileHeader.end(),2))) == 1 ? true : false); +} + +/** getMeteringFileHeaderEnvironmentId +* \brief Get the environment id from the metering file header. +* \param[in] meteringFileHeader is a list containing the metering file header to retrieve the environment id from. +* \return Returns the environment id. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::getMeteringFileHeaderEnvironmentId(const std::vector &meteringFileHeader) const { + return bits(0,0x0000FFFF,*(prev(meteringFileHeader.end(),2))); +} + +/** getMeteringFileHeaderSegmentIndex +* \brief Get the segment index from the metering file header. +* \param[in] meteringFileHeader is a list containing the metering file header to retrieve the segment index from. +* \return Returns the segment index. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_0::getMeteringFileHeaderSegmentIndex(const std::vector &meteringFileHeader) const { + return *(prev(meteringFileHeader.end(),1)); +} + +/** getMeteringFileLicenseTimer +* \brief Get the license timer from the metering file. +* \param[in] meteringFile is a list containing the metering file to retrieve the license timer from. +* \return Returns a list containing the license timer retrieved from metering file. +**/ +std::vector DrmControllerRegistersStrategy_v4_2_0::getMeteringFileLicenseTimer(const std::vector &meteringFile) const { + return std::vector(next(meteringFile.begin(),mMeteringFileLicenseTimerCountWordPosition*mMeteringWordRegisterWordNumber+mSampledLicenseTimerCountRegisterWordNumber), + next(meteringFile.begin(),(mMeteringFileLicenseTimerCountWordPosition+1)*mMeteringWordRegisterWordNumber)); +} + +/** getMeteringFileIpMeteringData +* \brief Get the ip metering data from the metering file. +* \param[in] meteringFile is a list containing the metering file to retrieve the ip metering data from. +* \return Returns a list containing the ip metering retrieved from metering file. +**/ +std::vector DrmControllerRegistersStrategy_v4_2_0::getMeteringFileIpMeteringData(const std::vector &meteringFile) const { + return std::vector(next(meteringFile.begin(),mMeteringFileFirstIpMeteringDataWordPosition*mMeteringWordRegisterWordNumber), + prev(meteringFile.end(), (mMeteringFileMacWordFromEndPosition+1)*mMeteringWordRegisterWordNumber)); +} + +/** getMeteringFileMac +* \brief Get the mac from the metering file. +* \param[in] meteringFile is a list containing the metering file to retrieve the mac from. +* \return Returns a list containing the mac retrieved from metering file. +**/ +std::vector DrmControllerRegistersStrategy_v4_2_0::getMeteringFileMac(const std::vector &meteringFile) const { + return std::vector(prev(meteringFile.end(),(mMeteringFileMacWordFromEndPosition+1)*mMeteringWordRegisterWordNumber), + prev(meteringFile.end(),mMeteringFileMacWordFromEndPosition*mMeteringWordRegisterWordNumber)); +} diff --git a/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_2_1.cpp b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_2_1.cpp new file mode 100644 index 00000000..bb62d644 --- /dev/null +++ b/drm_controller_sdk/source/HAL/DrmControllerRegistersStrategy_v4_2_1.cpp @@ -0,0 +1,1803 @@ +/** +* \file DrmControllerRegistersStrategy_v4_2_1.cpp +* \version 4.2.1.0 +* \date July 2020 +* \brief Class DrmControllerRegistersStrategy_v4_2_1 defines strategy for register access of drm controller v4.2.1. +* \copyright Licensed under the Apache License, Version 2.0 (the "License") { + +} +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +#include + +// name space usage +using namespace DrmControllerLibrary; + +/************************************************************/ +/** PUBLIC MEMBER FUNCTIONS **/ +/************************************************************/ + +/** DrmControllerRegistersStrategy_v4_2_1 +* \brief Class constructor. +* \param[in] readRegisterFunction function pointer to read 32 bits register. +* The function pointer shall have the following prototype "unsigned int f(const std::string&, unsigned int&)". +* \param[in] writeRegisterFunction function pointer to write 32 bits register. +* The function pointer shall have the following prototype "unsigned int f(const std::string&, unsigned int)". +**/ +DrmControllerRegistersStrategy_v4_2_1::DrmControllerRegistersStrategy_v4_2_1(tDrmReadRegisterFunction readRegisterFunction, + tDrmWriteRegisterFunction writeRegisterFunction) +: DrmControllerRegistersStrategyInterface(readRegisterFunction, writeRegisterFunction), + mCommandRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_COMMAND_SIZE)), + mLicenseStartAddressRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_LICENSE_START_ADDRESS_SIZE)), + mLicenseTimerRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_LICENSE_TIMER_SIZE)), + mStatusRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_STATUS_SIZE)), + mErrorRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_ERROR_SIZE)), + mDnaRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_DEVICE_DNA_SIZE)), + mSaasChallengeRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_SAAS_CHALLENGE_SIZE)), + mSampledLicenseTimerCountRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_LICENSE_TIMER_COUNTER_SIZE)), + mVersionRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_VERSION_SIZE)), + mAdaptiveProportionTestFailuresRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_ADAPTIVE_PROPORTION_TEST_FAILURES_SIZE)), + mRepetitionCountTestFailuresRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_REPETITION_COUNT_TEST_FAILURES_SIZE)), + mVlnvWordRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_VLNV_WORD_SIZE)), + mLicenseWordRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_LICENSE_WORD_SIZE)), + mTraceWordRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_TRACE_WORD_SIZE)), + mMeteringWordRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_METERING_WORD_SIZE)), + mMailboxWordRegisterWordNumber(numberOfWords(DRM_CONTROLLER_V4_2_1_MAILBOX_WORD_SIZE)), + mCommandRegisterStartIndex(0), + mLicenseStartAddressRegisterStartIndex(mCommandRegisterStartIndex+mCommandRegisterWordNumber), + mLicenseTimerRegisterStartIndex(mLicenseStartAddressRegisterStartIndex+mLicenseStartAddressRegisterWordNumber), + mStatusRegisterStartIndex(mLicenseTimerRegisterStartIndex+mLicenseTimerRegisterWordNumber), + mErrorRegisterStartIndex(mStatusRegisterStartIndex+mStatusRegisterWordNumber), + mDnaRegisterStartIndex(mErrorRegisterStartIndex+mErrorRegisterWordNumber), + mSaasChallengeRegisterStartIndex(mDnaRegisterStartIndex+mDnaRegisterWordNumber), + mSampledLicenseTimerCountRegisterStartIndex(mSaasChallengeRegisterStartIndex+mSaasChallengeRegisterWordNumber), + mVersionRegisterStartIndex(mSampledLicenseTimerCountRegisterStartIndex+mSampledLicenseTimerCountRegisterWordNumber), + mAdaptiveProportionTestFailuresRegisterStartIndex(mVersionRegisterStartIndex+mVersionRegisterWordNumber), + mRepetitionCountTestFailuresRegisterStartIndex(mAdaptiveProportionTestFailuresRegisterStartIndex+mAdaptiveProportionTestFailuresRegisterWordNumber), + mLogsRegisterStartIndex(mRepetitionCountTestFailuresRegisterStartIndex+mRepetitionCountTestFailuresRegisterWordNumber), + mVlnvWordRegisterStartIndex(0), + mLicenseWordRegisterStartIndex(0), + mTraceWordRegisterStartIndex(0), + mMeteringWordRegisterStartIndex(0), + mMailboxWordRegisterStartIndex(0), + mNumberOfTracesPerIp(DRM_CONTROLLER_V4_2_1_NUMBER_OF_TRACES_PER_IP), + mVlnvNumberOfAdditionalWords(DRM_CONTROLLER_V4_2_1_VLNV_NUMBER_OF_ADDITIONAL_WORDS), + mMeteringNumberOfAdditionalWords(DRM_CONTROLLER_V4_2_1_METERING_NUMBER_OF_ADDITIONAL_WORDS), + mMailboxNumberOfAdditionalWords(DRM_CONTROLLER_V4_2_1_MAILBOX_NUMBER_OF_ADDITIONAL_WORDS), + mLicenseFileHeaderWordNumber(DRM_CONTROLLER_V4_2_1_LICENSE_HEADER_BLOCK_SIZE), + mLicenseFileIpBlockWordNumber(DRM_CONTROLLER_V4_2_1_LICENSE_IP_BLOCK_SIZE), + mLicenseFileMinimumWordNumber((mLicenseFileHeaderWordNumber+mLicenseFileIpBlockWordNumber)*mLicenseWordRegisterWordNumber), + mMeteringFileHeaderWordPosition(DRM_CONTROLLER_V4_2_1_METERING_FILE_HEADER_POSITION), + mMeteringFileLicenseTimerCountWordPosition(DRM_CONTROLLER_V4_2_1_METERING_FILE_LICENSE_TIMER_COUNT_POSITION), + mMeteringFileFirstIpMeteringDataWordPosition(DRM_CONTROLLER_V4_2_1_METERING_FILE_FIRST_IP_METERING_DATA_POSITION), + mMeteringFileMacWordFromEndPosition(DRM_CONTROLLER_V4_2_1_METERING_FILE_MAC_FROM_END_POSITION), + mDrmErrorRegisterMessagesArraySize(DRM_CONTROLLER_V4_2_1_NUMBER_OF_ERROR_CODES), + mDrmErrorRegisterMessagesArray({ + { mDrmErrorNotReady, "Not ready" }, + { mDrmErrorNoError, "No error" }, + { mDrmErrorBusReadAuthenticatorDrmVersionTimeOutError, "Bus read authenticator drm version timeout error" }, + { mDrmErrorAuthenticatorDrmVersionError, "Authenticator drm version error" }, + { mDrmErrorDnaAuthenticationError, "Authenticator authentication error" }, + { mDrmErrorBusWriteAuthenticatorCommandTimeOutError, "Bus write authenticator command timeout error" }, + { mDrmErrorBusReadAuthenticatorStatusTimeOutError, "Bus read authenticator status timeout error" }, + { mDrmErrorBusWriteAuthenticatorChallengeTimeOutError, "Bus write authenticator challenge timeout error" }, + { mDrmErrorBusReadAuthenticatorResponseTimeOutError, "Bus read authenticator response timeout error" }, + { mDrmErrorBusReadAuthenticatorDnaTimeOutError, "Bus read authenticator dna timeout error" }, + { mDrmErrorBusReadActivatorDrmVersionTimeOutError, "Bus read activator drm version timeout error" }, + { mDrmErrorActivatorDrmVersionError, "Activator drm version error" }, + { mDrmErrorLicenseHeaderCheckError, "License header check error" }, + { mDrmErrorLicenseDrmVersionError, "License drm version error" }, + { mDrmErrorLicenseDnaDeltaError, "License dna delta error" }, + { mDrmErrorLicenseMacCheckError, "License MAC check error" }, + { mDrmErrorBusWriteActivatorCommandTimeOutError, "Bus write activator command timeout error" }, + { mDrmErrorBusReadActivatorStatusTimeOutError, "Bus read activator status timeout error" }, + { mDrmErrorBusReadActivatorChallengeTimeOutError, "Bus read activator challenge timeout error" }, + { mDrmErrorBusWriteActivatorResponseTimeOutError, "Bus write activator response timeout error" }, + { mDrmErrorBusReadInterruptTimeOutError, "Bus read interrupt timeout error" }, + { mDrmErrorBusReadExpectedStatusError, "Bus read expected status error" } + }) +{ + setIndexedRegisterName(DRM_CONTROLLER_V4_2_1_INDEXED_REGISTER_NAME); +} + +/** ~DrmControllerRegistersStrategy_v4_2_1 +* \brief Class destructor. +**/ +DrmControllerRegistersStrategy_v4_2_1::~DrmControllerRegistersStrategy_v4_2_1() +{} + +/** writeRegistersPageRegister +* \brief Write the page register to select the registers page. +* This method will access to the system bus to write into the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeRegistersPageRegister() const { + return writePageRegister(mDrmPageRegisters); +} + +/** writeVlnvFilePageRegister +* \brief Write the page register to select the vlnv file page. +* This method will access to the system bus to write into the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeVlnvFilePageRegister() const { + return writePageRegister(mDrmPageVlnvFile); +} + +/** writeLicenseFilePageRegister +* \brief Write the page register to select the license file page. +* This method will access to the system bus to write into the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeLicenseFilePageRegister() const { + return writePageRegister(mDrmPageLicenseFile); +} + +/** writeTraceFilePageRegister +* \brief Write the page register to select the trace file page. +* This method will access to the system bus to write into the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeTraceFilePageRegister() const { + return writePageRegister(mDrmPageTraceFile); +} + +/** writeMeteringFilePageRegister +* \brief Write the page register to select the metering file page. +* This method will access to the system bus to write into the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeMeteringFilePageRegister() const { + return writePageRegister(mDrmPageMeteringFile); +} + +/** writeMailBoxFilePageRegister +* \brief Write the page register to select the mailbox file page. +* This method will access to the system bus to write into the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeMailBoxFilePageRegister() const { + return writePageRegister(mDrmPageMailboxFile); +} + +/** writeNopCommandRegister +* \brief Write the command register to the NOP Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeNopCommandRegister() const { + return writeCommandRegister(mDrmCommandNop); +} + +/** writeDnaExtractCommandRegister +* \brief Write the command register to the DNA Extract Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeDnaExtractCommandRegister() const { + return writeCommandRegister(mDrmCommandExtractDna); +} + +/** writeVlnvExtractCommandRegister +* \brief Write the command register to the VLNV Extract Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeVlnvExtractCommandRegister() const { + return writeCommandRegister(mDrmCommandExtractVlnv); +} + +/** writeActivateCommandRegister +* \brief Write the command register to the Activate Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeActivateCommandRegister() const { + return writeCommandRegister(mDrmCommandActivate); +} + +/** writeEndSessionMeteringExtractCommandRegister +* \brief Write the command register to the end session extract metering Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeEndSessionMeteringExtractCommandRegister() const { + return writeCommandRegister(mDrmCommandEndSessionExtractMetering); +} + +/** writeMeteringExtractCommandRegister +* \brief Write the command register to the extract metering Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeMeteringExtractCommandRegister() const { + return writeCommandRegister(mDrmCommandExtractMetering); +} + +/** writeSampleLicenseTimerCounterCommandRegister +* \brief Write the command register to the sample license timer counter Command. +* This method will access to the system bus to write into the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeSampleLicenseTimerCounterCommandRegister() const { + return writeCommandRegister(mDrmCommandSampleLicenseTimerCounter); +} + +/** readLicenseStartAddressRegister +* \brief Read the license start address register. +* This method will access to the system bus to read the license start address. +* \param[out] licenseStartAddress is a list of binary values for the license start address register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLicenseStartAddressRegister(std::vector &licenseStartAddress) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mLicenseStartAddressRegisterStartIndex, mLicenseStartAddressRegisterWordNumber, licenseStartAddress); +} + +/** writeLicenseStartAddressRegister +* \brief Write the license start address register. +* This method will access to the system bus to write the license start address. +* \param[in] licenseStartAddress is a list of binary values for the license start address register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeLicenseStartAddressRegister(const std::vector &licenseStartAddress) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return writeRegisterListFromIndex(mLicenseStartAddressRegisterStartIndex, mLicenseStartAddressRegisterWordNumber, licenseStartAddress); +} + +/** readLicenseTimerInitRegister +* \brief Read the license timer register. +* This method will access to the system bus to read the license timer. +* \param[out] licenseTimerInit is a list of binary values for the license timer register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLicenseTimerInitRegister(std::vector &licenseTimerInit) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mLicenseTimerRegisterStartIndex, mLicenseTimerRegisterWordNumber, licenseTimerInit); +} + +/** writeLicenseTimerInitRegister +* \brief Write the license start address register. +* This method will access to the system bus to write the license timer. +* \param[in] licenseTimerInit is a list of binary values for the license timer register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeLicenseTimerInitRegister(const std::vector &licenseTimerInit) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return writeRegisterListFromIndex(mLicenseTimerRegisterStartIndex, mLicenseTimerRegisterWordNumber, licenseTimerInit); +} + +/** readDnaReadyStatusRegister +* \brief Read the status register and get the dna ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] dnaReady is the value of the status bit DNA Ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readDnaReadyStatusRegister(bool &dnaReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusDnaReady, mDrmStatusMaskDnaReady, dnaReady); +} + +/** waitDnaReadyStatusRegister +* \brief Wait dna ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitDnaReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusDnaReady, mDrmStatusMaskDnaReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Dna Ready Status is in timeout", "Expected Dna Ready Status", "Actual Dna Ready Status", expected, actual); + return errorCode; +} + +/** readVlnvReadyStatusRegister +* \brief Read the status register and get the vlnv ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] vlnvReady is the value of the status bit VLNV Ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readVlnvReadyStatusRegister(bool &vlnvReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusVlnvReady, mDrmStatusMaskVlnvReady, vlnvReady); +} + +/** waitVlnvReadyStatusRegister +* \brief Wait vlnv ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitVlnvReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusVlnvReady, mDrmStatusMaskVlnvReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Vlnv Ready Status is in timeout", "Expected Vlnv Ready Status", "Actual Vlnv Ready Status", expected, actual); + return errorCode; +} + +/** readActivationDoneStatusRegister +* \brief Read the status register and get the activation done status bit. +* This method will access to the system bus to read the status register. +* \param[out] activationDone is the value of the status bit Activation Done. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readActivationDoneStatusRegister(bool &activationDone) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusActivationDone, mDrmStatusMaskActivationDone, activationDone); +} + +/** waitActivationDoneStatusRegister +* \brief Wait activation done status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitActivationDoneStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusActivationDone, mDrmStatusMaskActivationDone, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Activation Done Status is in timeout", "Expected Activation Done Status", "Actual Activation Done Status", expected, actual); + return errorCode; +} + +/** readAutonomousControllerEnabledStatusRegister +* \brief Read the status register and get the autonomous controller enabled status bit. +* This method will access to the system bus to read the status register. +* \param[out] autoEnabled is the value of the status bit autonomous controller enabled. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readAutonomousControllerEnabledStatusRegister(bool &autoEnabled) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusAutoEnabled, mDrmStatusMaskAutoEnabled, autoEnabled); + +} + +/** readAutonomousControllerBusyStatusRegister +* \brief Read the status register and get the autonomous controller busy status bit. +* This method will access to the system bus to read the status register. +* \param[out] autoBusy is the value of the status bit autonomous controller busy. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readAutonomousControllerBusyStatusRegister(bool &autoBusy) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusAutoBusy, mDrmStatusMaskAutoBusy, autoBusy); +} + +/** waitAutonomousControllerBusyStatusRegister +* \brief Wait autonomous controller busy status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitAutonomousControllerBusyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusAutoBusy, mDrmStatusMaskAutoBusy, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Autonomous Controller Busy Status is in timeout", "Expected Autonomous Controller Busy Status", "Actual Autonomous Controller Busy Status", expected, actual); + return errorCode; +} + +/** readMeteringEnabledStatusRegister +* \brief Read the status register and get the metering enabled status bit. +* This method will access to the system bus to read the status register. +* \param[out] meteringEnabled is the value of the status bit metering enabled. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readMeteringEnabledStatusRegister(bool &meteringEnabled) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusMeteringEnabled, mDrmStatusMaskMeteringEnabled, meteringEnabled); + +} + +/** readMeteringReadyStatusRegister +* \brief Read the status register and get the metering ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] meteringReady is the value of the status bit metering ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readMeteringReadyStatusRegister(bool &meteringReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusMeteringReady, mDrmStatusMaskMeteringReady, meteringReady); +} + +/** waitMeteringReadyStatusRegister +* \brief Wait metering ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitMeteringReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusMeteringReady, mDrmStatusMaskMeteringReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Metering Ready Status is in timeout", "Expected Metering Ready Status", "Actual Metering Ready Status", expected, actual); + return errorCode; +} + +/** readSaasChallengeReadyStatusRegister +* \brief Read the status register and get the saas challenge ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] saasChallengeReady is the value of the status bit saas challenge ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readSaasChallengeReadyStatusRegister(bool &saasChallengeReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusSaasChallengeReady, mDrmStatusMaskSaasChallengeReady, saasChallengeReady); +} + +/** waitSaasChallengeReadyStatusRegister +* \brief Wait saas challenge ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitSaasChallengeReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusSaasChallengeReady, mDrmStatusMaskSaasChallengeReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Saas Challenge Ready Status is in timeout", "Expected Saas Challenge Ready Status", "Actual Saas Challenge Ready Status", expected, actual); + return errorCode; +} + +/** readLicenseTimerEnabledStatusRegister +* \brief Read the status register and get the license timer enabled status bit. +* This method will access to the system bus to read the status register. +* \param[out] licenseTimerEnabled is the value of the status bit license timer enabled. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLicenseTimerEnabledStatusRegister(bool &licenseTimerEnabled) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseTimerEnabled, mDrmStatusMaskLicenseTimerEnabled, licenseTimerEnabled); +} + +/** readLicenseTimerInitLoadedStatusRegister +* \brief Read the status register and get the license timer init loaded status bit. +* This method will access to the system bus to read the status register. +* \param[out] licenseTimerInitLoaded is the value of the status bit license timer init load. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLicenseTimerInitLoadedStatusRegister(bool &licenseTimerInitLoaded) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseTimerInitLoaded, mDrmStatusMaskLicenseTimerInitLoaded, licenseTimerInitLoaded); +} + +/** waitLicenseTimerInitLoadedStatusRegister +* \brief Wait license timer init loaded status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitLicenseTimerInitLoadedStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusLicenseTimerInitLoaded, mDrmStatusMaskLicenseTimerInitLoaded, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait License Timer Init Loaded Status is in timeout", "Expected License Timer Init Loaded Status", "Actual License Timer Init Loaded Status", expected, actual); + return errorCode; +} + +/** readEndSessionMeteringReadyStatusRegister +* \brief Read the status register and get the end session metering ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] endSessionMeteringReady is the value of the status bit end session metering ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readEndSessionMeteringReadyStatusRegister(bool &endSessionMeteringReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusEndSessionMeteringReady, mDrmStatusMaskEndSessionMeteringReady, endSessionMeteringReady); +} + +/** waitEndSessionMeteringReadyStatusRegister +* \brief Wait end session metering ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitEndSessionMeteringReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusEndSessionMeteringReady, mDrmStatusMaskEndSessionMeteringReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait End Session Metering Ready Status is in timeout", "Expected End Session Metering Ready Status", "Actual End Session Metering Ready Status", expected, actual); + return errorCode; +} + +/** readHeartBeatModeEnabledStatusRegister +* \brief Read the status register and get the heart beat mode enabled status bit. +* This method will access to the system bus to read the status register. +* \param[out] heartBeatModeEnabled is the value of the status bit heart beat mode enabled. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readHeartBeatModeEnabledStatusRegister(bool &heartBeatModeEnabled) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusHeartBeatModeEnabled, mDrmStatusMaskHeartBeatModeEnabled, heartBeatModeEnabled); +} + +/** readAsynchronousMeteringReadyStatusRegister +* \brief Read the status register and get the asynchronous metering ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] asynchronousMeteringReady is the value of the status bit asynchronous metering ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readAsynchronousMeteringReadyStatusRegister(bool &asynchronousMeteringReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusAsynchronousMeteringReady, mDrmStatusMaskAsynchronousMeteringReady, asynchronousMeteringReady); +} + +/** waitAsynchronousMeteringReadyStatusRegister +* \brief Wait asynchronous metering ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitAsynchronousMeteringReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusAsynchronousMeteringReady, mDrmStatusMaskAsynchronousMeteringReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Asynchronous Metering Ready Status is in timeout", "Expected Asynchronous Metering Ready Status", "Actual Asynchronous Metering Ready Status", expected, actual); + return errorCode; +} + +/** readLicenseTimerSampleReadyStatusRegister +* \brief Read the status register and get the license timer sample ready status bit. +* This method will access to the system bus to read the status register. +* \param[out] licenseTimerSampleReady is the value of the status bit license timer sample ready. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLicenseTimerSampleReadyStatusRegister(bool &licenseTimerSampleReady) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseTimerSampleReady, mDrmStatusMaskLicenseTimerSampleReady, licenseTimerSampleReady); +} + +/** waitLicenseTimerSampleReadyStatusRegister +* \brief Wait license timer sample ready status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitLicenseTimerSampleReadyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusLicenseTimerSampleReady, mDrmStatusMaskLicenseTimerSampleReady, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait License Timer Sample Ready Status is in timeout", "Expected License Timer Sample Ready Status", "Actual License Timer Sample Ready Status", expected, actual); + return errorCode; +} + +/** readLicenseTimerCountEmptyStatusRegister +* \brief Read the status register and get the license timer count empty status bit. +* This method will access to the system bus to read the status register. +* \param[out] licenseTimerCounterEmpty is the value of the status bit license timer count empty. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLicenseTimerCountEmptyStatusRegister(bool &licenseTimerCounterEmpty) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseTimerCountEmpty, mDrmStatusMaskLicenseTimerCountEmpty, licenseTimerCounterEmpty); +} + +/** waitLicenseTimerCountEmptyStatusRegister +* \brief Wait license timer count empty status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitLicenseTimerCountEmptyStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusLicenseTimerCountEmpty, mDrmStatusMaskLicenseTimerCountEmpty, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait License Timer Count Empty Status is in timeout", "Expected License Timer Count Empty Status", "Actual License Timer Count Empty Status", expected, actual); + return errorCode; +} + +/** readSessionRunningStatusRegister +* \brief Read the status register and get the session running status bit. +* This method will access to the system bus to read the status register. +* \param[out] sessionRunning is the value of the status bit session running. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readSessionRunningStatusRegister(bool &sessionRunning) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusSessionRunning, mDrmStatusMaskSessionRunning, sessionRunning); +} + +/** waitSessionRunningStatusRegister +* \brief Wait session running status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitSessionRunningStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusSessionRunning, mDrmStatusMaskSessionRunning, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Session Running Status is in timeout", "Expected Session Running Status", "Actual Session Running Status", expected, actual); + return errorCode; +} + +/** readActivationCodesTransmittedStatusRegister +* \brief Read the status register and get the activation codes transmitted status bit. +* This method will access to the system bus to read the status register. +* \param[out] activationCodeTransmitted is the value of the status bit activation codes transmitted. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readActivationCodesTransmittedStatusRegister(bool &activationCodeTransmitted) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusActivationCodesTransmitted, mDrmStatusMaskActivationCodesTransmitted, activationCodeTransmitted); +} + +/** waitActivationCodesTransmittedStatusRegister +* \brief Wait activation codes transmitted status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitActivationCodesTransmittedStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusActivationCodesTransmitted, mDrmStatusMaskActivationCodesTransmitted, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Activation Codes Transmitted Status is in timeout", "Expected Activation Codes Transmitted Status", "Actual Activation Codes Transmitted Status", expected, actual); + return errorCode; +} + +/** readLicenseNodeLockStatusRegister +* \brief Read the status register and get the license node lock status bit. +* This method will access to the system bus to read the status register. +* \param[out] licenseNodeLock is the value of the status bit license node lock. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLicenseNodeLockStatusRegister(bool &licenseNodeLock) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseNodeLock, mDrmStatusMaskLicenseNodeLock, licenseNodeLock); +} + +/** waitLicenseNodeLockStatusRegister +* \brief Wait license node lock status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitLicenseNodeLockStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusLicenseNodeLock, mDrmStatusMaskLicenseNodeLock, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait License Node Lock Status is in timeout", "Expected License Node Lock Status", "Actual License Node Lock Status", expected, actual); + return errorCode; +} + +/** readLicenseMeteringStatusRegister +* \brief Read the status register and get the license metering status bit. +* This method will access to the system bus to read the status register. +* \param[out] licenseMetering is the value of the status bit license metering. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLicenseMeteringStatusRegister(bool &licenseMetering) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseMetering, mDrmStatusMaskLicenseMetering, licenseMetering); +} + +/** waitLicenseMeteringStatusRegister +* \brief Wait license metering status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitLicenseMeteringStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusLicenseMetering, mDrmStatusMaskLicenseMetering, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait License Metering Status is in timeout", "Expected License Metering Status", "Actual License Metering Status", expected, actual); + return errorCode; +} + +/** readSecurityAlertStatusRegister +* \brief Read the status register and get the Security Alert status bit. +* This method will access to the system bus to read the status register. +* \param[out] securityAlert is the value of the status bit Security Alert. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readSecurityAlertStatusRegister(bool &securityAlert) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusSecurityAlert, mDrmStatusMaskSecurityAlert, securityAlert); +} + +/** waitSecurityAlertStatusRegister +* \brief Wait Security Alert status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status bit read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitSecurityAlertStatusRegister(const unsigned int &timeout, const bool &expected, bool &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusSecurityAlert, mDrmStatusMaskSecurityAlert, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Security Alert Status is in timeout", "Expected Security Alert Status", "Actual Security Alert Status", expected, actual); + return errorCode; +} + +/** readNumberOfLicenseTimerLoadedStatusRegister +* \brief Read the status register and get the number of license timer loaded. +* This method will access to the system bus to read the status register. +* \param[out] numberOfLicenseTimerLoaded is the number of license timer loaded retrieved from the status. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readNumberOfLicenseTimerLoadedStatusRegister(unsigned int &numberOfLicenseTimerLoaded) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusLicenseTimerLoadedNumberLsb, mDrmStatusMaskLicenseTimerLoadedNumber, numberOfLicenseTimerLoaded); +} + +/** waitNumberOfLicenseTimerLoadedStatusRegister +* \brief Wait number of license timer loaded status register to reach specified value. +* This method will access to the system bus to read the status register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the status to be expected. +* \param[out] actual is the value of the status read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitNumberOfLicenseTimerLoadedStatusRegister(const unsigned int &timeout, const unsigned int &expected, unsigned int &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitStatusRegister(timeout, mDrmStatusLicenseTimerLoadedNumberLsb, mDrmStatusMaskLicenseTimerLoadedNumber, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Number Of License Timer Loaded Status is in timeout", "Expected Number Of License Timer Loaded Status", "Actual Number Of License Timer Loaded Status", expected, actual); + return errorCode; +} + +/** readNumberOfDetectedIpsStatusRegister +* \brief Read the status register and get the number of detected IPs. +* This method will access to the system bus to read the status register. +* \param[out] numberOfDetectedIps is the number of detected ips retrieved from the status. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readNumberOfDetectedIpsStatusRegister(unsigned int &numberOfDetectedIps) const { + return DrmControllerRegistersStrategyInterface::readStatusRegister(mDrmStatusIpActivatorNumberLsb, mDrmStatusMaskIpActivatorNumber, numberOfDetectedIps); +} + +/** readExtractDnaErrorRegister +* \brief Read the error register and get the error code related to dna extraction. +* This method will access to the system bus to read the error register. +* \param[out] dnaExtractError is the error code related to dna extraction. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readExtractDnaErrorRegister(unsigned char &dnaExtractError) const { + return DrmControllerRegistersStrategyInterface::readErrorRegister(mDrmDnaExtractErrorPosition, mDrmDnaExtractErrorMask, dnaExtractError); +} + +/** waitExtractDnaErrorRegister +* \brief Wait error to reach specified value. +* This method will access to the system bus to read the error register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the error to be expected. +* \param[out] actual is the value of the error read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitExtractDnaErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitErrorRegister(timeout, mDrmDnaExtractErrorPosition, mDrmDnaExtractErrorMask, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Extract Dna Error is in timeout", "Expected Extract Dna Error", "Actual Extract Dna Error", expected, actual, getDrmErrorRegisterMessage(expected), getDrmErrorRegisterMessage(actual)); + return errorCode; +} + +/** readExtractVlnvErrorRegister +* \brief Read the error register and get the error code related to vlnv extraction. +* This method will access to the system bus to read the error register. +* \param[out] vlnvExtractError is the error code related to vlnv extraction. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readExtractVlnvErrorRegister(unsigned char &vlnvExtractError) const { + return DrmControllerRegistersStrategyInterface::readErrorRegister(mDrmVlnvExtractErrorPosition, mDrmVlnvExtractErrorMask, vlnvExtractError); +} + +/** waitExtractVlnvErrorRegister +* \brief Wait error to reach specified value. +* This method will access to the system bus to read the error register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the error to be expected. +* \param[out] actual is the value of the error read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitExtractVlnvErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitErrorRegister(timeout, mDrmVlnvExtractErrorPosition, mDrmVlnvExtractErrorMask, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Extract Vlnv Error is in timeout", "Expected Extract Vlnv Error", "Actual Extract Vlnv Error", expected, actual, getDrmErrorRegisterMessage(expected), getDrmErrorRegisterMessage(actual)); + return errorCode; +} + +/** readActivationErrorRegister +* \brief Read the error register and get the error code related to activation. +* This method will access to the system bus to read the error register. +* \param[out] activationError is the error code related to activation. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readActivationErrorRegister(unsigned char &activationError) const { + return DrmControllerRegistersStrategyInterface::readErrorRegister(mDrmActivationErrorPosition, mDrmActivationErrorMask, activationError); +} + +/** waitActivationErrorRegister +* \brief Wait error to reach specified value. +* This method will access to the system bus to read the error register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the error to be expected. +* \param[out] actual is the value of the error read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitActivationErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitErrorRegister(timeout, mDrmActivationErrorPosition, mDrmActivationErrorMask, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait Activation Error is in timeout", "Expected Activation Error", "Actual Activation Error", expected, actual, getDrmErrorRegisterMessage(expected), getDrmErrorRegisterMessage(actual)); + return errorCode; +} + +/** readLicenseTimerLoadErrorRegister +* \brief Read the error register and get the error code related to license timer loading. +* This method will access to the system bus to read the error register. +* \param[out] licenseTimerLoadError is the error code related to license timer loading. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLicenseTimerLoadErrorRegister(unsigned char &licenseTimerLoadError) const { + return DrmControllerRegistersStrategyInterface::readErrorRegister(mDrmLicenseTimerLoadErrorPosition, mDrmLicenseTimerLoadErrorMask, licenseTimerLoadError); +} + +/** waitActivationErrorRegister +* \brief Wait error to reach specified value. +* This method will access to the system bus to read the error register. +* \param[in] timeout is the timeout value in micro seconds. +* \param[in] expected is the value of the error to be expected. +* \param[out] actual is the value of the error read. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_HARDWARE_TIMEOUT_ERROR if a timeout occured, errors from read/write register functions otherwize. +* \throw DrmControllerTimeOutException whenever a timeout error occured. DrmControllerTimeOutException::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::waitLicenseTimerLoadErrorRegister(const unsigned int &timeout, const unsigned char &expected, unsigned char &actual) const { + unsigned int errorCode = DrmControllerRegistersStrategyInterface::waitErrorRegister(timeout, mDrmLicenseTimerLoadErrorPosition, mDrmLicenseTimerLoadErrorMask, expected, actual); + if (errorCode == mDrmApi_HARDWARE_TIMEOUT_ERROR) + throwTimeoutException("Wait License Timer Load Error is in timeout", "Expected License Timer Load Error", "Actual License Timer Load Error", expected, actual, getDrmErrorRegisterMessage(expected), getDrmErrorRegisterMessage(actual)); + return errorCode; +} + +/** readDnaRegister +* \brief Read the dna register and get the value. +* This method will access to the system bus to read the dna register. +* \param[out] dna is the dna value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readDnaRegister(std::vector &dna) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mDnaRegisterStartIndex, mDnaRegisterWordNumber, dna); +} + +/** readSaasChallengeRegister +* \brief Read the Saas Challenge register and get the value. +* This method will access to the system bus to read the Saas Challenge register. +* \param[out] saasChallenge is the saas challenge value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readSaasChallengeRegister(std::vector &saasChallenge) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mSaasChallengeRegisterStartIndex, mSaasChallengeRegisterWordNumber, saasChallenge); +} + +/** readLicenseTimerCounterRegister +* \brief Read the License Timer Counter register and get the value. +* This method will access to the system bus to read the License Timer Counter register. +* \param[out] licenseTimerCounter is the License Timer Counter value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLicenseTimerCounterRegister(std::vector &licenseTimerCounter) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mSampledLicenseTimerCountRegisterStartIndex, mSampledLicenseTimerCountRegisterWordNumber, licenseTimerCounter); +} + +/** readDrmVersionRegister +* \brief Read the drm version register and get the value. +* This method will access to the system bus to read the drm version register. +* \param[out] drmVersion is the drm version value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readDrmVersionRegister(unsigned int &drmVersion) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterAtIndex(mVersionRegisterStartIndex, drmVersion); +} + +/** readAdaptiveProportionTestFailuresRegister +* \brief Read the Adaptive Proportion Test Failures register and get the value. +* This method will access to the system bus to read the Adaptive Proportion Test Failures register. +* \param[out] adaptiveProportionTestFailures is the Adaptive Proportion Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readAdaptiveProportionTestFailuresRegister(std::vector &adaptiveProportionTestFailures) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mAdaptiveProportionTestFailuresRegisterStartIndex, mAdaptiveProportionTestFailuresRegisterWordNumber, adaptiveProportionTestFailures); +} + +/** readRepetitionCountTestFailuresRegister +* \brief Read the Repetition Count Test Failures register and get the value. +* This method will access to the system bus to read the Repetition Count Test Failures register. +* \param[out] repetitionCountTestFailures is the Repetition Count Test Failures value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readRepetitionCountTestFailuresRegister(std::vector &repetitionCountTestFailures) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mRepetitionCountTestFailuresRegisterStartIndex, mRepetitionCountTestFailuresRegisterWordNumber, repetitionCountTestFailures); +} + +/** readLogsRegister +* \brief Read the logs register and get the value. +* This method will access to the system bus to read the logs register. +* \param[in] numberOfIps is the total number of IPs. +* \param[out] logs is the logs value. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLogsRegister(const unsigned int &numberOfIps, std::vector &logs) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mLogsRegisterStartIndex, numberOfWords(numberOfIps), logs); +} + +/** readVlnvFileRegister +* \brief Read the vlnv file and get the value. +* This method will access to the system bus to read the vlnv file. +* The vlnv file will contains numberOfIps+1 words. The first one +* is dedicated to the drm controller, the others correspond for +* the IPs connected to the drm controller. +* \param[in] numberOfIps is the total number of IPs. +* \param[out] vlnvFile is the vlnv file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readVlnvFileRegister(const unsigned int &numberOfIps, std::vector &vlnvFile) const { + unsigned int errorCode = writeVlnvFilePageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mVlnvWordRegisterStartIndex, mVlnvWordRegisterWordNumber*(numberOfIps+mVlnvNumberOfAdditionalWords), vlnvFile); +} + +/** readVlnvFileRegister +* \brief Read the vlnv file and get the value. +* This method will access to the system bus to read the vlnv file. +* The vlnv file will contains numberOfIps+1 elements. The first one +* is dedicated to the drm controller, the others correspond for +* the IPs connected to the drm controller. +* \param[in] numberOfIPs is the total number of IPs. +* \param[out] vlnvFile is the vlnv file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readVlnvFileRegister(const unsigned int &numberOfIPs, std::vector &vlnvFile) const { + std::vector tmpVlnvFile; + unsigned int errorCode = readVlnvFileRegister(numberOfIPs, tmpVlnvFile); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + vlnvFile = DrmControllerDataConverter::binaryToHexStringList(tmpVlnvFile, mVlnvWordRegisterWordNumber); + return errorCode; +} + +/** readLicenseFileRegister +* \brief Read the license file and get the value. +* This method will access to the system bus to read the license file. +* \param[in] licenseFileSize is the number of 128 bits words to read. +* \param[out] licenseFile is the license file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLicenseFileRegister(const unsigned int &licenseFileSize, std::vector &licenseFile) const { + unsigned int errorCode = writeLicenseFilePageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mLicenseWordRegisterStartIndex, mLicenseWordRegisterWordNumber*licenseFileSize, licenseFile); +} + +/** readLicenseFileRegister +* \brief Read the license file and get the value. +* This method will access to the system bus to read the license file. +* The license file is a string using a hexadecimal representation. +* \param[in] licenseFileSize is the number of 128 bits words to read. +* \param[out] licenseFile is the license file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readLicenseFileRegister(const unsigned int &licenseFileSize, std::string &licenseFile) const { + std::vector tmpLicense; + unsigned int errorCode = readLicenseFileRegister(licenseFileSize, tmpLicense); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + licenseFile = DrmControllerDataConverter::binaryToHexString(tmpLicense); + return errorCode; +} + +/** writeLicenseFile +* \brief Write the license file. +* This method will access to the system bus to write the license file. +* \param[in] licenseFileSize is the number of 128 bits words to read. +* \param[in] licenseFile is the license file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeLicenseFileRegister(const unsigned int &licenseFileSize, const std::vector &licenseFile) const { + unsigned int errorCode = writeLicenseFilePageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return writeRegisterListFromIndex(mLicenseWordRegisterStartIndex, mLicenseWordRegisterWordNumber*licenseFileSize, licenseFile); +} + +/** writeLicenseFileRegister +* \brief Write the license file. +* This method will access to the system bus to write the license file. +* The license file is a string using a hexadecimal representation. +* \param[in] licenseFile is the license file. +* \return Returns mDrmApi_NO_ERROR if no error, +* mDrmApi_LICENSE_FILE_SIZE_ERROR if the license file size is lower than the minimum required, +* or the error code produced by the read/write register function. +* \throw DrmControllerLicenseFileSizeException whenever a check on license file size is bad. DrmControllerLicenseFileSizeException::what() +* should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeLicenseFileRegister(const std::string &licenseFile) const { + std::vector tmpLicenseFile = DrmControllerDataConverter::hexStringToBinary(licenseFile); + if (checkLicenseFileSize(tmpLicenseFile) == false) return mDrmApi_LICENSE_FILE_SIZE_ERROR; + unsigned int licenseFileSize = tmpLicenseFile.size()/mLicenseWordRegisterWordNumber; + return writeLicenseFileRegister(licenseFileSize, tmpLicenseFile); +} + +/** readTraceFileRegister +* \brief Read the trace file and get the value. +* This method will access to the system bus to read the trace file. +* \param[in] numberOfIps is the total number of IPs. +* \param[out] traceFile is the trace file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readTraceFileRegister(const unsigned int &numberOfIps, std::vector &traceFile) const { + unsigned int errorCode = writeTraceFilePageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mTraceWordRegisterStartIndex, mTraceWordRegisterWordNumber*numberOfIps*mNumberOfTracesPerIp, traceFile); +} + +/** readTraceFileRegister +* \brief Read the trace file and get the value. +* This method will access to the system bus to read the trace file. +* \param[in] numberOfIPs is the total number of IPs. +* \param[out] traceFile is the trace file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readTraceFileRegister(const unsigned int &numberOfIPs, std::vector &traceFile) const { + std::vector tmpTraceFile; + unsigned int errorCode = readTraceFileRegister(numberOfIPs, tmpTraceFile); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + traceFile = DrmControllerDataConverter::binaryToHexStringList(tmpTraceFile, mTraceWordRegisterWordNumber); + return errorCode; +} + +/** readMeteringFileRegister +* \brief Read the metering file and get the value. +* This method will access to the system bus to read the metering file. +* \param[in] numberOfIps is the total number of IPs. +* \param[out] meteringFile is the metering file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readMeteringFileRegister(const unsigned int &numberOfIps, std::vector &meteringFile) const { + unsigned int errorCode = writeMeteringFilePageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterListFromIndex(mMeteringWordRegisterStartIndex, mMeteringWordRegisterWordNumber*(numberOfIps+mMeteringNumberOfAdditionalWords), meteringFile); +} + +/** readMeteringFileRegister +* \brief Read the metering file and get the value. +* This method will access to the system bus to read the metering file. +* \param[in] numberOfIPs is the total number of IPs. +* \param[out] meteringFile is the metering file. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readMeteringFileRegister(const unsigned int &numberOfIPs, std::vector &meteringFile) const { + std::vector tmpMeteringFile; + unsigned int errorCode = readMeteringFileRegister(numberOfIPs, tmpMeteringFile); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + meteringFile = DrmControllerDataConverter::binaryToHexStringList(tmpMeteringFile, mMeteringWordRegisterWordNumber); + return errorCode; +} + +/** readMailboxFileSizeRegister +* \brief Read the mailbox file word numbers. +* This method will access to the system bus to read the mailbox file. +* \param[out] readOnlyMailboxWordNumber is the number of words in the read-only mailbox. +* \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readMailboxFileSizeRegister(unsigned int &readOnlyMailboxWordNumber, unsigned int &readWriteMailboxWordNumber) const { + unsigned int errorCode = writeMailBoxFilePageRegister(); + // read data at file start index + unsigned int mailboxSize; + errorCode = readRegisterAtIndex(mMailboxWordRegisterStartIndex, mailboxSize); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + // update sizes + readOnlyMailboxWordNumber = bits((unsigned int)mDrmMailboxFileReadOnlyMailboxWordNumberLsb, (unsigned int)mDrmMailboxFileMaskReadOnlyMailboxWordNumber, mailboxSize); + readWriteMailboxWordNumber = bits((unsigned int)mDrmMailboxFileReadWriteMailboxWordNumberLsb, (unsigned int)mDrmMailboxFileMaskReadWriteMailboxWordNumber, mailboxSize); + // return error result + return errorCode; +} + +/** readMailboxFileRegister +* \brief Read the mailbox file. +* This method will access to the system bus to read the mailbox file. +* \param[out] readOnlyMailboxWordNumber is the number of words in the read-only mailbox. +* \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. +* \param[out] readOnlyMailboxData is the data read from the read-only mailbox. +* \param[out] readWriteMailboxData is the data read from the read-write mailbox. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readMailboxFileRegister(unsigned int &readOnlyMailboxWordNumber, unsigned int &readWriteMailboxWordNumber, + std::vector &readOnlyMailboxData, std::vector &readWriteMailboxData) const { + // get mailbox sizes + unsigned int errorCode = readMailboxFileSizeRegister(readOnlyMailboxWordNumber, readWriteMailboxWordNumber); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + // read the read only mailbox + errorCode = readRegisterListFromIndex(mMailboxWordRegisterStartIndex + mMailboxNumberOfAdditionalWords, readOnlyMailboxWordNumber * mMailboxWordRegisterWordNumber, readOnlyMailboxData); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + // read the read write mailbox + return readRegisterListFromIndex(mMailboxWordRegisterStartIndex + readOnlyMailboxWordNumber * mMailboxWordRegisterWordNumber + mMailboxNumberOfAdditionalWords, + readWriteMailboxWordNumber * mMailboxWordRegisterWordNumber, readWriteMailboxData); +} + +/** readMailboxFileRegister +* \brief Read the mailbox file. +* This method will access to the system bus to read the mailbox file. +* \param[out] readOnlyMailboxWordNumber is the number of words in the read-only mailbox. +* \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. +* \param[out] readOnlyMailboxData is the data read from the read-only mailbox. +* \param[out] readWriteMailboxData is the data read from the read-write mailbox. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readMailboxFileRegister(unsigned int &readOnlyMailboxWordNumber, unsigned int &readWriteMailboxWordNumber, + std::vector &readOnlyMailboxData, std::vector &readWriteMailboxData) const { + std::vector tmpReadOnlyMailboxData, tmpReadWriteMailboxData; + unsigned int errorCode = readMailboxFileRegister(readOnlyMailboxWordNumber, readWriteMailboxWordNumber, tmpReadOnlyMailboxData, tmpReadWriteMailboxData); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + readOnlyMailboxData = DrmControllerDataConverter::binaryToHexStringList(tmpReadOnlyMailboxData, mMailboxWordRegisterWordNumber); + readWriteMailboxData = DrmControllerDataConverter::binaryToHexStringList(tmpReadWriteMailboxData, mMailboxWordRegisterWordNumber); + return errorCode; +} + +/** writeMailboxFileRegister +* \brief Write the mailbox file. +* This method will access to the system bus to write the mailbox file. +* \param[in] readWriteMailboxData is the data to write into the read-write mailbox. +* \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeMailboxFileRegister(const std::vector &readWriteMailboxData, unsigned int &readWriteMailboxWordNumber) const { + // read mailbox + unsigned int tmpReadOnlyMailboxWordNumber; + std::vector tmpReadOnlyMailboxData, tmpReadWriteMailboxData; + unsigned int errorCode = readMailboxFileRegister(tmpReadOnlyMailboxWordNumber, readWriteMailboxWordNumber, tmpReadOnlyMailboxData, tmpReadWriteMailboxData); + if (errorCode != mDrmApi_NO_ERROR || tmpReadWriteMailboxData == readWriteMailboxData) return errorCode; + // write the read write mailbox + return writeRegisterListFromIndex(mMailboxWordRegisterStartIndex + tmpReadOnlyMailboxWordNumber * mMailboxWordRegisterWordNumber + mMailboxNumberOfAdditionalWords, + readWriteMailboxWordNumber * mMailboxWordRegisterWordNumber, readWriteMailboxData); +} + +/** writeMailboxFileRegister +* \brief Write the mailbox file. +* This method will access to the system bus to write the mailbox file. +* \param[in] readWriteMailboxData is the data to write into the read-write mailbox. +* \param[out] readWriteMailboxWordNumber is the number of words in the read-write mailbox. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeMailboxFileRegister(const std::vector &readWriteMailboxData, unsigned int &readWriteMailboxWordNumber) const { + return writeMailboxFileRegister(DrmControllerDataConverter::hexStringListToBinary(readWriteMailboxData), readWriteMailboxWordNumber); +} + +/** printMeteringFile +* \brief Display the value of the metering file. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printMeteringFileHwReport(std::ostream &file) const { + unsigned int numberOfDetectedIps; + std::vector meteringFile; + if (readNumberOfDetectedIpsStatusRegister(numberOfDetectedIps) != mDrmApi_NO_ERROR) return; + if (readMeteringFileRegister(numberOfDetectedIps, meteringFile) != mDrmApi_NO_ERROR) return; + bool meteringFileEncrypted(getMeteringFileHeaderEncryptedMeteringFlag(getMeteringFileHeader(meteringFile))); + std::string environmentId(DrmControllerDataConverter::binaryToHexString(getMeteringFileHeaderEnvironmentId(getMeteringFileHeader(meteringFile)))); + if (meteringFileEncrypted == true) + file << fileName("ENCRYPTED METERING") << std::endl; + else + file << fileName("PLAIN METERING") << std::endl; + file << registerValue(DrmControllerDataConverter::binaryToHexString(getMeteringFileHeaderSessionId(getMeteringFileHeader(meteringFile))), "SESSION ID") << std::endl; + file << registerValue(meteringFileEncrypted, "ENCRYPTED METERING FLAG") << std::endl; + file << registerValue(getMeteringFileHeaderEndSessionMeteringFlag(getMeteringFileHeader(meteringFile)), "END SESSION METERING FLAG") << std::endl; + file << registerValue(environmentId.substr(4), "ENVIRONMENT ID") << std::endl; + file << registerValue(DrmControllerDataConverter::binaryToHexString(getMeteringFileHeaderSegmentIndex(getMeteringFileHeader(meteringFile))), "SEGMENT INDEX") << std::endl; + file << registerValue(DrmControllerDataConverter::binaryToHexString(getMeteringFileLicenseTimer(meteringFile)), "LICENSE TIMER COUNT") << std::endl; + if (meteringFileEncrypted == false) { + std::vector ipMeteringData(getMeteringFileIpMeteringData(meteringFile)); + for (unsigned int ii = 0; ii < numberOfDetectedIps; ii++) { + std::vector ipIndex(next(ipMeteringData.begin(),ii*mMeteringWordRegisterWordNumber),next(ipMeteringData.begin(),ii*mMeteringWordRegisterWordNumber+mMeteringWordRegisterWordNumber/2)); + std::vector ipMetering(next(ipMeteringData.begin(),ii*mMeteringWordRegisterWordNumber+mMeteringWordRegisterWordNumber/2),next(ipMeteringData.begin(),(ii+1)*mMeteringWordRegisterWordNumber)); + std::ostringstream writter; + writter << "IP INDEX 0x" << DrmControllerDataConverter::binaryToHexString(ipIndex) << " PLAIN METERING"; + file << registerValue(DrmControllerDataConverter::binaryToHexString(ipMetering), writter.str()) << std::endl; + } + } + else + file << registerValue(DrmControllerDataConverter::binaryToHexStringList(getMeteringFileIpMeteringData(meteringFile),mMeteringWordRegisterWordNumber), "ENCRYPTED IP METERING DATA", 0) << std::endl; + file << registerValue(DrmControllerDataConverter::binaryToHexString(getMeteringFileMac(meteringFile)), "MAC") << std::endl; +} + +/** getDrmErrorRegisterMessage +* \brief Get the error message from the error register value. +* \param[in] errorRegister is the value of the error register. +* \return Returns the error message. +**/ +const char* DrmControllerRegistersStrategy_v4_2_1::getDrmErrorRegisterMessage(const unsigned char &errorRegister) const { + for (unsigned int ii = 0; ii < mDrmErrorRegisterMessagesArraySize; ii++) { + if (mDrmErrorRegisterMessagesArray[ii].mDrmErrorCode == errorRegister) { + return mDrmErrorRegisterMessagesArray[ii].mDrmErrorMessage.c_str(); + } + } + return "Unknown error"; +} + +/************************************************************/ +/** PROTECTED MEMBER FUNCTIONS **/ +/************************************************************/ + +/** readPageRegister +* \brief Read and get the value of the page register from the hardware. +* This method will access to the system bus to read the page register. +* \param[out] page is the value of the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readPageRegister(unsigned int &page) const { + return readRegister(DRM_CONTROLLER_V4_2_1_PAGE_REGISTER_NAME, page); +} + +/** writePageRegister +* \brief Write the value of the page register into the hardware. +* This method will access to the system bus to write the page register. +* \param[in] page is the value of the page register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writePageRegister(const unsigned int &page) const { + return writeRegister(DRM_CONTROLLER_V4_2_1_PAGE_REGISTER_NAME, page); +} + +/** readCommandRegister +* \brief Read and get the value of the command register from the hardware. +* This method will access to the system bus to read the command register. +* \param[out] command is the value of the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readCommandRegister(unsigned int &command) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterAtIndex(mCommandRegisterStartIndex, command); +} + +/** writeCommandRegister +* \brief Write the value of the command register into the hardware. +* This method will access to the system bus to write the command register. +* \param[in] command is the value of the command register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::writeCommandRegister(const unsigned int &command) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return writeRegisterAtIndex(mCommandRegisterStartIndex, command); +} + +/** readStatusRegister +* \brief Read the status register. +* This method will access to the system bus to read the status register. +* \param[out] status is the binary value of the status register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readStatusRegister(unsigned int &status) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterAtIndex(mStatusRegisterStartIndex, status); +} + +/** readErrorRegister +* \brief Read the error register. +* This method will access to the system bus to read the error register. +* \param[out] error is the binary value of the error register. +* \return Returns mDrmApi_NO_ERROR if no error, mDrmApi_UNSUPPORTED_FEATURE_ERROR if the feature is not supported, errors from read/write register functions otherwize. +* \throw DrmControllerUnsupportedFeature whenever the feature is not supported. DrmControllerUnsupportedFeature::what() should be called to get the exception description. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::readErrorRegister(unsigned int &error) const { + unsigned int errorCode = writeRegistersPageRegister(); + if (errorCode != mDrmApi_NO_ERROR) return errorCode; + return readRegisterAtIndex(mErrorRegisterStartIndex, error); +} + +/************************************************************/ +/** PRIVATE MEMBER FUNCTIONS **/ +/************************************************************/ + +/** checkLicenseFileSize +* \brief Verify that the size of the license file is correct. +* \param[in] licenseFile is the license file. +* \return Returns true if license file size is correct, false otherwize. +* \throw DrmControllerLicenseFileSizeException whenever a check on license file size is bad. DrmControllerLicenseFileSizeException::what() should be called to get the exception description. +**/ +bool DrmControllerRegistersStrategy_v4_2_1::checkLicenseFileSize(const std::vector &licenseFile) const { + if (licenseFile.size() >= mLicenseFileMinimumWordNumber) return true; + throwLicenseFileSizeException(mLicenseFileMinimumWordNumber, licenseFile.size()); + return false; +} + +/** printPage +* \brief Display the value of the page register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printPageHwReport(std::ostream &file) const { + unsigned int page(0); + if (readPageRegister(page) != mDrmApi_NO_ERROR) return; + file << registerName("PAGE") << std::endl; + file << registerValue(page, "PAGE", 1) << std::endl; +} + +/** printCommand +* \brief Display the value of the command register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printCommandHwReport(std::ostream &file) const { + unsigned int command(0); + if (readCommandRegister(command) != mDrmApi_NO_ERROR) return; + file << registerName("COMMAND") << std::endl; + file << registerValue(command, "COMMAND", 3) << std::endl; +} + +/** printLicenseStartAddress +* \brief Display the value of the license start address register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printLicenseStartAddressHwReport(std::ostream &file) const { + std::string licenseStartAddress(""); + if (DrmControllerRegistersStrategyInterface::readLicenseStartAddressRegister(licenseStartAddress) != mDrmApi_NO_ERROR) return; + file << registerName("LICENSE START ADDRESS") << std::endl; + file << registerValue(licenseStartAddress, "LICENSE START ADDRESS") << std::endl; +} + +/** printLicenseTimer +* \brief Display the value of the license timer register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printLicenseTimerHwReport(std::ostream &file) const { + std::string licenseTimerInit(""); + if (DrmControllerRegistersStrategyInterface::readLicenseTimerInitRegister(licenseTimerInit) != mDrmApi_NO_ERROR) return; + file << registerName("LICENSE TIMER INIT") << std::endl; + file << registerValue(licenseTimerInit.substr(0, 32), "LICENSE TIMER INIT WORD 0") << std::endl; + file << registerValue(licenseTimerInit.substr(32, 32), "LICENSE TIMER INIT WORD 0") << std::endl; + file << registerValue(licenseTimerInit.substr(64, 32), "LICENSE TIMER INIT WORD 0") << std::endl; +} + +/** printStatus +* \brief Display the value of the status register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printStatusHwReport(std::ostream &file) const { + bool bitStatus(false); + unsigned int intStatus(0); + file << registerName("STATUS") << std::endl; + // + if (readDnaReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "DNA READY STATUS") << std::endl; + // + if (readVlnvReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "VLNV READY STATUS") << std::endl; + // + if (readActivationDoneStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "ACTIVATION DONE STATUS") << std::endl; + // + if (readAutonomousControllerEnabledStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "AUTONOMOUS CONTROLLER ENABLED STATUS") << std::endl; + // + if (readAutonomousControllerBusyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "AUTONOMOUS CONTROLLER BUSY STATUS") << std::endl; + // + if (readMeteringEnabledStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "METERING ENABLED STATUS") << std::endl; + // + if (readMeteringReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "METERING READY STATUS") << std::endl; + // + if (readSaasChallengeReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "SAAS CHALLENGE READY STATUS") << std::endl; + // + if (readLicenseTimerEnabledStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "LICENSE TIMER ENABLED STATUS") << std::endl; + // + if (readLicenseTimerInitLoadedStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "LICENSE TIMER INIT LOADED STATUS") << std::endl; + // + if (readEndSessionMeteringReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "END SESSION METERING READY STATUS") << std::endl; + // + if (readHeartBeatModeEnabledStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "HEART BEAT MODE ENABLED STATUS") << std::endl; + // + if (readAsynchronousMeteringReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "ASYNCHRONOUS METERING READY STATUS") << std::endl; + // + if (readLicenseTimerSampleReadyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "LICENSE TIMER SAMPLE READY STATUS") << std::endl; + // + if (readLicenseTimerCountEmptyStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "LICENSE TIMER COUNTER EMPTY STATUS") << std::endl; + // + if (readSessionRunningStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "SESSION RUNNING STATUS") << std::endl; + // + if (readActivationCodesTransmittedStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "ACTIVATION CODES TRANSMITTED STATUS") << std::endl; + // + if (readLicenseNodeLockStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "LICENSE NODE LOCK STATUS") << std::endl; + // + if (readLicenseMeteringStatusRegister(bitStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(bitStatus, "LICENSE METERING STATUS") << std::endl; + // + if (readNumberOfLicenseTimerLoadedStatusRegister(intStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(intStatus, "NUMBER OF LICENSE TIMER LOADED STATUS") << std::endl; + // + if (readNumberOfDetectedIpsStatusRegister(intStatus) != mDrmApi_NO_ERROR) return; + file << registerValue(intStatus, "NUMBER OF DETECTED IPS STATUS") << std::endl; +} + +/** printError +* \brief Display the value of the error register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printErrorHwReport(std::ostream &file) const { + unsigned char errorCode(0); + file << registerName("STATUS") << std::endl; + // + if (readExtractDnaErrorRegister(errorCode) != mDrmApi_NO_ERROR) return; + file << registerValue((unsigned int)errorCode, "DNA EXTRACT ERROR", 2) << std::endl; + file << stringValue(getDrmErrorRegisterMessage(errorCode), "DNA EXTRACT ERROR MESSAGE") << std::endl; + // + if (readExtractVlnvErrorRegister(errorCode) != mDrmApi_NO_ERROR) return; + file << registerValue((unsigned int)errorCode, "VLNV EXTRACT ERROR", 2) << std::endl; + file << stringValue(getDrmErrorRegisterMessage(errorCode), "VLNV EXTRACT ERROR MESSAGE") << std::endl; + // + if (readLicenseTimerLoadErrorRegister(errorCode) != mDrmApi_NO_ERROR) return; + file << registerValue((unsigned int)errorCode, "LICENSE TIMER LOAD ERROR", 2) << std::endl; + file << stringValue(getDrmErrorRegisterMessage(errorCode), "LICENSE TIMER LOAD ERROR MESSAGE") << std::endl; + // + if (readActivationErrorRegister(errorCode) != mDrmApi_NO_ERROR) return; + file << registerValue((unsigned int)errorCode, "ACTIVATION ERROR", 2) << std::endl; + file << stringValue(getDrmErrorRegisterMessage(errorCode), "ACTIVATION ERROR MESSAGE") << std::endl; +} + +/** printDrmVersion +* \brief Display the value of the drm version. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printDrmVersionHwReport(std::ostream &file) const { + std::string drmVersion; + if (DrmControllerRegistersStrategyInterface::readDrmVersionRegister(drmVersion) != mDrmApi_NO_ERROR) return; + file << versionName("SOFTWARE") << std::endl; + file << stringValue(DRM_CONTROLLER_SDK_VERSION, "SDK VERSION") << std::endl; + // display the hardware version + std::string drmVersionDot = DrmControllerDataConverter::binaryToVersionString(DrmControllerDataConverter::hexStringToBinary(drmVersion)[0]); + file << versionName("HARDWARE") << std::endl; + file << stringValue(drmVersionDot, "HDK VERSION") << std::endl; +} + +/** printDna +* \brief Display the value of the dna. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printDnaHwReport(std::ostream &file) const { + std::string dna; + if (DrmControllerRegistersStrategyInterface::readDnaRegister(dna) != mDrmApi_NO_ERROR) return; + file << registerName("DNA") << std::endl; + file << registerValue(dna, "DNA") << std::endl; +} + +/** printSaasChallenge +* \brief Display the value of the saas challenge. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printSaasChallengeHwReport(std::ostream &file) const { + std::string saasChallenge; + if (DrmControllerRegistersStrategyInterface::readSaasChallengeRegister(saasChallenge) != mDrmApi_NO_ERROR) return; + file << registerName("SAAS CHALLENGE") << std::endl; + file << registerValue(saasChallenge, "SAAS CHALLENGE") << std::endl; +} + +/** printAdaptiveProportionTestFailures +* \brief Display the value of the Adaptive Proportion Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printAdaptiveProportionTestFailuresHwReport(std::ostream &file) const { + std::string adaptiveProportionTestFailures; + if (DrmControllerRegistersStrategyInterface::readAdaptiveProportionTestFailuresRegister(adaptiveProportionTestFailures) != mDrmApi_NO_ERROR) return; + file << registerName("ADAPTIVE PROPORTION TEST FAILURES") << std::endl; + file << registerValue(adaptiveProportionTestFailures, "ADAPTIVE PROPORTION TEST FAILURES") << std::endl; +} + +/** printRepetitionCountTestFailures +* \brief Display the value of the Repetition Count Test Failures. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printRepetitionCountTestFailuresHwReport(std::ostream &file) const { + std::string repetitionCountTestFailures; + if (DrmControllerRegistersStrategyInterface::readRepetitionCountTestFailuresRegister(repetitionCountTestFailures) != mDrmApi_NO_ERROR) return; + file << registerName("REPETITION COUNT TEST FAILURES") << std::endl; + file << registerValue(repetitionCountTestFailures, "REPETITION COUNT TEST FAILURES") << std::endl; +} + +/** printLicenseTimerCounter +* \brief Display the value of the license timer counter. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printLicenseTimerCounterHwReport(std::ostream &file) const { + std::string licenseTimerCounter; + if (DrmControllerRegistersStrategyInterface::readLicenseTimerCounterRegister(licenseTimerCounter) != mDrmApi_NO_ERROR) return; + file << registerName("LICENSE TIMER COUNTER") << std::endl; + file << registerValue(licenseTimerCounter, "LICENSE TIMER COUNTER") << std::endl; +} + +/** printLogs +* \brief Display the value of the logs register. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printLogsHwReport(std::ostream &file) const { + unsigned int numberOfDetectedIps; + std::string logs; + if (readNumberOfDetectedIpsStatusRegister(numberOfDetectedIps) != mDrmApi_NO_ERROR) return; + if (DrmControllerRegistersStrategyInterface::readLogsRegister(numberOfDetectedIps, logs) != mDrmApi_NO_ERROR) return; + file << registerName("LOGS") << std::endl; + file << registerValue(concat("0b", logs), "LOGS") << std::endl; +} + +/** printVlnvFile +* \brief Display the value of the vlnv file. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printVlnvFileHwReport(std::ostream &file) const { + unsigned int numberOfDetectedIps; + std::vector vlnvFile; + if (readNumberOfDetectedIpsStatusRegister(numberOfDetectedIps) != mDrmApi_NO_ERROR) return; + if (readVlnvFileRegister(numberOfDetectedIps, vlnvFile) != mDrmApi_NO_ERROR) return; + file << fileName("VLNV") << std::endl; + file << registerValue(vlnvFile, "VLNV", -1) << std::endl; +} + +/** printLicenseFile +* \brief Display the license file. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printLicenseFileHwReport(std::ostream &file) const { + unsigned int numberOfDetectedIps; + std::string licenseFile; + unsigned int licenseFileSize = mLicenseFileHeaderWordNumber; + if (readNumberOfDetectedIpsStatusRegister(numberOfDetectedIps) != mDrmApi_NO_ERROR) return; + licenseFileSize += numberOfDetectedIps*mLicenseFileIpBlockWordNumber; + if (readLicenseFileRegister(licenseFileSize, licenseFile) != mDrmApi_NO_ERROR) return; + file << fileName("LICENSE") << std::endl; + file << registerValue(licenseFile, "LICENSE WORD", (DRM_CONTROLLER_SYSTEM_BUS_DATA_SIZE/DRM_CONTROLLER_NIBBLE_SIZE)*mLicenseWordRegisterWordNumber, 0) << std::endl; +} + +/** printTraceFile +* \brief Display the trace file. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printTraceFileHwReport(std::ostream &file) const { + unsigned int numberOfDetectedIps; + std::vector traceFile; + if (readNumberOfDetectedIpsStatusRegister(numberOfDetectedIps) != mDrmApi_NO_ERROR) return; + if (readTraceFileRegister(numberOfDetectedIps, traceFile) != mDrmApi_NO_ERROR) return; + // the number of digits to show the ip index + std::ostringstream writter; + writter << numberOfDetectedIps-1; + const unsigned int digits = writter.str().size(); + file << fileName("TRACE") << std::endl; + for (unsigned int ii = 0; ii < numberOfDetectedIps; ii++) { + // get the trace part for the current ip + std::vector currentTraceFile(traceFile.begin()+ii*mNumberOfTracesPerIp, traceFile.begin()+(ii+1)*mNumberOfTracesPerIp); + file << registerValue(currentTraceFile, concat(wsConcat("IP", padRight('0', digits, (int)ii)), " - Trace "), 0) << std::endl; + } +} + +/** printMailBoxFile +* \brief Display the value of the mailbox file. +* \param[in] file is the stream to use for the data print. +**/ +void DrmControllerRegistersStrategy_v4_2_1::printMailBoxFileHwReport(std::ostream &file) const { + // read mailbox file + unsigned int readOnlyMailboxWordNumber, readWriteMailboxWordNumber; + std::vector readOnlyMailboxData, readWriteMailboxData; + if (readMailboxFileRegister(readOnlyMailboxWordNumber, readWriteMailboxWordNumber, readOnlyMailboxData, readWriteMailboxData) != mDrmApi_NO_ERROR) return; + file << fileName("MAILBOX") << std::endl; + file << registerValue(readOnlyMailboxWordNumber, "READ-ONLY MAILBOX WORD NUMBER") << std::endl; + file << registerValue(readOnlyMailboxData, "READ-ONLY MAILBOX", 0) << std::endl; + file << registerValue(readWriteMailboxWordNumber, "READ-WRITE MAILBOX WORD NUMBER") << std::endl; + file << registerValue(readWriteMailboxData, "READ-WRITE MAILBOX", 0) << std::endl; +} + +/** getMeteringFileHeader +* \brief Get the header of the metering file. +* \param[in] meteringFile is a list containing the metering file to retrieve the header from. +* \return Returns a list containing the metering file header. +**/ +std::vector DrmControllerRegistersStrategy_v4_2_1::getMeteringFileHeader(const std::vector &meteringFile) const { + return std::vector(next(meteringFile.begin(),mMeteringFileHeaderWordPosition*mMeteringWordRegisterWordNumber), + next(meteringFile.begin(),(mMeteringFileHeaderWordPosition+1)*mMeteringWordRegisterWordNumber)); +} + +/** getMeteringFileHeaderSessionId +* \brief Get the session id from the metering file header. +* \param[in] meteringFileHeader is a list containing the metering file header to retrieve the session id from. +* \return Returns a list containing the metering file session id. +**/ +std::vector DrmControllerRegistersStrategy_v4_2_1::getMeteringFileHeaderSessionId(const std::vector &meteringFileHeader) const { + return std::vector(meteringFileHeader.begin(), next(meteringFileHeader.begin(), 2)); +} + +/** getMeteringFileHeaderEncryptedMeteringFlag +* \brief Get the encrypted metering flag from the metering file header. +* \param[in] meteringFileHeader is a list containing the metering file header to retrieve the encrypted metering flag from. +* \return Returns true if the metering file is encrypted, false otherwize. +**/ +bool DrmControllerRegistersStrategy_v4_2_1::getMeteringFileHeaderEncryptedMeteringFlag(const std::vector &meteringFileHeader) const { + return (bits(17,0x00020000,*(prev(meteringFileHeader.end(),2))) == 1 ? true : false); +} + +/** getMeteringFileHeaderEndSessionMeteringFlag +* \brief Get the end session metering flag from the metering file header. +* \param[in] meteringFileHeader is a list containing the metering file header to retrieve the end session metering flag from. +* \return Returns true if the metering file is for an end session, false otherwize. +**/ +bool DrmControllerRegistersStrategy_v4_2_1::getMeteringFileHeaderEndSessionMeteringFlag(const std::vector &meteringFileHeader) const { + return (bits(16,0x00010000,*(prev(meteringFileHeader.end(),2))) == 1 ? true : false); +} + +/** getMeteringFileHeaderEnvironmentId +* \brief Get the environment id from the metering file header. +* \param[in] meteringFileHeader is a list containing the metering file header to retrieve the environment id from. +* \return Returns the environment id. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::getMeteringFileHeaderEnvironmentId(const std::vector &meteringFileHeader) const { + return bits(0,0x0000FFFF,*(prev(meteringFileHeader.end(),2))); +} + +/** getMeteringFileHeaderSegmentIndex +* \brief Get the segment index from the metering file header. +* \param[in] meteringFileHeader is a list containing the metering file header to retrieve the segment index from. +* \return Returns the segment index. +**/ +unsigned int DrmControllerRegistersStrategy_v4_2_1::getMeteringFileHeaderSegmentIndex(const std::vector &meteringFileHeader) const { + return *(prev(meteringFileHeader.end(),1)); +} + +/** getMeteringFileLicenseTimer +* \brief Get the license timer from the metering file. +* \param[in] meteringFile is a list containing the metering file to retrieve the license timer from. +* \return Returns a list containing the license timer retrieved from metering file. +**/ +std::vector DrmControllerRegistersStrategy_v4_2_1::getMeteringFileLicenseTimer(const std::vector &meteringFile) const { + return std::vector(next(meteringFile.begin(),mMeteringFileLicenseTimerCountWordPosition*mMeteringWordRegisterWordNumber+mSampledLicenseTimerCountRegisterWordNumber), + next(meteringFile.begin(),(mMeteringFileLicenseTimerCountWordPosition+1)*mMeteringWordRegisterWordNumber)); +} + +/** getMeteringFileIpMeteringData +* \brief Get the ip metering data from the metering file. +* \param[in] meteringFile is a list containing the metering file to retrieve the ip metering data from. +* \return Returns a list containing the ip metering retrieved from metering file. +**/ +std::vector DrmControllerRegistersStrategy_v4_2_1::getMeteringFileIpMeteringData(const std::vector &meteringFile) const { + return std::vector(next(meteringFile.begin(),mMeteringFileFirstIpMeteringDataWordPosition*mMeteringWordRegisterWordNumber), + prev(meteringFile.end(), (mMeteringFileMacWordFromEndPosition+1)*mMeteringWordRegisterWordNumber)); +} + +/** getMeteringFileMac +* \brief Get the mac from the metering file. +* \param[in] meteringFile is a list containing the metering file to retrieve the mac from. +* \return Returns a list containing the mac retrieved from metering file. +**/ +std::vector DrmControllerRegistersStrategy_v4_2_1::getMeteringFileMac(const std::vector &meteringFile) const { + return std::vector(prev(meteringFile.end(),(mMeteringFileMacWordFromEndPosition+1)*mMeteringWordRegisterWordNumber), + prev(meteringFile.end(),mMeteringFileMacWordFromEndPosition*mMeteringWordRegisterWordNumber)); +} diff --git a/include/accelize/drm/ParameterKey.def b/include/accelize/drm/ParameterKey.def index b78b9c16..b8dea778 100644 --- a/include/accelize/drm/ParameterKey.def +++ b/include/accelize/drm/ParameterKey.def @@ -2,8 +2,8 @@ PARAMETERKEY_ITEM( license_type ) ///< Read-only, return strin PARAMETERKEY_ITEM( license_duration ) ///< Read-only, return uint32 with the duration in seconds of the current or last license PARAMETERKEY_ITEM( num_activators ) ///< Read-only, return uint32_t/string with the number of activators detected by the DRM controller PARAMETERKEY_ITEM( session_id ) ///< Read-only, return string with the current session ID -PARAMETERKEY_ITEM( session_status ) ///< Read-only, return boolean to indicate if a session is currently running -PARAMETERKEY_ITEM( license_status ) ///< Read-only, return the license status of the configuration file +PARAMETERKEY_ITEM( session_status ) ///< Read-only, return boolean to indicate if a session is currently open +PARAMETERKEY_ITEM( license_status ) ///< Read-only, return boolean to indicate if a license is running in the Controller PARAMETERKEY_ITEM( metered_data ) ///< Read-only, return uint64_t or string with the current value of the metering data counter PARAMETERKEY_ITEM( nodelocked_request_file ) ///< Read-only, return string with the path to the node-locked license request JSON file PARAMETERKEY_ITEM( drm_frequency ) ///< Read-only, return the measured DRM frequency @@ -15,21 +15,21 @@ PARAMETERKEY_ITEM( token_validity ) ///< Read-only, return the v PARAMETERKEY_ITEM( token_time_left ) ///< Read-only, return the number of seconds left until the current token expires PARAMETERKEY_ITEM( frequency_detection_method ) ///< Read-only, return the method index used to detect the DRM frequency PARAMETERKEY_ITEM( bypass_frequency_detection ) ///< Read-only, return true if the frequency detection system is disabled, false otherwise -PARAMETERKEY_ITEM( log_file_path ) ///< Read-(write), read (or write) the logging file path: default path is "./drm_lib.log". Can be set only from configuration file (no override from C/C++ code) -PARAMETERKEY_ITEM( log_file_type ) ///< Read-(write), read (or write) the logging file type 0=no logging file, 1=basic file, 2=rotation file. Set only from configuration file (no override from C code) -PARAMETERKEY_ITEM( log_file_rotating_size ) ///< Read-(write), read (or write) the logging rotating file size: default=100MB. Set only from configuration file (no override from C code) -PARAMETERKEY_ITEM( log_file_rotating_num ) ///< Read-(write), read (or write) the logging rotating number of backup files: default=3. Set only from configuration file (no override from C code) +PARAMETERKEY_ITEM( log_file_path ) ///< Read-(write), read (and write) the logging file path: default path is "./drm_lib.log". Can be set only from configuration file (no override from user's code) +PARAMETERKEY_ITEM( log_file_type ) ///< Read-(write), read (and write) the logging file type 0=no logging file, 1=basic file, 2=rotation file. Set only from configuration file (no override from user's code) +PARAMETERKEY_ITEM( log_file_rotating_size ) ///< Read-(write), read (and write) the logging rotating file size in KB: default=1024KB (1MB). Set only from configuration file (no override from user's code) +PARAMETERKEY_ITEM( log_file_rotating_num ) ///< Read-(write), read (and write) the logging rotating number of backup files: default=3. Set only from configuration file (no override from user's code) PARAMETERKEY_ITEM( log_file_verbosity ) ///< Read-write, read and write the logging verbosity on the file: 0=trace, 6=quiet PARAMETERKEY_ITEM( log_file_format ) ///< Read-write, read and write the logging file format. Refer to spdlog reference manual (https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) PARAMETERKEY_ITEM( log_verbosity ) ///< Read-write, read and write the logging verbosity on the stdout/stderr: 0=trace, 6=quiet -PARAMETERKEY_ITEM( log_format ) ///< Read-write, read and write the logging format: 0=short, 1=long -PARAMETERKEY_ITEM( frequency_detection_threshold ) ///< Read-write, read and write frequency gap threshold used to measure the real DRM Controller frequency +PARAMETERKEY_ITEM( log_format ) ///< Read-write, read and write the logging file format. Refer to spdlog reference manual (https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) +PARAMETERKEY_ITEM( frequency_detection_threshold ) ///< Read-write, read and write the accepted percentage of error between the frequency set in the conf file and the measured frequency PARAMETERKEY_ITEM( frequency_detection_period ) ///< Read-write, read and write the period of time in milliseconds used to measure the real DRM Controller frequency -PARAMETERKEY_ITEM( custom_field ) ///< Read-write, only for testing, any uint32_t register accessible to the user for any purpose +PARAMETERKEY_ITEM( custom_field ) ///< Read-write, only for testing, a register accessible to the user for any purpose PARAMETERKEY_ITEM( mailbox_data ) ///< Read-write, only for testing, read or write values to Mailbox read-write memory in DRM Controller PARAMETERKEY_ITEM( ws_retry_period_long ) ///< Read-write, read and write the time in seconds before the next request attempt to the Web Server when the time left before timeout is long PARAMETERKEY_ITEM( ws_retry_period_short ) ///< Read-write, read and write the time in seconds before the next request attempt to the Web Server when the time left before timeout is short -PARAMETERKEY_ITEM( ws_request_timeout ) ///< Read-write, read and write the web service request timeout in seconds during which the response is waited +PARAMETERKEY_ITEM( ws_request_timeout ) ///< Read-(write), read (and write) the maximum period of time in seconds for the request to complete. Can be set only from configuration file (no override from user's code) PARAMETERKEY_ITEM( log_message_level ) ///< Read-write, only for testing, read and write the log level used with log_message parameter to set the message level PARAMETERKEY_ITEM( list_all ) ///< Read-only, list all parameter keys available PARAMETERKEY_ITEM( dump_all ) ///< Read-only, read all parameter key values @@ -41,6 +41,13 @@ PARAMETERKEY_ITEM( page_meteringfile ) ///< Read-only, return nothi PARAMETERKEY_ITEM( page_mailbox ) ///< Read-only, return nothing, print all registers in the Mailbox page PARAMETERKEY_ITEM( hw_report ) ///< Read-only, return nothing, print the Algodone HW report PARAMETERKEY_ITEM( trigger_async_callback ) ///< Write-only, only for testing, call the asynchronous error callback with the given message -PARAMETERKEY_ITEM( bad_product_id ) ///< Write-only, only for testing, uses a bad product ID -PARAMETERKEY_ITEM( bad_oauth2_token ) ///< Write-only, only for testing, uses a bad token PARAMETERKEY_ITEM( log_message ) ///< Write-only, only for testing, insert a message with the value as content +PARAMETERKEY_ITEM( hdk_compatibility ) ///< Read-only, only for testing, return the lower version of the HDK it is compatible with +PARAMETERKEY_ITEM( health_period ) ///< Read-only, return the current value of the health period +PARAMETERKEY_ITEM( health_retry ) ///< Read-only, return the current value of the health retry timeout +PARAMETERKEY_ITEM( health_retry_sleep ) ///< Read-only, return the current value of the health retry sleep +PARAMETERKEY_ITEM( ws_api_retry_duration ) ///< Read-write, read and write the period of time in seconds during which retries occur on activate and deactivate functions +PARAMETERKEY_ITEM( host_data_verbosity ) ///< Read-(write), read (and write) the level of verbosity for the amont of host and card data collected. Set only from configuration file (no override from user's code) +PARAMETERKEY_ITEM( host_data ) ///< Read-only, read the host and card information +PARAMETERKEY_ITEM( log_file_append ) ///< Read-(write), read (and write) the appending parameter for the basic logging file. Set only from configuration file (no override from user's code) +PARAMETERKEY_ITEM( ws_verbosity ) ///< Read-(write), read (and write) the curl verbosity. Set only from configuration file (no override from user's code) diff --git a/include/accelize/drmc/common.h b/include/accelize/drmc/common.h index a98e6ac4..69989f56 100644 --- a/include/accelize/drmc/common.h +++ b/include/accelize/drmc/common.h @@ -15,7 +15,7 @@ limitations under the License. */ #ifndef _H_ACCELIZE_COMMON_EXPORT - #define _H_ACCELIZE_COMMON_EXPORT +#define _H_ACCELIZE_COMMON_EXPORT #ifdef __cplusplus #ifdef BUILDING_DRMLIB @@ -31,13 +31,13 @@ limitations under the License. #endif /* __cplusplus */ - #define Throw( errcode, ... ) do { \ - Accelize::DRM::Exception except( errcode, fmt::format( __VA_ARGS__ ) ); \ - if ( ( errcode != DRM_Exit ) && ( errcode != DRM_WSMayRetry ) ) \ - Fatal( __VA_ARGS__ ); \ - else \ - Debug( __VA_ARGS__ ); \ - throw except; \ + #define Throw( errcode, ... ) do { \ + Accelize::DRM::Exception except( errcode, fmt::format( __VA_ARGS__ ) ); \ + if ( ( errcode == DRM_Exit ) || ( errcode == DRM_WSTimedOut ) || ( errcode == DRM_WSMayRetry ) ) \ + Debug( __VA_ARGS__ ); \ + else \ + Error( __VA_ARGS__ ); \ + throw except; \ } while(0) diff --git a/include/accelize/drmc/errorcode.h b/include/accelize/drmc/errorcode.h index d323cb93..40a3f685 100644 --- a/include/accelize/drmc/errorcode.h +++ b/include/accelize/drmc/errorcode.h @@ -40,6 +40,7 @@ typedef enum { DRM_WSReqError = 10002, /**< Failed during HTTP request to Accelize WebService */ DRM_WSError = 10003, /**< Error returned from Accelize WebService */ DRM_WSMayRetry = 10004, /**< Error with request to Accelize Webservice, retry advised */ + DRM_WSTimedOut = 10005, /**< Error with request to Accelize Webservice, deadline has been reached */ DRM_CtlrError = 20001, /**< An error happened on a command to the DRM controller */ diff --git a/internal_inc/csp.h b/internal_inc/csp.h new file mode 100644 index 00000000..7025085a --- /dev/null +++ b/internal_inc/csp.h @@ -0,0 +1,91 @@ +/* +Copyright (C) 2018, Accelize + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/** \brief Accelize CSP Metadata Management +*/ + +#ifndef _H_ACCELIZE_CSP_MANAGER +#define _H_ACCELIZE_CSP_MANAGER + +#include + +#include "ws_client.h" + + +namespace Accelize { +namespace DRM { + + +Json::Value GetCspInfo( uint32_t verbosity ); + + +/** \brief Interface to collect CSP metadata +*/ +class CspBase { + +private: + std::string mName; // CSP name + +protected: + CurlEasyPost mHTTPRequest; + uint32_t mVerbosity; // HTTP verbosity: 0: default, 1:verbose + +public: + + CspBase() = delete; //!< No default constructor + CspBase( const std::string &name, const uint32_t timeout_ms ); + virtual ~CspBase() {}; + + std::string getName() const { return mName; } + + uint32_t getVerbosity() const { return mVerbosity; } + void setVerbosity( const uint32_t& verbosity ) { mHTTPRequest.setVerbosity( verbosity ); } + + /** \brief Get Metadata information + + \param[in] resume_session_request : If true, the pending session is + reused. If no pending session is found, create a new one. If + false and a pending session is found, close it and create a new + one. Default to False. + */ + virtual Json::Value get_metadata() = 0; +}; + + +/** \brief Interface to collect AWS metadata +*/ +class Aws : public CspBase { +public: + Aws(); + //~Aws() {}; + Json::Value get_metadata(); +}; + + +/** \brief Interface to collect Alibaba metadata +*/ +class Alibaba : public CspBase { +public: + Alibaba(); + //~Alibaba() {}; + Json::Value get_metadata(); +}; + + +} +} + +#endif // _H_ACCELIZE_CSP_MANAGER diff --git a/internal_inc/utils.h b/internal_inc/utils.h index afc85c36..ef91c64b 100644 --- a/internal_inc/utils.h +++ b/internal_inc/utils.h @@ -23,6 +23,13 @@ limitations under the License. namespace Accelize { namespace DRM { +const char PATH_SEP = +#ifdef _WIN32 + '\\'; +#else + '/'; +#endif + std::string getDirName( const std::string& full_path ); bool isDir( const std::string& dir_path ); bool isFile( const std::string& file_path ); @@ -35,7 +42,9 @@ Json::Value parseJsonFile(const std::string &file_path); const Json::Value& JVgetRequired( const Json::Value& json_value, const char* key, const Json::ValueType& type ); const Json::Value& JVgetOptional( const Json::Value& json_value, const char* key, const Json::ValueType& type, const Json::Value& defaultValue = Json::nullValue ); +std::string exec_cmd( const std::string cmd); } } #endif // _H_ACCELIZE_METERING_UTILS + diff --git a/internal_inc/ws_client.h b/internal_inc/ws_client.h index 89032dcf..02ae7506 100644 --- a/internal_inc/ws_client.h +++ b/internal_inc/ws_client.h @@ -23,6 +23,8 @@ limitations under the License. #include #include +#include "log.h" + namespace Accelize { namespace DRM { @@ -30,26 +32,33 @@ namespace DRM { // RAII for Curl global init/cleanup class CurlSingleton { + private: CurlSingleton() { curl_global_init(CURL_GLOBAL_ALL); } ~CurlSingleton() { curl_global_cleanup(); } + public: static void Init() { static CurlSingleton g_curl; (void) g_curl; } + }; // RAII for Curl easy class CurlEasyPost { + private: - const ulong cConnectionTimeout = 4000L; // In milliseconds + const uint32_t cConnectionTimeoutMS = 30000; // Timeout default value in milliseconds + CURL *curl = NULL; - struct curl_slist *headers = NULL; - struct curl_slist *host_resolve_list = NULL; - std::list data; // keep data until request performed - std::array errbuff; + std::string mUrl; + struct curl_slist *mHeaders_p = NULL; + struct curl_slist *mHostResolveList = NULL; + std::list data; // keep data until request performed + std::array mErrBuff; + uint32_t mConnectionTimeoutMS; // Request timeout in milliseconds public: @@ -57,6 +66,7 @@ class CurlEasyPost { return resp_code == 408 // Request Timeout || resp_code == 429 // Too Many Requests || resp_code == 470 // Floating License: no token available + || resp_code == 495 // SSL Certificate Error || resp_code == 500 // Internal Server Error || resp_code == 502 // Bad Gateway || resp_code == 503 // Service Unavailable @@ -68,48 +78,119 @@ class CurlEasyPost { || resp_code == 522 // Connection Timed Out || resp_code == 524 // A Timeout Occurred || resp_code == 525 // SSL Handshake Failed + || resp_code == 526 // Invalid SSL Certificate || resp_code == 527 // Railgun Error || resp_code == 530 // Origin DNS Error || resp_code == 560 // Accelize License generation temporary issue ; } + static DRM_ErrorCode httpCode2DrmCode( const uint32_t http_resp_code ) { + if ( http_resp_code == 200 ) + return DRM_OK; + if ( CurlEasyPost::is_error_retryable( http_resp_code ) ) + return DRM_WSMayRetry; + if ( ( http_resp_code >= 400 ) && ( http_resp_code < 500 ) ) + return DRM_WSReqError; + return DRM_WSError; + } CurlEasyPost(); ~CurlEasyPost(); - long perform(std::string* resp, std::chrono::steady_clock::time_point deadline); double getTotalTime(); + void setVerbosity( const uint32_t verbosity ); + void setHostResolves( const Json::Value& host_json ); template void setURL(T&& url) { - data.push_back(std::forward(url)); - curl_easy_setopt(curl, CURLOPT_URL, data.back().c_str()); + data.push_back( std::forward(url) ); + curl_easy_setopt( curl, CURLOPT_URL, data.back().c_str() ); + mUrl = url; } template - void appendHeader(T&& header) { - data.push_back(std::forward(header)); - Debug2( "Add {} to CURL header", std::forward(header) ); - headers = curl_slist_append(headers, data.back().c_str()); + void appendHeader( T&& header ) { + data.push_back( std::forward(header) ); + Debug2( "Add '{}' to CURL header", std::forward(header) ); + mHeaders_p = curl_slist_append( mHeaders_p, data.back().c_str() ); } template - void setPostFields(T&& postfields) { - data.push_back(std::forward(postfields)); - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.back().size()); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.back().c_str()); + void setPostFields( T&& postfields ) { + data.push_back( std::forward(postfields) ); + curl_easy_setopt( curl, CURLOPT_POSTFIELDSIZE, data.back().size() ); + curl_easy_setopt( curl, CURLOPT_POSTFIELDS, data.back().c_str() ); + } + + void setConnectionTimeoutMS( const uint32_t timeoutMS ) { mConnectionTimeoutMS = timeoutMS; } + uint32_t getConnectionTimeoutMS() const { return mConnectionTimeoutMS; } + + uint32_t perform( std::string* resp, std::chrono::steady_clock::time_point& deadline ); + uint32_t perform( std::string* resp, int32_t timeout ); + std::string perform_put( std::string url, const uint32_t& timeout_ms ); + + template + T perform( std::string url, const uint32_t& timeout_ms ) { + T response; + uint32_t resp_code; + + // Configure and execute CURL command + curl_easy_setopt( curl, CURLOPT_URL, url.c_str() ); + if ( mHeaders_p ) { + curl_easy_setopt( curl, CURLOPT_HTTPHEADER, mHeaders_p ); + } + curl_easy_setopt( curl, CURLOPT_WRITEDATA, &response ); + curl_easy_setopt( curl, CURLOPT_CONNECTTIMEOUT_MS, mConnectionTimeoutMS ); + if ( timeout_ms <= 0 ) + Throw( DRM_WSTimedOut, "Did not perform HTTP request to Accelize webservice because deadline is reached." ); + curl_easy_setopt( curl, CURLOPT_TIMEOUT_MS, timeout_ms ); + CURLcode res = curl_easy_perform( curl ); + + // Analyze libcurl response + if ( res != CURLE_OK ) { + if ( res == CURLE_COULDNT_RESOLVE_PROXY + || res == CURLE_COULDNT_RESOLVE_HOST + || res == CURLE_COULDNT_CONNECT + || res == CURLE_OPERATION_TIMEDOUT ) { + Throw( DRM_WSMayRetry, "libcurl failed to perform HTTP request to Accelize webservice ({}) : {}", + curl_easy_strerror( res ), mErrBuff.data() ); //LCOV_EXCL_LINE + } else { + Throw( DRM_ExternFail, "libcurl failed to perform HTTP request to Accelize webservice ({}) : {}", + curl_easy_strerror( res ), mErrBuff.data() ); //LCOV_EXCL_LINE + } + } + curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &resp_code ); + Debug( "Received code {} from {} in {} ms", resp_code, url, getTotalTime() * 1000 ); + + // Analyze HTTP response + if ( resp_code != 200 ) { + // An error occurred + DRM_ErrorCode drm_error; + if ( CurlEasyPost::is_error_retryable( resp_code ) ) + drm_error = DRM_WSMayRetry; + else if ( ( resp_code >= 400 ) && ( resp_code < 500 ) ) + drm_error = DRM_WSReqError; + else + drm_error = DRM_WSError; + Throw( drm_error, "OAuth2 Web Service error {}: {}", resp_code, response ); + } + return response; } protected: - static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) { - auto *s = (std::string*)userp; + static size_t write_callback( void *contents, size_t size, size_t nmemb, std::string *userp ) { size_t realsize = size * nmemb; - s->append((const char*)contents, realsize); + try { + userp->append( (const char*)contents, realsize ); + } catch( const std::bad_alloc& e ) { + Throw( DRM_ExternFail, "Curl write callback exception: {}", e.what() ); //LCOV_EXCL_LINE + } return realsize; } + }; @@ -117,36 +198,43 @@ class CurlEasyPost { get license and send metering data*/ class DrmWSClient { - const uint32_t cTokenExpirationMargin = 30; + const uint32_t cTokenExpirationMargin = 30; // In seconds + const uint32_t cRequestTimeout = 30; // In seconds protected: typedef std::chrono::steady_clock TClock; /// Shortcut type def to steady clock which is monotonic (so unaffected by clock adjustments) + uint32_t mVerbosity; std::string mClientId; std::string mClientSecret; - std::string mMeteringUrl; std::string mOAuth2Token; + std::string mLicenseUrl; + std::string mHealthUrl; Json::Value mHostResolvesJson; uint32_t mTokenValidityPeriod; /// Validation period of the OAuth2 token in seconds uint32_t mTokenExpirationMargin; /// OAuth2 token expiration margin in seconds TClock::time_point mTokenExpirationTime; /// OAuth2 expiration time CurlEasyPost mOAUth2Request; + uint32_t mRequestTimeout; bool isTokenValid() const; + Json::Value requestMetering( const std::string url, const Json::Value& json_req, TClock::time_point deadline ); public: DrmWSClient(const std::string &conf_file_path, const std::string &cred_file_path); ~DrmWSClient() = default; + uint32_t getVerbosity() const { return mVerbosity; } + uint32_t getTokenValidity() const { return mTokenValidityPeriod; } int32_t getTokenTimeLeft() const; std::string getTokenString() const { return mOAuth2Token; } - void setOAuth2token( const std::string& token ); - void requestOAuth2token(TClock::time_point deadline); + Json::Value requestLicense( const Json::Value& json_req, TClock::time_point deadline ); + Json::Value requestHealth( const Json::Value& json_req, TClock::time_point deadline ); }; diff --git a/pytest.ini b/pytest.ini index a9556b31..40fabc87 100644 --- a/pytest.ini +++ b/pytest.ini @@ -11,6 +11,7 @@ markers = first: used by pytest-ordering plugin last: used by pytest-ordering plugin hwtst: used to run minimum hw validation tests + lgdn: used to run tests shared with LGDN #log_file = pytest.log #log_file_level = DEBUG #log_file_format = %(asctime)s.%(msecs)03d - (%(filename)s:%(lineno)s - [%(levelname)8s] %(message)s) diff --git a/python/accelize_drm/exceptions.py b/python/accelize_drm/exceptions.py index 1d365799..b4d95d77 100644 --- a/python/accelize_drm/exceptions.py +++ b/python/accelize_drm/exceptions.py @@ -83,6 +83,14 @@ class DRMWSMayRetry(DRMException): error_code = 10004 +class DRMWSTimedOut(DRMException): + """ + Error with request to Accelize Webservice, deadline has been reached + """ + #: Error code + error_code = 10005 + + class DRMCtlrError(DRMException): """ An error happened on a command on the DRM controller diff --git a/python/setup.py b/python/setup.py index 843fbb63..f438b459 100755 --- a/python/setup.py +++ b/python/setup.py @@ -81,7 +81,7 @@ PACKAGE_INFO['package_data'] = {'accelize_drm': ['*']} # Debug compiler options - compile_args = ["-g3", "-O0"] + compile_args = ["-g3", "-Og"] # Show source code in generated files cython_options = dict(emit_code_comments=True) diff --git a/source/c/wrapperc.cpp b/source/c/wrapperc.cpp index b7ddaeff..8d4da18c 100644 --- a/source/c/wrapperc.cpp +++ b/source/c/wrapperc.cpp @@ -31,7 +31,7 @@ const char * DrmManager_getApiVersion() { void checkPointer(void *p) { if ( p == NULL ) - Throw( DRM_BadArg, "Provided pointer is NULL" ); + Throw( DRM_BadArg, "Provided pointer is NULL" ); //LCOV_EXCL_LINE } /* Help macros TRY/CATCH to return code error */ diff --git a/source/csp.cpp b/source/csp.cpp new file mode 100644 index 00000000..19abbe44 --- /dev/null +++ b/source/csp.cpp @@ -0,0 +1,119 @@ +/* +Copyright (C) 2018, Accelize + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "csp.h" +#include "utils.h" +#include "log.h" + + +namespace Accelize { +namespace DRM { + +Json::Value GetCspInfo( uint32_t verbosity ) { + Json::Value info_node = Json::nullValue; + + // Test AWS command + Aws* csp_aws = new Aws(); + try { + csp_aws->setVerbosity( verbosity ); + info_node = csp_aws->get_metadata(); + Debug( "Instance is running on Aws" ); + delete csp_aws; + return info_node; + } catch( std::runtime_error &e ) { + Debug( "Instance is not running on Aws" ); + delete csp_aws; + } + + // Test Alibaba command + Alibaba* csp_alibaba = new Alibaba(); + try { + csp_alibaba->setVerbosity( verbosity ); + info_node = csp_alibaba->get_metadata(); + Debug( "Instance is running on Alibaba" ); + delete csp_alibaba; + return info_node; + } catch( std::runtime_error &e ) { + Debug( "Instance is not running on Alibaba" ); + delete csp_alibaba; + } + + // Not a supported CSP or this is On-Prem system + Debug( "Cloud environment could not be determined" ); + return info_node; +} + + +/** AWS class +*/ +Aws::Aws():CspBase( "Aws", 50 ) {} + +Json::Value Aws::get_metadata() { + Json::Value metadata = Json::nullValue; + std::string token; + uint32_t timeout_ms = mHTTPRequest.getConnectionTimeoutMS(); + + // Using IMDSv2 method + + // Get token + CurlEasyPost tokenReq; + tokenReq.setConnectionTimeoutMS( timeout_ms ); + tokenReq.setVerbosity( mVerbosity ); + tokenReq.appendHeader( "X-aws-ec2-metadata-token-ttl-seconds: 21600" ); + token = tokenReq.perform_put( "http://169.254.169.254/latest/api/token", timeout_ms ); + + // Collect AWS information + std::string header = fmt::format("X-aws-ec2-metadata-token: {}", token); + mHTTPRequest.appendHeader( header ); + std::string base_url("http://169.254.169.254/latest"); + metadata["instance_id"] = mHTTPRequest.perform( fmt::format( "{}/meta-data/instance-id", base_url ), timeout_ms ); + metadata["instance_type"] = mHTTPRequest.perform( fmt::format( "{}/meta-data/instance-type", base_url ), timeout_ms ); + metadata["ami_id"] = mHTTPRequest.perform( fmt::format( "{}/meta-data/ami-id", base_url ), timeout_ms ); + std::string doc_string = mHTTPRequest.perform( fmt::format( "{}/dynamic/instance-identity/document", base_url ), timeout_ms ); + Json::Value doc_json = parseJsonString( doc_string ); + metadata["region"] = doc_json["region"]; + return metadata; +} + + +/** Alibaba class +*/ +Alibaba::Alibaba():CspBase( "Alibaba", 50 ) {} + +Json::Value Alibaba::get_metadata() { + Json::Value metadata = Json::nullValue; + uint32_t timeout_ms = mHTTPRequest.getConnectionTimeoutMS(); + // Collect Alibaba information + std::string base_url("http://100.100.100.200/latest/meta-data"); + metadata["instance_id"] = mHTTPRequest.perform( fmt::format( "{}/instance-id", base_url ), timeout_ms ); + metadata["instance_type"] = mHTTPRequest.perform( fmt::format( "{}/instance/instance-type", base_url ), timeout_ms ); + metadata["ami_id"] = mHTTPRequest.perform( fmt::format( "{}/image-id", base_url ), timeout_ms ); + metadata["region"] = mHTTPRequest.perform( fmt::format( "{}/region-id", base_url ), timeout_ms ); + return metadata; +} + + +/** CspBase class +*/ +CspBase::CspBase( const std::string &name, const uint32_t timeout_ms ) { + mName = name; + mHTTPRequest.setConnectionTimeoutMS( timeout_ms ); + mVerbosity = 0; +} + + +} +} diff --git a/source/drm_manager.cpp b/source/drm_manager.cpp index d5051cfa..0f2011ff 100644 --- a/source/drm_manager.cpp +++ b/source/drm_manager.cpp @@ -41,6 +41,7 @@ limitations under the License. #include "ws_client.h" #include "log.h" #include "utils.h" +#include "csp.h" #pragma GCC diagnostic push @@ -56,21 +57,21 @@ limitations under the License. #define FREQ_DETECTION_VERSION_EXPECTED 0x60DC0DE0 -static const std::string DRM_SELF_TEST_ERROR_MESSAGE( "Could not access DRM Controller registers.\nPlease verify:\n" - "\t-The read/write callbacks implementation in the SW application: verify it uses the correct offset address of DRM Controller IP in the design address space.\n" - "\t-The DRM Controller IP instantiation in the FPGA design: verify the correctness of 16-bit address received by the AXI-Lite port of the DRM Controller." ); #define TRY try { -#define CATCH_AND_THROW \ - } catch( const Exception &e ) { \ - throw; \ - } catch( const std::exception &e ) { \ - Error( e.what() ); \ - throw; \ +#define CATCH_AND_THROW \ + } catch( const std::exception &e ) { \ + Fatal( e.what() ); \ + throw; \ } +static const std::string DRM_SELF_TEST_ERROR_MESSAGE( "Could not access DRM Controller registers.\nPlease verify:\n" + "\t-The read/write callbacks implementation in the SW application: verify it uses the correct offset address of DRM Controller IP in the design address space.\n" + "\t-The DRM Controller IP instantiation in the FPGA design: verify the correctness of 16-bit address received by the AXI-Lite port of the DRM Controller." ); + + namespace Accelize { namespace DRM { @@ -91,13 +92,11 @@ class DRM_LOCAL DrmManager::Impl { enum class eLogFileType: uint8_t {NONE=0, BASIC, ROTATING}; enum class eLicenseType: uint8_t {METERED, NODE_LOCKED, NONE}; enum class eMailboxOffset: uint8_t {MB_LOCK_DRM=0, MB_CUSTOM_FIELD, MB_USER}; + enum class eHostDataVerbosity: uint8_t {FULL=0, PARTIAL, NONE}; // Design constants - const uint32_t SDK_COMPATIBLITY_LIMIT_MAJOR = 3; - const uint32_t SDK_COMPATIBLITY_LIMIT_MINOR = 1; - - const uint32_t HDK_COMPATIBLITY_LIMIT_MAJOR = 3; - const uint32_t HDK_COMPATIBLITY_LIMIT_MINOR = 1; + const uint32_t HDK_COMPATIBILITY_LIMIT_MAJOR = 3; + const uint32_t HDK_COMPATIBILITY_LIMIT_MINOR = 1; const std::map LicenseTypeStringMap = { {eLicenseType::NONE , "Idle"}, @@ -107,6 +106,7 @@ class DRM_LOCAL DrmManager::Impl { const uint32_t LICENSE_DURATION_DEFAULT = 30; + const double ACTIVATIONCODE_TRANSMISSION_TIMEOUT_MS = 2000.0; #ifdef _WIN32 const char path_sep = '\\'; @@ -130,10 +130,11 @@ class DRM_LOCAL DrmManager::Impl { std::string sLogConsoleFormat = std::string("[%^%=8l%$] %-6t, %v"); spdlog::level::level_enum sLogFileVerbosity = spdlog::level::info; + std::string sLogFilePath = fmt::format( "accelize_drmlib_{}.log", getpid() ); std::string sLogFileFormat = std::string("%Y-%m-%d %H:%M:%S.%e - %18s:%-4# [%=8l] %=6t, %v"); eLogFileType sLogFileType = eLogFileType::NONE; - std::string sLogFilePath = fmt::format( "accelize_drmlib_{}.log", getpid() ); - size_t sLogFileRotatingSize = 100*1024*1024; + bool sLogFileAppend = false; + size_t sLogFileRotatingSize = 100*1024; ///< Size max in KBytes of the log roating file size_t sLogFileRotatingNum = 3; // Function callbacks @@ -153,12 +154,12 @@ class DRM_LOCAL DrmManager::Impl { // License related properties uint32_t mWSRetryPeriodLong = 60; ///< Time in seconds before the next request attempt to the Web Server when the time left before timeout is large uint32_t mWSRetryPeriodShort = 2; ///< Time in seconds before the next request attempt to the Web Server when the time left before timeout is short - uint32_t mWSRequestTimeout = 10; ///< Time in seconds during which retries occur + uint32_t mWSApiRetryDuration = 10; ///< Period of time in seconds during which retries occur on activate and deactivate functions + uint32_t mWSRequestTimeout = 10; ///< Time in seconds for a request to complete eLicenseType mLicenseType = eLicenseType::METERED; - uint32_t mLicenseCounter = 0; - uint32_t mLicenseDuration = 0; ///< Time duration in seconds of the license - uint32_t mLicenseWaitPeriod = 5; ///< Time in seconds to wait for the load of a new license + uint32_t mLicenseDuration = 0; ///< Time duration in seconds of the license + uint32_t mLicenseWaitPeriod = 5; ///< Time in seconds to wait for the load of a new license // To protect access to the metering data (to securize the segment ID check in HW) mutable std::mutex mMeteringAccessMutex; @@ -166,8 +167,8 @@ class DRM_LOCAL DrmManager::Impl { // Design parameters int32_t mFrequencyInit = 0; int32_t mFrequencyCurr = 0; - uint32_t mFrequencyDetectionPeriod = 100; // in milliseconds - double mFrequencyDetectionThreshold = 12.0; // Error in percentage + uint32_t mFrequencyDetectionPeriod = 100; // in milliseconds + double mFrequencyDetectionThreshold = 12.0; // Error in percentage bool mIsFreqDetectionMethod1 = false; bool mBypassFrequencyDetection = false; @@ -179,11 +180,31 @@ class DRM_LOCAL DrmManager::Impl { // Web service communication Json::Value mHeaderJsonRequest; - // thread to maintain alive + // Health/Asynchronous metering parameters + uint32_t mHealthPeriod; ///< Time in seconds before performing the next health request + uint32_t mHealthRetryTimeout; ///< Timeout in seconds for the health request + uint32_t mHealthRetrySleep; ///< Time in seconds before perforing a new health retry + + // Thread to maintain license alive + uint32_t mLicenseCounter = 0; std::future mThreadKeepAlive; - std::mutex mThreadKeepAliveMtx; - std::condition_variable mThreadKeepAliveCondVar; - bool mThreadStopRequest{false}; + TClock::time_point mExpirationTime; + + // Thread to maintain health alive + mutable uint32_t mHealthCounter = 0; + std::future mThreadHealth; + + // Threads exit elements + std::mutex mThreadExitMtx; + std::condition_variable mThreadExitCondVar; + bool mThreadExit{false}; + + // XRT PATH + std::string mXrtPath; + std::string mXbutil; + Json::Value mHostConfigData; + eHostDataVerbosity mHostDataVerbosity = eHostDataVerbosity::PARTIAL; + Json::Value mSettings; // Debug parameters spdlog::level::level_enum mDebugMessageLevel; @@ -200,8 +221,11 @@ class DRM_LOCAL DrmManager::Impl { #define checkDRMCtlrRet( func ) { \ unsigned int errcode = DRM_OK; \ try { \ + std::lock_guard lock( mDrmControllerMutex ); \ errcode = func; \ + Debug( "{} returned {}", #func, errcode ); \ } catch( const std::exception &e ) { \ + Debug( "{} threw an exception", #func ); \ Throw( DRM_CtlrError, e.what() ); \ } \ if ( errcode ) \ @@ -238,23 +262,25 @@ class DRM_LOCAL DrmManager::Impl { if ( param_lib != Json::nullValue ) { // Console logging sLogConsoleVerbosity = static_cast( JVgetOptional( - param_lib, "log_verbosity", Json::intValue, (int)sLogConsoleVerbosity ).asInt()); + param_lib, "log_verbosity", Json::uintValue, (uint32_t)sLogConsoleVerbosity ).asUInt()); sLogConsoleFormat = JVgetOptional( param_lib, "log_format", Json::stringValue, sLogConsoleFormat ).asString(); // File logging sLogFileVerbosity = static_cast( JVgetOptional( - param_lib, "log_file_verbosity", Json::intValue, (int)sLogFileVerbosity ).asInt() ); + param_lib, "log_file_verbosity", Json::uintValue, (uint32_t)sLogFileVerbosity ).asUInt() ); sLogFileFormat = JVgetOptional( param_lib, "log_file_format", Json::stringValue, sLogFileFormat ).asString(); sLogFilePath = JVgetOptional( param_lib, "log_file_path", Json::stringValue, sLogFilePath ).asString(); sLogFileType = static_cast( JVgetOptional( - param_lib, "log_file_type", Json::intValue, (int)sLogFileType ).asInt() ); + param_lib, "log_file_type", Json::uintValue, (uint32_t)sLogFileType ).asUInt() ); + sLogFileAppend = JVgetOptional( + param_lib, "log_file_append", Json::booleanValue, sLogFileAppend ).asBool(); sLogFileRotatingSize = JVgetOptional( param_lib, "log_file_rotating_size", - Json::intValue, (int)sLogFileRotatingSize ).asInt(); + Json::uintValue, (uint32_t)sLogFileRotatingSize ).asUInt(); sLogFileRotatingNum = JVgetOptional( param_lib, "log_file_rotating_num", - Json::intValue, (int)sLogFileRotatingNum ).asInt(); + Json::uintValue, (uint32_t)sLogFileRotatingNum ).asUInt(); // Frequency detection mFrequencyDetectionPeriod = JVgetOptional( param_lib, "frequency_detection_period", @@ -262,16 +288,26 @@ class DRM_LOCAL DrmManager::Impl { mFrequencyDetectionThreshold = JVgetOptional( param_lib, "frequency_detection_threshold", Json::uintValue, mFrequencyDetectionThreshold).asDouble(); - // Others + // Retry parameters mWSRetryPeriodLong = JVgetOptional( param_lib, "ws_retry_period_long", Json::uintValue, mWSRetryPeriodLong).asUInt(); mWSRetryPeriodShort = JVgetOptional( param_lib, "ws_retry_period_short", Json::uintValue, mWSRetryPeriodShort).asUInt(); + mWSApiRetryDuration = JVgetOptional( param_lib, "ws_api_retry_duration", + Json::uintValue, mWSApiRetryDuration).asUInt(); mWSRequestTimeout = JVgetOptional( param_lib, "ws_request_timeout", Json::uintValue, mWSRequestTimeout).asUInt(); if ( mWSRequestTimeout == 0 ) Throw( DRM_BadArg, "ws_request_timeout must not be 0"); + + // Host and Card information + mHostDataVerbosity = static_cast( JVgetOptional( + param_lib, "host_data_verbosity", Json::uintValue, (uint32_t)mHostDataVerbosity ).asUInt() ); } + mHealthPeriod = 0; + mHealthRetryTimeout = mWSRequestTimeout; + mHealthRetrySleep = mWSRetryPeriodShort; + // Customize logging configuration updateLog(); @@ -332,7 +368,7 @@ class DRM_LOCAL DrmManager::Impl { void createFileLog( const std::string file_path, const eLogFileType type, const spdlog::level::level_enum level, const std::string format, - const size_t rotating_size, const size_t rotating_num ) { + const size_t rotating_size, const size_t rotating_num, const bool file_append ) { spdlog::sink_ptr log_sink; std::string version_list = fmt::format( "Installed versions:\n\t-drmlib: {}\n\t-libcurl: {}\n\t-jsoncpp: {}\n\t-spdlog: {}.{}.{}", DRMLIB_VERSION, curl_version(), JSONCPP_VERSION_STRING, @@ -348,10 +384,10 @@ class DRM_LOCAL DrmManager::Impl { } if ( type == eLogFileType::BASIC ) log_sink = std::make_shared( - file_path, true); + file_path, !file_append); else // type == eLogFileType::ROTATING log_sink = std::make_shared( - file_path, rotating_size, rotating_num); + file_path, rotating_size*1024, rotating_num); } log_sink->set_pattern( format ); log_sink->set_level( spdlog::level::info ); @@ -374,7 +410,7 @@ class DRM_LOCAL DrmManager::Impl { // File logging createFileLog( sLogFilePath, sLogFileType, sLogFileVerbosity, sLogFileFormat, - sLogFileRotatingSize, sLogFileRotatingNum ); + sLogFileRotatingSize, sLogFileRotatingNum, sLogFileAppend ); } catch( const spdlog::spdlog_ex& ex ) { std::cout << "Failed to update logging settings: " << ex.what() << std::endl; @@ -382,15 +418,128 @@ class DRM_LOCAL DrmManager::Impl { } void uninitLog() { - if ( sLogger ) + if ( sLogger ) { + Debug( "Log messages are flushed now." ); sLogger->flush(); + } + } + + bool findXrtUtility() { + // Check XILINX_XRT environment variable existence + char * env_val = getenv( "XILINX_XRT" ); + if (env_val == NULL) { + Debug( "XILINX_XRT variable is not defined" ); + mXrtPath.clear(); + return false; + } + mXrtPath = std::string( env_val ); + Debug( "XILINX_XRT variable is defined: {}", mXrtPath ); + + // Check xbutil existence + std::string xrt_bin_dir = fmt::format( "{}{}bin", mXrtPath, PATH_SEP ); + mXbutil = fmt::format( "{}{}xbutil", xrt_bin_dir, PATH_SEP ); + if ( !isFile( mXbutil ) ) { + // If xbutil does not exist + Debug( "xbutil tool could not be found in {}", xrt_bin_dir ); + mXbutil.clear(); + return false; + } + Debug( "xbutil tool has been found in {}", mXbutil ); + return true; + } + + void getHostAndCardInfo() { + + Debug( "Host and CSP information verbosity: {}", static_cast( mHostDataVerbosity ) ); + + // Depending on the host data verbosity + if ( mHostDataVerbosity == eHostDataVerbosity::NONE ) { + return; + } + + // Gather CSP information if detected + Json::Value csp_node = Json::nullValue; + uint32_t ws_verbosity = getDrmWSClient().getVerbosity(); + mHostConfigData["csp"] = GetCspInfo( ws_verbosity ); + Debug( "CSP information:\n{}", mHostConfigData["csp"].toStyledString() ); + + // Gather host and card information if xbutil existing + if ( findXrtUtility() ) { + Json::Value hostcard_node = Json::nullValue; + try { + // Call xbutil to collect host and card data + std::string cmd = fmt::format( "{} dump", mXbutil ); + std::string cmd_out = exec_cmd( cmd ); + + // Parse collected data and save to header + Json::Value xbutil_node = parseJsonString( cmd_out ); + + if ( mHostDataVerbosity == eHostDataVerbosity::FULL ) { + // Verbosity is FULL + hostcard_node = xbutil_node; + } else { + // Verbosity is PARTIAL + for(Json::Value::iterator itr=xbutil_node.begin(); itr!=xbutil_node.end(); ++itr) { + std::string key = itr.key().asString(); + try { + if ( ( key == "version" ) + || ( key == "system" ) + || ( key == "runtime" ) + ) + hostcard_node[key] = *itr; + else if ( key == "board" ) { + // Add general info node + hostcard_node[key]["info"] = itr->get("info", Json::nullValue); + // Try to get the number of kernels + Json::Value compute_unit_node = itr->get("compute_unit", Json::nullValue); + if ( compute_unit_node != Json::nullValue ) + hostcard_node[key]["compute_unit"] = compute_unit_node.size(); + else + hostcard_node[key]["compute_unit"] = -1; + // Add XCLBIN UUID + hostcard_node[key]["xclbin"] = itr->get("xclbin", Json::nullValue); + } + } catch( const std::exception &e ) { + Debug( "Could not extract Host Information for key {}", key ); + } + } + } + } catch( const std::exception &e ) { + Debug( "No host and card information collected: {}", e.what() ); + hostcard_node = fmt::format( "No host and card information collected: {}", e.what() ); + } + Debug( "Host and card information:\n{}", hostcard_node.toStyledString() ); + mHostConfigData["host_card"] = hostcard_node; + } + } + + Json::Value buildSettingsNode() { + Json::Value settings; + settings["frequency_detection_method"] = mIsFreqDetectionMethod1? 1:2; + settings["bypass_frequency_detection"] = mBypassFrequencyDetection; + settings["frequency_detection_threshold"] = mFrequencyDetectionThreshold; + settings["frequency_detection_period"] = mFrequencyDetectionPeriod; + settings["log_file_type"] = static_cast( sLogFileType ); + settings["log_file_append"] = sLogFileAppend; + settings["log_file_rotating_size"] = static_cast( sLogFileRotatingSize ); + settings["log_file_rotating_num"] = static_cast( sLogFileRotatingNum ); + settings["log_file_verbosity"] = static_cast( sLogFileVerbosity ); + settings["log_verbosity"] = static_cast( sLogConsoleVerbosity ); + settings["ws_retry_period_long"] = mWSRetryPeriodLong; + settings["ws_retry_period_short"] = mWSRetryPeriodShort; + settings["ws_request_timeout"] = mWSRequestTimeout; + settings["health_period"] = mHealthPeriod; + settings["health_retry"] = mHealthRetryTimeout; + settings["health_retry_sleep"] = mHealthRetrySleep; + settings["ws_api_retry_duration"] = mWSApiRetryDuration; + settings["host_data_verbosity"] = static_cast( mHostDataVerbosity ); + return settings; } uint32_t getMailboxSize() const { uint32_t roSize, rwSize; - std::lock_guard lock( mDrmControllerMutex ); - checkDRMCtlrRet( getDrmController().writeMailBoxFilePageRegister() ); checkDRMCtlrRet( getDrmController().readMailboxFileSizeRegister( roSize, rwSize ) ); + Debug2( "Full mailbox size: {}", rwSize ); return rwSize; } @@ -410,8 +559,6 @@ class DRM_LOCAL DrmManager::Impl { uint32_t roSize, rwSize; std::vector roData, rwData; - std::lock_guard lock( mDrmControllerMutex ); - checkDRMCtlrRet( getDrmController().writeMailBoxFilePageRegister() ); checkDRMCtlrRet( getDrmController().readMailboxFileRegister( roSize, rwSize, roData, rwData) ); if ( index >= rwData.size() ) @@ -427,8 +574,6 @@ class DRM_LOCAL DrmManager::Impl { uint32_t roSize, rwSize; std::vector roData, rwData; - std::lock_guard lock( mDrmControllerMutex ); - checkDRMCtlrRet( getDrmController().writeMailBoxFilePageRegister() ); checkDRMCtlrRet( getDrmController().readMailboxFileRegister( roSize, rwSize, roData, rwData) ); if ( (uint32_t)index >= rwData.size() ) @@ -450,7 +595,6 @@ class DRM_LOCAL DrmManager::Impl { std::vector roData, rwData; std::lock_guard lockk( mDrmControllerMutex ); - checkDRMCtlrRet( getDrmController().writeMailBoxFilePageRegister() ); checkDRMCtlrRet( getDrmController().readMailboxFileRegister( roSize, rwSize, roData, rwData) ); if ( index >= rwData.size() ) @@ -467,7 +611,6 @@ class DRM_LOCAL DrmManager::Impl { std::vector roData, rwData; std::lock_guard lock( mDrmControllerMutex ); - checkDRMCtlrRet( getDrmController().writeMailBoxFilePageRegister() ); checkDRMCtlrRet( getDrmController().readMailboxFileRegister( roSize, rwSize, roData, rwData) ); if ( index >= rwData.size() ) Unreachable( "Index {} overflows the Mailbox memory: max index is {}. ", @@ -499,47 +642,43 @@ class DRM_LOCAL DrmManager::Impl { Unreachable( "Unsupported regName argument: {}. ", regName ); //LCOV_EXCL_LINE } - unsigned int readDrmRegister( const std::string& regName, uint32_t& value ) const { - int ret = 0; - ret = f_read_register( getDrmRegisterOffset( regName ), &value ); + unsigned int readDrmAddress( const uint32_t address, uint32_t& value ) const { + std::lock_guard lock( mDrmControllerMutex ); + int ret = f_read_register( address, &value ); if ( ret != 0 ) { - Error( "Error in read register callback, errcode = {}: failed to read register {}", ret, regName ); + Error( "Error in read register callback, errcode = {}: failed to read address {}", ret, address ); return (uint32_t)(-1); } - Debug2( "Read DRM register {} = 0x{:08x}", regName, value ); + Debug2( "Read DRM address 0x{:x} = 0x{:08x}", address, value ); return 0; } - unsigned int writeDrmRegister( const std::string& regName, uint32_t value ) const { - int ret = 0; - ret = f_write_register( getDrmRegisterOffset( regName ), value ); - if ( ret ) { - Error( "Error in write register callback, errcode = {}: failed to write {} to register {}", ret, value, regName ); + unsigned int readDrmRegister( const std::string& regName, uint32_t& value ) const { + int ret = readDrmAddress( getDrmRegisterOffset( regName ), value ); + if ( ret != 0 ) { + Error( "Error in read register callback, errcode = {}: failed to read register {}", ret, regName ); return (uint32_t)(-1); } - Debug2( "Write DRM register {} = 0x{:08x}", regName, value ); return 0; } - unsigned int readDrmAddress( const uint32_t address, uint32_t& value ) const { - int ret = 0; - ret = f_read_register( address, &value ); - if ( ret != 0 ) { - Error( "Error in read register callback, errcode = {}: failed to read address {}", ret, address ); + unsigned int writeDrmAddress( const uint32_t address, uint32_t value ) const { + std::lock_guard lock( mDrmControllerMutex ); + int ret = f_write_register( address, value ); + if ( ret ) { + Error( "Error in write register callback, errcode = {}: failed to write {} to address {}", ret, value, address ); return (uint32_t)(-1); } - Debug2( "Read DRM address 0x{:x} = 0x{:08x}", address, value ); + Debug2( "Wrote DRM address 0x{:x} = 0x{:08x}", address, value ); return 0; } - unsigned int writeDrmAddress( const uint32_t address, uint32_t value ) const { - int ret = 0; - ret = f_write_register( address, value ); + unsigned int writeDrmRegister( const std::string& regName, uint32_t value ) const { + int ret = writeDrmAddress( getDrmRegisterOffset( regName ), value ); if ( ret ) { - Error( "Error in write register callback, errcode = {}: failed to write {} to address {}", ret, value, address ); + Error( "Error in write register callback, errcode = {}: failed to write {} to register {}", ret, value, regName ); return (uint32_t)(-1); } - Debug2( "Wrote DRM address 0x{:x} = 0x{:08x}", address, value ); return 0; } @@ -577,14 +716,14 @@ class DRM_LOCAL DrmManager::Impl { auto drmMajor = ( mDrmVersion >> 16 ) & 0xFF; auto drmMinor = ( mDrmVersion >> 8 ) & 0xFF; - if ( drmMajor < HDK_COMPATIBLITY_LIMIT_MAJOR ) { + if ( drmMajor < HDK_COMPATIBILITY_LIMIT_MAJOR ) { Throw( DRM_CtlrError, "This DRM Lib {} is not compatible with the DRM HDK version {}: To be compatible HDK version shall be > or equal to {}.{}.x", - DRMLIB_VERSION, drmVersionDot, HDK_COMPATIBLITY_LIMIT_MAJOR, HDK_COMPATIBLITY_LIMIT_MINOR ); - } else if ( ( drmMajor == HDK_COMPATIBLITY_LIMIT_MAJOR ) && ( drmMinor < HDK_COMPATIBLITY_LIMIT_MINOR ) ) { + DRMLIB_VERSION, drmVersionDot, HDK_COMPATIBILITY_LIMIT_MAJOR, HDK_COMPATIBILITY_LIMIT_MINOR ); + } else if ( ( drmMajor == HDK_COMPATIBILITY_LIMIT_MAJOR ) && ( drmMinor < HDK_COMPATIBILITY_LIMIT_MINOR ) ) { Throw( DRM_CtlrError, "This DRM Library version {} is not compatible with the DRM HDK version {}: To be compatible HDK version shall be > or equal to {}.{}.x", - DRMLIB_VERSION, drmVersionDot, HDK_COMPATIBLITY_LIMIT_MAJOR, HDK_COMPATIBLITY_LIMIT_MINOR ); + DRMLIB_VERSION, drmVersionDot, HDK_COMPATIBILITY_LIMIT_MAJOR, HDK_COMPATIBILITY_LIMIT_MINOR ); } Debug( "DRM HDK Version: {}", drmVersionDot ); } @@ -696,7 +835,7 @@ class DRM_LOCAL DrmManager::Impl { std::placeholders::_1, std::placeholders::_2 ) )); - } catch( const std::exception& e ) { + } catch( const std::exception &e ) { std::string err_msg(e.what()); if ( err_msg.find( "Unable to select a register strategy that is compatible with the DRM Controller" ) != std::string::npos ) @@ -760,21 +899,35 @@ class DRM_LOCAL DrmManager::Impl { // Get DRM HDK version std::string getDrmCtrlVersion() const { std::string drmVersion; - std::lock_guard lock( mDrmControllerMutex ); checkDRMCtlrRet( getDrmController().extractDrmVersion( drmVersion ) ); return drmVersion; } + void checkSessionIDFromWS( const Json::Value license_json ) { + std::string ws_sessionID = license_json["metering"]["sessionId"].asString(); + if ( !mSessionID.empty() && ( mSessionID != ws_sessionID ) ) { + Warning( "Session ID mismatch: WebService returns '{}' but '{}' is expected", ws_sessionID, mSessionID ); //LCOV_EXCL_LINE + } else if ( mSessionID.empty() ) { + mSessionID = ws_sessionID; + } + } + + void checkSessionIDFromDRM( const Json::Value license_json ) { + std::string drm_sessionID = license_json["sessionId"].asString(); + if ( !mSessionID.empty() && ( mSessionID != drm_sessionID ) ) { + Warning( "Session ID mismatch: DRM IP returns '{}' but '{}' is expected", drm_sessionID, mSessionID ); //LCOV_EXCL_LINE + } else if ( mSessionID.empty() ) { + mSessionID = drm_sessionID; + } + } + void getNumActivator( uint32_t& value ) const { - std::lock_guard lock( mDrmControllerMutex ); - checkDRMCtlrRet( getDrmController().writeRegistersPageRegister() ); checkDRMCtlrRet( getDrmController().readNumberOfDetectedIpsStatusRegister( value ) ); } uint64_t getTimerCounterValue() const { uint32_t licenseTimerCounterMsb(0), licenseTimerCounterLsb(0); uint64_t licenseTimerCounter(0); - std::lock_guard lock( mDrmControllerMutex ); checkDRMCtlrRet( getDrmController().sampleLicenseTimerCounter( licenseTimerCounterMsb, licenseTimerCounterLsb ) ); licenseTimerCounter = licenseTimerCounterMsb; @@ -821,7 +974,7 @@ class DRM_LOCAL DrmManager::Impl { // Get information from DRM Controller getDesignInfo( drmVersion, dna, vlnvFile, mailboxReadOnly ); - // Fulfill DRM section + // Fulfill with DRM section json_output["drmlibVersion"] = DRMLIB_VERSION; json_output["lgdnVersion"] = drmVersion; json_output["dna"] = dna; @@ -833,9 +986,22 @@ class DRM_LOCAL DrmManager::Impl { json_output["vlnvFile"][i_str]["version"] = std::string("x") + vlnvFile[i].substr(12, 4); } + // Fulfill with product information if ( !mailboxReadOnly.empty() ) { try { - json_output["product"] = parseJsonString( mailboxReadOnly ); + Json::Value product_info = parseJsonString( mailboxReadOnly ); + if ( product_info.isMember( "product_id" ) ) + json_output["product"] = product_info["product_id"]; + else + json_output["product"] = product_info; + if ( product_info.isMember( "pkg_version" ) ) { + json_output["pkg_version"] = product_info["pkg_version"]; + Debug( "HDK Generator version: {}", json_output["pkg_version"].asString() ); + } + if ( product_info.isMember( "dna_type" ) ) { + json_output["dna_type"] = product_info["dna_type"]; + Debug( "HDK DNA type: {}", json_output["dna_type"].asString() ); + } } catch( const Exception &e ) { if ( e.getErrCode() == DRM_BadFormat ) Throw( DRM_BadFormat, "Failed to parse Read-Only Mailbox in DRM Controller: {}", e.what() ); @@ -844,19 +1010,18 @@ class DRM_LOCAL DrmManager::Impl { } else { Debug( "Could not find product ID information in DRM Controller Mailbox" ); } + return json_output; } - Json::Value getMeteringStart() { + Json::Value getMeteringStart() const { Json::Value json_request( mHeaderJsonRequest ); uint32_t numberOfDetectedIps; std::string saasChallenge; std::vector meteringFile; - mLicenseCounter = 0; - Debug( "Build web request #{} to create new session", mLicenseCounter ); + Debug( "Build license request #{} to create new session", mLicenseCounter ); - std::lock_guard lock( mDrmControllerMutex ); // Request challenge and metering info for first request checkDRMCtlrRet( getDrmController().initialization( numberOfDetectedIps, saasChallenge, meteringFile ) ); json_request["saasChallenge"] = saasChallenge; @@ -869,14 +1034,13 @@ class DRM_LOCAL DrmManager::Impl { return json_request; } - Json::Value getMeteringWait() { + Json::Value getMeteringRunning() { Json::Value json_request( mHeaderJsonRequest ); uint32_t numberOfDetectedIps; std::string saasChallenge; std::vector meteringFile; - Debug( "Build web request #{} to maintain current session", mLicenseCounter ); - std::lock_guard lock( mDrmControllerMutex ); + Debug( "Build license request #{} to maintain current session", mLicenseCounter ); // Check if an error occurred checkDRMCtlrRet( getDrmController().waitNotTimerInitLoaded( 5 ) ); @@ -884,6 +1048,7 @@ class DRM_LOCAL DrmManager::Impl { checkDRMCtlrRet( getDrmController().synchronousExtractMeteringFile( numberOfDetectedIps, saasChallenge, meteringFile ) ); json_request["saasChallenge"] = saasChallenge; json_request["sessionId"] = meteringFile[0].substr( 0, 16 ); + checkSessionIDFromDRM( json_request ); if ( !isNodeLockedMode() ) json_request["drm_frequency"] = mFrequencyCurr; @@ -898,14 +1063,14 @@ class DRM_LOCAL DrmManager::Impl { std::string saasChallenge; std::vector meteringFile; - Debug( "Build web request #{} to stop current session", mLicenseCounter ); - std::lock_guard lock( mDrmControllerMutex ); + Debug( "Build license request #{} to stop current session", mLicenseCounter ); // Request challenge and metering info for first request checkDRMCtlrRet( getDrmController().endSessionAndExtractMeteringFile( numberOfDetectedIps, saasChallenge, meteringFile ) ); json_request["saasChallenge"] = saasChallenge; json_request["sessionId"] = meteringFile[0].substr( 0, 16 ); + checkSessionIDFromDRM( json_request ); if ( !isNodeLockedMode() ) json_request["drm_frequency"] = mFrequencyCurr; @@ -914,32 +1079,40 @@ class DRM_LOCAL DrmManager::Impl { return json_request; } - uint64_t getMeteringData() const { + Json::Value getMeteringHealth() const { + Json::Value json_request( mHeaderJsonRequest ); uint32_t numberOfDetectedIps; std::string saasChallenge; std::vector meteringFile; - uint64_t meteringData = 0; - { - Debug( "Waiting metering access mutex from getMeteringData" ); + Debug( "Waiting metering access mutex from getMeteringHealth" ); std::lock_guard lockMetering( mMeteringAccessMutex ); - Debug( "Acquired metering access mutex from getMeteringData" ); - - Debug( "Get metering data from current session on DRM controller" ); - std::lock_guard lock( mDrmControllerMutex ); - if ( isNodeLockedMode() || isLicenseActive() ) { - checkDRMCtlrRet( getDrmController().asynchronousExtractMeteringFile( - numberOfDetectedIps, saasChallenge, meteringFile ) ); - std::string meteringDataStr = meteringFile[2].substr( 16, 16 ); - errno = 0; - meteringData = strtoull( meteringDataStr.c_str(), nullptr, 16 ); - if ( errno ) - Throw( DRM_CtlrError, "Could not convert string '{}' to unsigned long long.", - meteringDataStr ); + Debug( "Acquired metering access mutex from getMeteringHealth" ); + + Debug( "Build health request #{}", mHealthCounter ); + { + std::lock_guard lock( mDrmControllerMutex ); + if ( isNodeLockedMode() || isSessionRunning() ) { + checkDRMCtlrRet( getDrmController().asynchronousExtractMeteringFile( + numberOfDetectedIps, saasChallenge, meteringFile ) ); + } else { + Warning( "Cannot access metering data when no session is running" ); + } } } - Debug( "Released metering access mutex from getMeteringData" ); - return meteringData; + Debug( "Released metering access mutex from getMeteringHealth" ); + json_request["saasChallenge"] = saasChallenge; + if ( meteringFile.size() ) { + json_request["sessionId"] = meteringFile[0].substr( 0, 16 ); + } else { + json_request["sessionId"] = ""; + } + // Finalize the request with the collected data + json_request["meteringFile"] = std::accumulate( meteringFile.begin(), meteringFile.end(), std::string("") ); + json_request["drm_frequency"] = mFrequencyCurr; + json_request["request"] = "health"; + json_request["health_id"] = mHealthCounter++; + return json_request; } // Get common info @@ -968,8 +1141,6 @@ class DRM_LOCAL DrmManager::Impl { bool isSessionRunning()const { bool sessionRunning( false ); - std::lock_guard lock( mDrmControllerMutex ); - checkDRMCtlrRet( getDrmController().writeRegistersPageRegister() ); checkDRMCtlrRet( getDrmController().readSessionRunningStatusRegister( sessionRunning ) ); Debug( "DRM session running state: {}", sessionRunning ); return sessionRunning; @@ -977,8 +1148,6 @@ class DRM_LOCAL DrmManager::Impl { bool isDrmCtrlInNodelock()const { bool isNodelocked( false ); - std::lock_guard lock( mDrmControllerMutex ); - checkDRMCtlrRet( getDrmController().writeRegistersPageRegister() ); checkDRMCtlrRet( getDrmController().readLicenseNodeLockStatusRegister( isNodelocked ) ); Debug( "DRM Controller node-locked status: {}", isNodelocked ); return isNodelocked; @@ -986,45 +1155,49 @@ class DRM_LOCAL DrmManager::Impl { bool isDrmCtrlInMetering()const { bool isMetering( false ); - std::lock_guard lock( mDrmControllerMutex ); - checkDRMCtlrRet( getDrmController().writeRegistersPageRegister() ); checkDRMCtlrRet( getDrmController().readLicenseMeteringStatusRegister( isMetering ) ); Debug( "DRM Controller metering status: {}", isMetering ); return isMetering; } bool isReadyForNewLicense() const { - bool ret( false ); - std::lock_guard lock( mDrmControllerMutex ); - checkDRMCtlrRet( getDrmController().writeRegistersPageRegister() ); - checkDRMCtlrRet( getDrmController().readLicenseTimerInitLoadedStatusRegister( ret ) ); - Debug( "DRM readiness to receive a new license: {}", !ret ); - return !ret; + uint32_t numberOfLicenseTimerLoaded; + checkDRMCtlrRet( getDrmController().readNumberOfLicenseTimerLoadedStatusRegister( + numberOfLicenseTimerLoaded ) ); + bool readiness = ( numberOfLicenseTimerLoaded < 2 ); + Debug( "DRM readiness to receive a new license: {} (# loaded licenses = {})", readiness, numberOfLicenseTimerLoaded ); + return readiness; } bool isLicenseActive() const { bool isLicenseEmpty( false ); - std::lock_guard lock( mDrmControllerMutex ); - checkDRMCtlrRet( getDrmController().writeRegistersPageRegister() ); checkDRMCtlrRet( getDrmController().readLicenseTimerCountEmptyStatusRegister( isLicenseEmpty ) ); return !isLicenseEmpty; } - Json::Value getLicense( const Json::Value& request_json, const uint32_t& timeout, - const uint32_t& short_retry_period = 0, const uint32_t& long_retry_period = 0 ) { - TClock::time_point deadline = TClock::now() + std::chrono::seconds( timeout ); + Json::Value getLicense( Json::Value& request_json, const uint32_t& timeout, + int32_t short_retry_period = -1, int32_t long_retry_period = -1 ) { + TClock::time_point deadline; + if ( timeout == 0 ) { + deadline = TClock::now() + std::chrono::seconds( mWSRequestTimeout ); + short_retry_period = -1; + long_retry_period = -1; + } else { + deadline = TClock::now() + std::chrono::seconds( timeout ); + } return getLicense( request_json, deadline, short_retry_period, long_retry_period ); } - Json::Value getLicense( const Json::Value& request_json, const TClock::time_point& deadline, - const uint32_t& short_retry_period = 0, const uint32_t& long_retry_period = 0 ) { + Json::Value getLicense( Json::Value& request_json, const TClock::time_point& deadline, + int32_t short_retry_period = -1, int32_t long_retry_period = -1 ) { TClock::duration long_duration = std::chrono::seconds( long_retry_period ); TClock::duration short_duration = std::chrono::seconds( short_retry_period ); - uint32_t attempt = 0; TClock::duration wait_duration; bool token_valid(false); + uint32_t oauth_attempt = 0; + uint32_t lic_attempt = 0; while ( 1 ) { token_valid = false; @@ -1033,30 +1206,30 @@ class DRM_LOCAL DrmManager::Impl { getDrmWSClient().requestOAuth2token( deadline ); token_valid = true; } catch ( const Exception& e ) { + lic_attempt = 0; + if ( e.getErrCode() == DRM_WSTimedOut ) { + // Reached timeout + Throw( DRM_WSError, "Timeout on Authentication request after {} attempts", oauth_attempt ); + } if ( e.getErrCode() != DRM_WSMayRetry ) { throw; } // It is retryable - attempt ++; - if ( TClock::now() > deadline ) { - // Reached timeout - Throw( DRM_WSError, "Timeout on Authentication request after {} attempts", attempt ); - } - if ( short_retry_period == 0 ) { + oauth_attempt ++; + if ( short_retry_period == -1 ) { // No retry throw; } - // Perform retry - if ( long_retry_period == 0 ) { + if ( long_retry_period == -1 ) { wait_duration = short_duration; } else { - if ( ( deadline - TClock::now() ) < long_duration ) + if ( ( deadline - TClock::now() ) <= long_duration ) wait_duration = short_duration; else wait_duration = long_duration; } Warning( "Attempt #{} to obtain a new OAuth2 token failed with message: {}. New attempt planned in {} seconds", - attempt, e.what(), wait_duration.count()/1000000000 ); + oauth_attempt, e.what(), wait_duration.count()/1000000000 ); // Wait a bit before retrying sleepOrExit( wait_duration ); } @@ -1064,32 +1237,39 @@ class DRM_LOCAL DrmManager::Impl { // Get new license try { + // Add Host and Card information for the first 2 requests + if ( mLicenseCounter < 2 ) + request_json["host_configuration"] = mHostConfigData; + // Add settings parameters + request_json["settings"] = buildSettingsNode(); + // Send license request and wait for the answer return getDrmWSClient().requestLicense( request_json, deadline ); } catch ( const Exception& e ) { + oauth_attempt = 0; + if ( e.getErrCode() == DRM_WSTimedOut ) { + // Reached timeout + Throw( DRM_WSError, "Timeout on License request after {} attempts", lic_attempt ); + } if ( e.getErrCode() != DRM_WSMayRetry ) { throw; } // It is retryable - attempt ++; - if ( TClock::now() > deadline ) { - // Reached timeout - Throw( DRM_WSError, "Timeout on License request after {} attempts", attempt ); - } - if ( short_retry_period == 0 ) { + lic_attempt ++; + if ( short_retry_period == -1 ) { // No retry throw; } - // Perform retry - if ( long_retry_period == 0 ) { + // Evaluate the next retry + if ( long_retry_period == -1 ) { wait_duration = short_duration; } else { - if ( ( deadline - TClock::now() ) < long_duration ) + if ( ( deadline - TClock::now() ) <= long_duration ) wait_duration = short_duration; else wait_duration = long_duration; } Warning( "Attempt #{} to obtain a new License failed with message: {}. New attempt planned in {} seconds", - attempt, e.what(), wait_duration.count()/1000000000 ); + lic_attempt, e.what(), wait_duration.count()/1000000000 ); // Wait a bit before retrying sleepOrExit( wait_duration ); } @@ -1098,8 +1278,6 @@ class DRM_LOCAL DrmManager::Impl { void setLicense( const Json::Value& license_json ) { - std::lock_guard lock( mDrmControllerMutex ); - Debug( "Provisioning license #{} on DRM controller", mLicenseCounter ); std::string dna = mHeaderJsonRequest["dna"].asString(); @@ -1115,9 +1293,12 @@ class DRM_LOCAL DrmManager::Impl { /// Save new Session ID mSessionID = JVgetRequired( metering_node, "sessionId", Json::stringValue ).asString(); Debug( "Saving session ID: {}", mSessionID ); + } else { + /// Verify Session ID + checkSessionIDFromWS( license_json ); } - // Extract license key and license timer from web service response + /// Extract license key and license timer from web service response if ( mLicenseCounter == 0 ) licenseKey = JVgetRequired( dna_node, "key", Json::stringValue ).asString(); if ( !isNodeLockedMode() ) @@ -1125,29 +1306,35 @@ class DRM_LOCAL DrmManager::Impl { mLicenseDuration = JVgetRequired( metering_node, "timeoutSecond", Json::uintValue ).asUInt(); if ( mLicenseDuration == 0 ) Warning( "'timeoutSecond' field sent by License WS must not be 0" ); + } catch( const Exception &e ) { if ( e.getErrCode() != DRM_BadFormat ) throw; Throw( DRM_WSRespError, "Malformed response from License Web Service: {}", e.what() ); } + std::lock_guard lock( mDrmControllerMutex ); + if ( mLicenseCounter == 0 ) { // Load key - bool activationDone = false; + bool activationDone( false ); uint8_t activationErrorCode; checkDRMCtlrRet( getDrmController().activate( licenseKey, activationDone, activationErrorCode ) ); if ( activationErrorCode ) { Throw( DRM_CtlrError, "Failed to activate license on DRM controller, activationErr: 0x{:x}", activationErrorCode ); } + if ( !activationDone ) + Throw( DRM_CtlrError, "Failed to activate license on DRM controller, activationDone: {}", + activationDone ); Debug( "Wrote license key of session ID: {}", mSessionID ); } // Load license timer if ( !isNodeLockedMode() ) { - bool licenseTimerEnabled = false; - checkDRMCtlrRet( - getDrmController().loadLicenseTimerInit( licenseTimer, licenseTimerEnabled ) ); + bool licenseTimerEnabled( false ); + checkDRMCtlrRet( getDrmController().loadLicenseTimerInit( licenseTimer, + licenseTimerEnabled ) ); if ( !licenseTimerEnabled ) { Throw( DRM_CtlrError, "Failed to load license timer on DRM controller, licenseTimerEnabled: 0x{:x}", @@ -1157,6 +1344,28 @@ class DRM_LOCAL DrmManager::Impl { mLicenseCounter, mSessionID, mLicenseDuration ); } + // Wait until license has been pushed to Activator's port + bool activationCodesTransmitted( false ); + TClock::duration timeSpan; + double mseconds( 0.0 ); + TClock::time_point timeStart = TClock::now(); + + while( mseconds < ACTIVATIONCODE_TRANSMISSION_TIMEOUT_MS ) { + checkDRMCtlrRet( getDrmController().readActivationCodesTransmittedStatusRegister( + activationCodesTransmitted ) ); + timeSpan = TClock::now() - timeStart; + mseconds = 1000.0 * double( timeSpan.count() ) * TClock::period::num / TClock::period::den; + if ( activationCodesTransmitted ) { + Debug( "License #{} transmitted after {:f} ms", mLicenseCounter, mseconds ); + break; + } + Debug2( "License #{} not transmitted yet after {:f} ms", mLicenseCounter, mseconds ); + } + if ( !activationCodesTransmitted ) { + Throw( DRM_CtlrError, "DRM Controller could not transmit Licence #{} to activators after {:f} ms. ", mLicenseCounter, mseconds ); //LCOV_EXCL_LINE + } + mExpirationTime += std::chrono::seconds( mLicenseDuration ); + // Check DRM Controller has switched to the right license mode bool is_nodelocked = isDrmCtrlInNodelock(); bool is_metered = isDrmCtrlInMetering(); @@ -1177,6 +1386,86 @@ class DRM_LOCAL DrmManager::Impl { mLicenseCounter ++; } + Json::Value postHealth( const Json::Value& request_json, const TClock::time_point& deadline, + const int32_t& retry_period = -1 ) { + + bool token_valid(false); + uint32_t oauth_attempt = 0; + uint32_t lic_attempt = 0; + TClock::duration retry_duration = std::chrono::seconds( retry_period ); + + while ( 1 ) { + token_valid = false; + // Get valid OAUth2 token + try { + getDrmWSClient().requestOAuth2token( deadline ); + token_valid = true; + } catch ( const Exception& e ) { + lic_attempt = 0; + if ( e.getErrCode() == DRM_WSTimedOut ) { + // Reached timeout + Warning( "Timeout on Authentication request after {} attempts", oauth_attempt ); + return Json::nullValue; + } + if ( e.getErrCode() != DRM_WSMayRetry ) { + Error( "Health request error: {}", e.what() ); + return Json::nullValue; + } + // It is retryable + oauth_attempt ++; + if ( retry_period == -1 ) { + // No retry + return Json::nullValue; + } + Warning( "Attempt #{} to obtain a new OAuth2 token failed with message: {}. New attempt planned in {} seconds", + oauth_attempt, e.what(), retry_duration.count()/1000000000 ); + // Wait a bit before retrying + sleepOrExit( retry_duration ); + } + if ( !token_valid ) continue; + + // Get new license + try { + return getDrmWSClient().requestHealth( request_json, deadline ); + } catch ( const Exception& e ) { + oauth_attempt = 0; + if ( e.getErrCode() == DRM_WSTimedOut ) { + // Reached timeout + Warning( "Timeout on Health request after {} attempts", lic_attempt ); + return Json::nullValue; + } + if ( e.getErrCode() != DRM_WSMayRetry ) { + Error( "Health request error: {}", e.what() ); + return Json::nullValue; + } + // It is retryable + lic_attempt ++; + if ( retry_period == -1 ) { + // No retry + return Json::nullValue; + } + // Perform retry + Warning( "Attempt #{} to send a new Health request failed with message: {}. New attempt planned in {} seconds", + lic_attempt, e.what(), retry_duration.count()/1000000000 ); + // Wait a bit before retrying + sleepOrExit( retry_duration ); + } + } + } + + Json::Value performHealth( const uint32_t retry_timeout, const uint32_t retry_sleep) { + // Get next data from DRM Controller + Json::Value request_json = getMeteringHealth(); + // Check session ID + checkSessionIDFromDRM( request_json ); + if ( request_json["meteringFile"].empty() ) + Unreachable( "Received an empty metering file from DRM Controller" ); //LCOV_EXCL_LINE + // Compute retry period + TClock::time_point retry_deadline = TClock::now() + std::chrono::seconds( retry_timeout ); + // Post next data to server + return postHealth( request_json, retry_deadline, retry_sleep ); + } + std::string getDesignHash() { std::string drmVersion, dna, mailboxReadOnly; std::vector vlnvFile; @@ -1241,9 +1530,7 @@ class DRM_LOCAL DrmManager::Impl { Json::Value request_json = parseJsonFile( mNodeLockRequestFilePath ); Debug( "Parsed Node-locked License Request file: {}", request_json .toStyledString() ); /// - Send request to web service and receive the new license - TClock::time_point deadline = - TClock::now() + std::chrono::seconds( mWSRequestTimeout ); - license_json = getLicense( request_json, deadline, mWSRetryPeriodShort ); + license_json = getLicense( request_json, mWSApiRetryDuration, mWSRetryPeriodShort ); /// - Save the license to file saveJsonToFile( mNodeLockLicenseFilePath, license_json ); Debug( "Requested and saved new node-locked license file: {}", mNodeLockLicenseFilePath ); @@ -1263,8 +1550,6 @@ class DRM_LOCAL DrmManager::Impl { Debug( "Frequency detection sequence is bypassed." ); return; } - - std::lock_guard lock( mDrmControllerMutex ); int ret = readDrmAddress( REG_FREQ_DETECTION_VERSION, reg ); if ( ret != 0 ) { Unreachable( "Failed to read DRM frequency detection version register, errcode = {}. ", ret ); //LCOV_EXCL_LINE @@ -1340,17 +1625,17 @@ class DRM_LOCAL DrmManager::Impl { TClock::duration wait_duration = std::chrono::milliseconds( mFrequencyDetectionPeriod ); int max_attempts = 3; - std::lock_guard lock( mDrmControllerMutex ); - Debug( "Detecting DRM frequency in {} ms", mFrequencyDetectionPeriod ); + std::lock_guard lock( mDrmControllerMutex ); + while ( max_attempts > 0 ) { counterStart = getTimerCounterValue(); // Wait until counter starts decrementing while (1) { - if (getTimerCounterValue() < counterStart) { + if ( getTimerCounterValue() < counterStart ) { counterStart = getTimerCounterValue(); timeStart = TClock::now(); break; @@ -1393,7 +1678,7 @@ class DRM_LOCAL DrmManager::Impl { mFrequencyCurr = measuredFrequency; if ( precisionError >= mFrequencyDetectionThreshold ) { Throw( DRM_BadFrequency, - "Estimated DRM frequency ({} MHz) differs from the value ({} MHz) defined in the configuration file '{}' by more than {}%: From now on the estimated frequency is used.", + "Estimated DRM frequency ({} MHz) differs from the value ({} MHz) defined in the configuration file '{}' by more than {}%: From now on the estimated frequency will be used.", mFrequencyCurr, mFrequencyInit, mConfFilePath, mFrequencyDetectionThreshold, mFrequencyCurr); } Debug( "Estimated DRM frequency = {} MHz, config frequency = {} MHz: gap = {}%", @@ -1402,25 +1687,25 @@ class DRM_LOCAL DrmManager::Impl { template< class Clock, class Duration > void sleepOrExit( const std::chrono::time_point &timeout_time ) { - std::unique_lock lock( mThreadKeepAliveMtx ); - bool isExitRequested = mThreadKeepAliveCondVar.wait_until( lock, timeout_time, - [ this ]{ return mThreadStopRequest; } ); + std::unique_lock lock( mThreadExitMtx ); + bool isExitRequested = mThreadExitCondVar.wait_until( lock, timeout_time, + [ this ]{ return mThreadExit; } ); if ( isExitRequested ) Throw( DRM_Exit, "Exit requested" ); } template< class Rep, class Period > void sleepOrExit( const std::chrono::duration &rel_time ) { - std::unique_lock lock( mThreadKeepAliveMtx ); - bool isExitRequested = mThreadKeepAliveCondVar.wait_for( lock, rel_time, - [ this ]{ return mThreadStopRequest; } ); + std::unique_lock lock( mThreadExitMtx ); + bool isExitRequested = mThreadExitCondVar.wait_for( lock, rel_time, + [ this ]{ return mThreadExit; } ); if ( isExitRequested ) Throw( DRM_Exit, "Exit requested" ); } bool isStopRequested() { - std::lock_guard lock( mThreadKeepAliveMtx ); - return mThreadStopRequest; + std::lock_guard lock( mThreadExitMtx ); + return mThreadExit; } uint32_t getCurrentLicenseTimeLeft() { @@ -1431,13 +1716,15 @@ class DRM_LOCAL DrmManager::Impl { void startLicenseContinuityThread() { if ( mThreadKeepAlive.valid() ) { - Warning( "Thread already started" ); + Warning( "Licensing thread already started" ); return; } mThreadKeepAlive = std::async( std::launch::async, [ this ]() { + Debug( "Starting background thread which maintains licensing" ); try { - Debug( "Started background thread which maintains licensing" ); + // Collect host and card information when possible + getHostAndCardInfo(); /// Detecting DRM controller frequency if needed if ( !mIsFreqDetectionMethod1 ) @@ -1447,14 +1734,13 @@ class DRM_LOCAL DrmManager::Impl { /// Starting license request loop while( 1 ) { + if ( isStopRequested() ) + break; { Debug( "Waiting metering access mutex from licensing thread" ); std::lock_guard lockMetering( mMeteringAccessMutex ); Debug( "Acquired metering access mutex from licensing thread" ); - if ( isStopRequested() ) - break; - // Check DRM licensing queue if ( !isReadyForNewLicense() ) { go_sleeping = true; @@ -1462,14 +1748,10 @@ class DRM_LOCAL DrmManager::Impl { } else { go_sleeping = false; Debug( "Requesting new license #{} now", mLicenseCounter ); - Json::Value request_json = getMeteringWait(); - Json::Value license_json; - - /// Retry Web Service request loop - TClock::time_point polling_deadline = TClock::now() + std::chrono::seconds( mLicenseDuration ); + Json::Value request_json = getMeteringRunning(); /// Attempt to get the next license - license_json = getLicense( request_json, polling_deadline, mWSRetryPeriodShort, mWSRetryPeriodLong ); + Json::Value license_json = getLicense( request_json, mExpirationTime, mWSRetryPeriodShort, mWSRetryPeriodLong ); /// New license has been received: now send it to the DRM Controller setLicense( license_json ); @@ -1480,8 +1762,10 @@ class DRM_LOCAL DrmManager::Impl { // DRM licensing queue is full, wait until current license expires uint32_t licenseTimeLeft = getCurrentLicenseTimeLeft(); TClock::duration wait_duration = std::chrono::seconds( licenseTimeLeft + 1 ); - Debug( "Sleeping for {} seconds before checking DRM Controller readiness for a new license", licenseTimeLeft ); + Debug( "License thread sleeping {} seconds before checking DRM Controller readiness", licenseTimeLeft ); sleepOrExit( wait_duration ); + // resync expiration time + mExpirationTime = TClock::now() + std::chrono::seconds( mLicenseDuration ); } } Debug( "Released metering access mutex from licensing thread" ); @@ -1491,7 +1775,7 @@ class DRM_LOCAL DrmManager::Impl { Error( e.what() ); f_asynch_error( std::string( e.what() ) ); } - } catch( const std::exception& e ) { + } catch( const std::exception &e ) { std::string errmsg = fmt::format( "[errCode={}] Unexpected error: {}", DRM_ExternFail, e.what() ); Error( errmsg ); f_asynch_error( errmsg ); @@ -1500,23 +1784,102 @@ class DRM_LOCAL DrmManager::Impl { }); } + void startHealthContinuityThread() { + + if ( mThreadHealth.valid() ) { + Warning( "Asynchronous metering thread already started" ); + return; + } + + mThreadHealth = std::async( std::launch::async, [ this ]() { + Debug( "Starting background thread which checks health" ); + try { + uint32_t retry_sleep = mWSRetryPeriodShort; + uint32_t retry_timeout = mWSRequestTimeout; + mHealthCounter = 0; + + /// Starting async metering post loop + while( 1 ) { + + /// Sleep until it's time to collect the next metering data + TClock::time_point wakeup_time = TClock::now() + std::chrono::seconds( mHealthPeriod ); + Debug( "Health thread sleeping {} seconds before gathering new metering", mHealthPeriod ); + sleepOrExit( wakeup_time ); + + /// Collect the next metering data and send them to the Health Web Service + Debug( "Health thread collecting new metering data" ); + Json::Value response_json = performHealth( retry_timeout, retry_sleep ); + + if ( response_json != Json::nullValue ) { + /// Extract asynchronous metering parameters from response + Json::Value metering_node = JVgetOptional( response_json, "metering", Json::objectValue, Json::nullValue ); + uint32_t healthPeriod = JVgetOptional( metering_node, "healthPeriod", Json::uintValue, mHealthPeriod ).asUInt(); + uint32_t healthRetryTimeout = JVgetOptional( metering_node, "healthRetry", Json::uintValue, mHealthRetryTimeout ).asUInt(); + uint32_t healthRetrySleep = JVgetOptional( metering_node, "healthRetrySleep", Json::uintValue, mHealthRetrySleep ).asUInt(); + + /// Reajust async metering thread if needed + if ( ( healthPeriod != mHealthPeriod ) || ( healthRetryTimeout != mHealthRetryTimeout) + || ( healthRetrySleep != mHealthRetrySleep) ) { + mHealthPeriod = healthPeriod; + mHealthRetryTimeout = healthRetryTimeout; + mHealthRetrySleep = healthRetrySleep; + Debug( "Updating Health parameters with new values: healthPeriod={}s, healthRetry={}s, healthRetrySleep={}s", + mHealthPeriod, mHealthRetryTimeout, mHealthRetrySleep ); + if ( mHealthPeriod == 0 ) { + Warning( "Health thread is disabled" ); + break; + } + if ( mHealthRetryTimeout == 0 ) { + retry_timeout = mWSRequestTimeout; + retry_sleep = 0; + Debug( "Health retry is disabled" ); + } else { + retry_timeout = mHealthRetryTimeout; + retry_sleep = mHealthRetrySleep; + Debug( "Health retry is enabled" ); + } + } else { + Debug( "Keep same Health parameters: healthPeriod={}s, healthRetry={}s, healthRetrySleep={}s", + mHealthPeriod, mHealthRetryTimeout, mHealthRetrySleep ); + } + } else { + Debug( "Keep same Health parameters: healthPeriod={}s, healthRetry={}s, healthRetrySleep={}s", + mHealthPeriod, mHealthRetryTimeout, mHealthRetrySleep ); + } + } + } catch( const Exception& e ) { + if ( e.getErrCode() != DRM_Exit ) { + Error( e.what() ); + f_asynch_error( std::string( e.what() ) ); + } + } catch( const std::exception &e ) { + Error( e.what() ); + f_asynch_error( std::string( e.what() ) ); + } + Debug( "Exiting background thread which checks health" ); + }); + } + void stopThread() { - if ( !mThreadKeepAlive.valid() ) { - Debug( "Background thread was not running" ); + if ( ( mThreadKeepAlive.valid() == 0 ) && ( mThreadHealth.valid() == 0 ) ) { + Debug( "Background threads are not running" ); return; } { - std::lock_guard lock( mThreadKeepAliveMtx ); - Debug( "Stop flag of thread is set" ); - mThreadStopRequest = true; + std::lock_guard lock( mThreadExitMtx ); + Debug( "Set Stop flag for threads" ); + mThreadExit = true; } - mThreadKeepAliveCondVar.notify_all(); - mThreadKeepAlive.get(); - Debug( "Background thread stopped" ); + mThreadExitCondVar.notify_all(); + if ( mThreadKeepAlive.valid() ) + mThreadKeepAlive.get(); // Wait until the License thread ends + if ( mThreadHealth.valid() ) + mThreadHealth.get(); // Wait until the Health thread ends + Debug( "Background threads stopped" ); { - std::lock_guard lock( mThreadKeepAliveMtx ); - Debug( "Stop flag of thread is reset" ); - mThreadStopRequest = false; + std::lock_guard lock( mThreadExitMtx ); + Debug( "Clear Stop flag for threads" ); + mThreadExit = false; } } @@ -1529,18 +1892,26 @@ class DRM_LOCAL DrmManager::Impl { if ( !isReadyForNewLicense() ) Unreachable( "To start a new session the DRM Controller shall be ready to accept a new license" ); //LCOV_EXCL_LINE + mLicenseCounter = 0; + // Build start request message for new license Json::Value request_json = getMeteringStart(); // Send request and receive new license - Json::Value license_json = getLicense( request_json, mWSRequestTimeout, mWSRetryPeriodShort ); + Json::Value license_json = getLicense( request_json, mWSApiRetryDuration, mWSRetryPeriodShort ); setLicense( license_json ); + // Extract asynchronous health parameters from response + Json::Value metering_node = JVgetOptional( license_json, "metering", Json::objectValue, Json::nullValue ); + mHealthPeriod = JVgetOptional( metering_node, "healthPeriod", Json::uintValue, mHealthPeriod ).asUInt(); + mHealthRetryTimeout = JVgetOptional( metering_node, "healthRetry", Json::uintValue, mHealthRetryTimeout ).asUInt(); + mHealthRetrySleep = JVgetOptional( metering_node, "healthRetrySleep", Json::uintValue, mHealthRetrySleep ).asUInt(); + // Check if an error occurred checkDRMCtlrRet( getDrmController().waitNotTimerInitLoaded( 5 ) ); } Debug( "Released metering access mutex from startSession" ); - Info( "New DRM session started." ); + Info( "New DRM session {} started.", mSessionID ); } void resumeSession() { @@ -1551,10 +1922,10 @@ class DRM_LOCAL DrmManager::Impl { if ( isReadyForNewLicense() ) { // Create JSON license request - Json::Value request_json = getMeteringWait(); + Json::Value request_json = getMeteringRunning(); // Send license request to web service - Json::Value license_json = getLicense( request_json, mWSRequestTimeout, mWSRetryPeriodShort ); + Json::Value license_json = getLicense( request_json, mWSApiRetryDuration, mWSRetryPeriodShort ); // Provision license on DRM controller setLicense( license_json ); @@ -1576,23 +1947,30 @@ class DRM_LOCAL DrmManager::Impl { std::lock_guard lockMetering( mMeteringAccessMutex ); Debug( "Acquired metering access mutex from stopSession" ); request_json = getMeteringStop(); + + // Send last metering information + Json::Value license_json = getLicense( request_json, mWSApiRetryDuration, mWSRetryPeriodShort ); + checkSessionIDFromWS( license_json ); + Debug( "Session ID {} stopped and last metering data uploaded", mSessionID ); } Debug( "Released metering access mutex from stopSession" ); - - // Send last metering information - Json::Value license_json = getLicense( request_json, mWSRequestTimeout, mWSRetryPeriodShort ); - Debug( "Session ID {} stopped and last metering data uploaded", mSessionID ); - - /// Clear Session IS - Debug( "Clearing session ID: {}", mSessionID ); + // Clear Session ID + std::string sessionID = mSessionID; + Debug2( "Clearing session ID: {}", mSessionID ); mSessionID = std::string(""); - Info( "DRM session stopped." ); + // Clear security flag + Debug( "Clearing stop security flag" ); + mSecurityStop = false; + + Info( "DRM session {} stopped.", sessionID ); } void pauseSession() { stopThread(); mSecurityStop = false; + if (mHealthPeriod) + performHealth(mWSApiRetryDuration, 0); Info( "DRM session paused." ); } @@ -1679,6 +2057,7 @@ class DRM_LOCAL DrmManager::Impl { Debug( "Calling 'activate' with 'resume_session_request'={}", resume_session_request ); bool isRunning = isSessionRunning(); + mExpirationTime = TClock::now(); if ( isNodeLockedMode() ) { // Install the node-locked license @@ -1689,7 +2068,6 @@ class DRM_LOCAL DrmManager::Impl { Throw( DRM_BadUsage, "DRM Controller is locked in Node-Locked licensing mode: " "To use other modes you must reprogram the FPGA device." ); } - mSecurityStop = true; if ( isRunning && resume_session_request ) { resumeSession(); } else { @@ -1704,7 +2082,11 @@ class DRM_LOCAL DrmManager::Impl { } startSession(); } + mThreadExit = false; startLicenseContinuityThread(); + if ( mHealthPeriod ) + startHealthContinuityThread(); + mSecurityStop = true; CATCH_AND_THROW } @@ -1733,7 +2115,7 @@ class DRM_LOCAL DrmManager::Impl { Debug2( "Getting parameter '{}'", key_str ); switch( key_id ) { case ParameterKey::log_verbosity: { - int logVerbosity = static_cast( sLogConsoleVerbosity ); + uint32_t logVerbosity = static_cast( sLogConsoleVerbosity ); json_value[key_str] = logVerbosity; Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, logVerbosity ); @@ -1746,7 +2128,7 @@ class DRM_LOCAL DrmManager::Impl { break; } case ParameterKey::log_file_verbosity: { - int logVerbosity = static_cast( sLogFileVerbosity ); + uint32_t logVerbosity = static_cast( sLogFileVerbosity ); json_value[key_str] = logVerbosity; Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, logVerbosity ); @@ -1765,20 +2147,20 @@ class DRM_LOCAL DrmManager::Impl { break; } case ParameterKey::log_file_type: { - json_value[key_str] = (int)sLogFileType; + json_value[key_str] = (uint32_t)sLogFileType; Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, - (int)sLogFileType ); + sLogFileType ); break; } case ParameterKey::log_file_rotating_num: { - json_value[key_str] = (int)sLogFileRotatingNum; + json_value[key_str] = (uint32_t)sLogFileRotatingNum; Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, sLogFileRotatingNum ); break; } case ParameterKey::log_file_rotating_size: { - json_value[key_str] = (int)sLogFileRotatingSize; - Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, + json_value[key_str] = (uint32_t)sLogFileRotatingSize; + Debug( "Get value of parameter '{}' (ID={}): {} KB", key_str, key_id, sLogFileRotatingSize ); break; } @@ -1829,15 +2211,25 @@ class DRM_LOCAL DrmManager::Impl { } case ParameterKey::metered_data: { #if ((JSONCPP_VERSION_MAJOR ) >= 1 and ((JSONCPP_VERSION_MINOR) > 7 or ((JSONCPP_VERSION_MINOR) == 7 and JSONCPP_VERSION_PATCH >= 5))) - uint64_t metered_data = 0; + uint64_t meteringData = 0; #else // No "int64_t" support with JsonCpp < 1.7.5 - unsigned long long metered_data = 0; + unsigned long long meteringData = 0; #endif - metered_data = getMeteringData(); - json_value[key_str] = metered_data; + Json::Value json_request = getMeteringHealth(); + std::string meteringFileStr = json_request["meteringFile"].asString(); + if ( meteringFileStr.size() ) { + std::string meteringDataStr = meteringFileStr.substr( 80, 16 ); + errno = 0; + meteringData = strtoull( meteringDataStr.c_str(), nullptr, 16 ); + if ( errno ) { + Throw( DRM_CtlrError, "Could not convert string '{}' to unsigned long long.", + meteringDataStr ); + } + } + json_value[key_str] = meteringData; Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, - metered_data ); + meteringData ); break; } case ParameterKey::nodelocked_request_file: { @@ -1900,7 +2292,7 @@ class DRM_LOCAL DrmManager::Impl { break; } case ParameterKey::frequency_detection_method: { - int method_index = 2; + int32_t method_index = 2; if ( mIsFreqDetectionMethod1 ) method_index = 1; json_value[key_str] = method_index; @@ -1927,10 +2319,10 @@ class DRM_LOCAL DrmManager::Impl { break; } case ParameterKey::token_string: { - std::string token_string = getDrmWSClient().getTokenString(); - json_value[key_str] = token_string; + std::string token_str = getDrmWSClient().getTokenString(); + json_value[key_str] = token_str; Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, - token_string ); + token_str ); break; } case ParameterKey::token_validity: { @@ -1975,14 +2367,20 @@ class DRM_LOCAL DrmManager::Impl { mWSRetryPeriodShort ); break; } + case ParameterKey::ws_api_retry_duration: { + json_value[key_str] = mWSApiRetryDuration ; + Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, + mWSApiRetryDuration ); + break; + } case ParameterKey::ws_request_timeout: { - json_value[key_str] = mWSRequestTimeout ; + json_value[key_str] = mWSRequestTimeout; Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, - mWSRequestTimeout ); + mWSRequestTimeout ); break; } case ParameterKey::log_message_level: { - int msgLevel = static_cast( mDebugMessageLevel ); + uint32_t msgLevel = static_cast( mDebugMessageLevel ); json_value[key_str] = msgLevel; Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, msgLevel ); @@ -2009,8 +2407,57 @@ class DRM_LOCAL DrmManager::Impl { list.toStyledString() ); break; } + case ParameterKey::hdk_compatibility: { + std::string hdk_limit = fmt::format( "{}.{}", HDK_COMPATIBILITY_LIMIT_MAJOR, HDK_COMPATIBILITY_LIMIT_MINOR ); + json_value[key_str] = hdk_limit; + Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, + hdk_limit ); + break; + } + case ParameterKey::health_period: { + json_value[key_str] = mHealthPeriod; + Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, mHealthPeriod ); + break; + } + case ParameterKey::health_retry: { + json_value[key_str] = mHealthRetryTimeout; + Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, mHealthRetryTimeout ); + break; + } + case ParameterKey::health_retry_sleep: { + json_value[key_str] = mHealthRetrySleep; + Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, mHealthRetrySleep ); + break; + } + case ParameterKey::host_data_verbosity: { + uint32_t dataLevel = static_cast( mHostDataVerbosity ); + json_value[key_str] = dataLevel; + Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, + dataLevel ); + break; + } + case ParameterKey::host_data: { + json_value[key_str] = mHostConfigData; + Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, + mHostConfigData.toStyledString() ); + break; + } + case ParameterKey::log_file_append: { + json_value[key_str] = sLogFileAppend; + Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, + sLogFileAppend ); + break; + } + case ParameterKey::ws_verbosity: { + uint32_t wsVerbosity = getDrmWSClient().getVerbosity(); + json_value[key_str] = wsVerbosity; + Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, + wsVerbosity ); + break; + } + case ParameterKey::ParameterKeyCount: { - uint32_t count = static_cast( ParameterKeyCount ); + uint32_t count = static_cast( ParameterKeyCount ); json_value[key_str] = count; Debug( "Get value of parameter '{}' (ID={}): {}", key_str, key_id, count ); @@ -2045,7 +2492,7 @@ class DRM_LOCAL DrmManager::Impl { const ParameterKey key_id = findParameterKey( key_str ); switch( key_id ) { case ParameterKey::log_verbosity: { - int verbosityInt = (*it).asInt(); + int32_t verbosityInt = (*it).asInt(); sLogConsoleVerbosity = static_cast( verbosityInt ); sLogger->sinks()[0]->set_level( sLogConsoleVerbosity ); if ( sLogConsoleVerbosity < sLogger->level() ) @@ -2063,7 +2510,7 @@ class DRM_LOCAL DrmManager::Impl { break; } case ParameterKey::log_file_verbosity: { - int verbosityInt = (*it).asInt(); + int32_t verbosityInt = (*it).asInt(); sLogFileVerbosity = static_cast( verbosityInt ); sLogger->sinks()[1]->set_level( sLogFileVerbosity ); if ( sLogFileVerbosity < sLogger->level() ) @@ -2133,12 +2580,10 @@ class DRM_LOCAL DrmManager::Impl { mWSRetryPeriodShort ); break; } - case ParameterKey::ws_request_timeout: { - mWSRequestTimeout = (*it).asUInt(); + case ParameterKey::ws_api_retry_duration: { + mWSApiRetryDuration = (*it).asUInt(); Debug( "Set parameter '{}' (ID={}) to value: {}", key_str, key_id, - mWSRequestTimeout ); - if ( mWSRequestTimeout == 0 ) - Throw( DRM_BadArg, "ws_request_timeout must not be 0"); + mWSApiRetryDuration ); break; } case ParameterKey::trigger_async_callback: { @@ -2149,22 +2594,12 @@ class DRM_LOCAL DrmManager::Impl { custom_msg ); break; } - case ParameterKey::bad_product_id: { - Debug( "Set parameter '{}' (ID={}) to random value", key_str, key_id ); - mHeaderJsonRequest["product"]["name"] = "BAD_NAME_JUST_FOR_TEST"; - break; - } - case ParameterKey::bad_oauth2_token: { - Debug( "Set parameter '{}' (ID={}) to random value", key_str, key_id ); - getDrmWSClient().setOAuth2token( "BAD_TOKEN" ); - break; - } case ParameterKey::log_message_level: { - int message_level = (*it).asInt(); + int32_t message_level = (*it).asInt(); if ( ( message_level < spdlog::level::trace) || ( message_level > spdlog::level::off) ) Throw( DRM_BadArg, "log_message_level ({}) is out of range [{:d}:{:d}]", - message_level, (int)spdlog::level::trace, (int)spdlog::level::off ); + message_level, (int32_t)spdlog::level::trace, (int32_t)spdlog::level::off ); mDebugMessageLevel = static_cast( message_level ); Debug( "Set parameter '{}' (ID={}) to value {}", key_str, key_id, message_level ); @@ -2183,11 +2618,9 @@ class DRM_LOCAL DrmManager::Impl { } void set( const std::string& json_string ) { - TRY - Debug2( "Calling 'set' with in/out string: {}", json_string ); - Json::Value root = parseJsonString( json_string ); - set( root ); - CATCH_AND_THROW + Debug2( "Calling 'set' with in/out string: {}", json_string ); + Json::Value root = parseJsonString( json_string ); + set( root ); } template void set( const ParameterKey /*key_id*/, const T& /*value*/ ) {} diff --git a/source/utils.cpp b/source/utils.cpp index 8feaf256..c855521a 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -30,12 +30,7 @@ namespace DRM { std::string getDirName( const std::string& full_path ) { - char sep = '/'; -#ifdef _WIN32 - sep = '\\'; -#endif - - size_t i = full_path.rfind( sep, full_path.length() ); + size_t i = full_path.rfind( PATH_SEP, full_path.length() ); if ( i != std::string::npos ) { return full_path.substr( 0, i ); } @@ -77,11 +72,6 @@ bool makeDirs( const std::string& dir_path, mode_t mode ) { std::string dir; size_t pos = 0; int ret; -#if defined(_WIN32) - char sep = '\\'; -#else - char sep = '/'; -#endif if ( dir_path.size() == 0 ) { return true; @@ -92,12 +82,12 @@ bool makeDirs( const std::string& dir_path, mode_t mode ) { return true; } - if ( path[ path.size() - 1 ] != sep ) { + if ( path[ path.size() - 1 ] != PATH_SEP ) { // Force trailing '/' so we can handle everything in loop - path += sep; + path += PATH_SEP; } - while( ( pos = path.find_first_of( sep, pos ) ) != std::string::npos ) { + while( ( pos = path.find_first_of( PATH_SEP, pos ) ) != std::string::npos ) { dir = path.substr( 0, pos++ ); if ( ( dir.size() == 0 ) || ( isDir( dir ) ) ) continue; // if leading / first time is 0 length @@ -169,12 +159,12 @@ Json::Value parseJsonString( const std::string &json_string ) { if ( !reader->parse( json_string.c_str(), json_string.c_str() + json_string.size(), &json_node, &parseErr) ) - Throw( DRM_BadFormat, "Cannot parse JSON string '{}' because {}", json_string, parseErr ); + Throw( DRM_BadFormat, "Cannot parse JSON string because {}", parseErr ); if ( json_node.empty() || json_node.isNull() ) Throw( DRM_BadArg, "JSON string is empty" ); - Debug( "Extracted JSON Object: {}", json_node.toStyledString() ); + Debug2( "Extracted JSON Object: {}", json_node.toStyledString() ); return json_node; } @@ -184,6 +174,11 @@ Json::Value parseJsonFile( const std::string& file_path ) { Json::Value json_node; std::string file_content; + // Check path is a file + if ( !isFile(file_path) ) { + Throw( DRM_BadArg, "Path is not a valid file: {}", file_path ); + } + // Open file std::ifstream fh( file_path ); if ( !fh.good() ) @@ -246,13 +241,28 @@ const Json::Value& JVgetOptional( const Json::Value& jval, val = val.erase( val.find_last_not_of("\t\n\v\f\r") + 1 ); if ( exists ) - Debug( "Found parameter '{}' of type {} with value {}", key, typeToString( jvalmember.type() ), val ); + Debug( "Found parameter '{}' of type {}: return its value {}", key, typeToString( jvalmember.type() ), val ); else - Debug( "Set parameter '{}' of type {} to default value {}", key, typeToString( jvalmember.type() ), val ); + Debug( "Could not find parameter '{}' of type {}: return default value {}", key, typeToString( jvalmember.type() ), val ); return jvalmember; } +std::string exec_cmd( const std::string cmd) { + std::array buffer; + std::string result; + Debug( "Running command: {}", cmd ); + std::unique_ptr pipe(popen(cmd.c_str(), "r"), pclose); + if (!pipe) { + throw std::runtime_error("popen() failed!"); + } + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { + result += buffer.data(); + } + return result; +} + + } } diff --git a/source/ws_client.cpp b/source/ws_client.cpp index ea36dc21..01b53dc6 100644 --- a/source/ws_client.cpp +++ b/source/ws_client.cpp @@ -30,75 +30,128 @@ namespace DRM { CurlEasyPost::CurlEasyPost() { + mConnectionTimeoutMS = cConnectionTimeoutMS; curl = curl_easy_init(); if ( !curl ) Throw( DRM_ExternFail, "Curl : cannot init curl_easy" ); + curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, &CurlEasyPost::write_callback ); + curl_easy_setopt( curl, CURLOPT_ERRORBUFFER, mErrBuff.data() ); + curl_easy_setopt( curl, CURLOPT_FOLLOWLOCATION, 1L ); + curl_easy_setopt( curl, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt( curl, CURLOPT_TCP_KEEPALIVE, 1L); } CurlEasyPost::~CurlEasyPost() { data.clear(); curl_easy_cleanup( curl ); - curl_slist_free_all( headers ); - curl_slist_free_all( host_resolve_list ); - headers = NULL; - host_resolve_list = NULL; + curl_slist_free_all( mHeaders_p ); + curl_slist_free_all( mHostResolveList ); + mHeaders_p = NULL; + mHostResolveList = NULL; +} + +void CurlEasyPost::setVerbosity( const uint32_t verbosity ) { + curl_easy_setopt(curl, CURLOPT_VERBOSE, verbosity); } void CurlEasyPost::setHostResolves( const Json::Value& host_json ) { if ( host_json != Json::nullValue ) { - if ( host_resolve_list != NULL ) { - curl_slist_free_all( host_resolve_list ); - host_resolve_list = NULL; + if ( mHostResolveList != NULL ) { + curl_slist_free_all( mHostResolveList ); + mHostResolveList = NULL; } for( Json::ValueConstIterator it = host_json.begin(); it != host_json.end(); it++ ) { std::string key = it.key().asString(); std::string val = (*it).asString(); std::string host_str = fmt::format( "{}:{}", key, val ); - host_resolve_list = curl_slist_append( host_resolve_list, host_str.c_str() ); + mHostResolveList = curl_slist_append( mHostResolveList, host_str.c_str() ); } - if ( curl_easy_setopt(curl, CURLOPT_RESOLVE, host_resolve_list) == CURLE_UNKNOWN_OPTION ) + if ( curl_easy_setopt(curl, CURLOPT_RESOLVE, mHostResolveList) == CURLE_UNKNOWN_OPTION ) Warning( "Could not set the CURL Host resolve option: {}", host_json.toStyledString() ); else Debug( "Set the following CURL Host resolve option: {}", host_json.toStyledString() ); } } -long CurlEasyPost::perform( std::string* resp, std::chrono::steady_clock::time_point deadline ) { +uint32_t CurlEasyPost::perform( std::string* response, int32_t timeout_ms ) { CURLcode res; - long resp_code; + uint32_t resp_code; - if ( headers ) { - curl_easy_setopt( curl, CURLOPT_HTTPHEADER, headers ); - } - curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, &CurlEasyPost::write_callback ); - curl_easy_setopt( curl, CURLOPT_WRITEDATA, (void*)resp ); - curl_easy_setopt( curl, CURLOPT_ERRORBUFFER, errbuff.data() ); - curl_easy_setopt( curl, CURLOPT_FOLLOWLOCATION, 1L ); - curl_easy_setopt( curl, CURLOPT_CONNECTTIMEOUT_MS, cConnectionTimeout ); + if ( timeout_ms <= 0 ) + Throw( DRM_WSTimedOut, "Did not perform HTTP request to Accelize webservice because deadline is reached." ); - { // Compute timeout - std::chrono::milliseconds timeout = std::chrono::duration_cast( deadline - std::chrono::steady_clock::now() ); - if ( timeout <= std::chrono::milliseconds( 0 ) ) - Throw( DRM_WSMayRetry, "Did not perform HTTP request to Accelize webservice because deadline is already reached." ); - curl_easy_setopt( curl, CURLOPT_TIMEOUT_MS, timeout.count() ); + // Configure and execute CURL command + if ( mHeaders_p ) { + curl_easy_setopt( curl, CURLOPT_HTTPHEADER, mHeaders_p ); } + curl_easy_setopt( curl, CURLOPT_WRITEDATA, response ); + curl_easy_setopt( curl, CURLOPT_CONNECTTIMEOUT_MS, mConnectionTimeoutMS ); + curl_easy_setopt( curl, CURLOPT_TIMEOUT_MS, timeout_ms ); res = curl_easy_perform( curl ); + + // Analyze libcurl response if ( res != CURLE_OK ) { + // A libcurl error occurred if ( res == CURLE_COULDNT_RESOLVE_PROXY || res == CURLE_COULDNT_RESOLVE_HOST || res == CURLE_COULDNT_CONNECT || res == CURLE_OPERATION_TIMEDOUT ) { - Throw( DRM_WSMayRetry, "Failed performing HTTP request to Accelize webservice ({}) : {}", - curl_easy_strerror( res ), errbuff.data() ); + Throw( DRM_WSMayRetry, "libcurl failed to perform HTTP request to Accelize webservice ({}) : {}", + curl_easy_strerror( res ), mErrBuff.data() ); } else { - Throw( DRM_ExternFail, "Failed performing HTTP request to Accelize webservice ({}) : {}", - curl_easy_strerror( res ), errbuff.data() ); + Throw( DRM_ExternFail, "libcurl failed to perform HTTP request to Accelize webservice ({}) : {}", + curl_easy_strerror( res ), mErrBuff.data() ); } } curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &resp_code ); + Debug( "Received code {} from {} in {} ms", resp_code, mUrl, getTotalTime() * 1000 ); return resp_code; } +uint32_t CurlEasyPost::perform( std::string* response, std::chrono::steady_clock::time_point& deadline ) { + std::chrono::milliseconds timeout_chrono = std::chrono::duration_cast( deadline - std::chrono::steady_clock::now() ); + int32_t timeout_ms = timeout_chrono.count(); + if ( timeout_ms >= (int32_t)mConnectionTimeoutMS ) + timeout_ms = mConnectionTimeoutMS; + return perform( response, timeout_ms ); +} + +std::string CurlEasyPost::perform_put( std::string url, const uint32_t& timeout_ms ) { + std::string response; + uint32_t resp_code; + + if ( timeout_ms <= 0 ) + Throw( DRM_WSTimedOut, "Did not perform HTTP request to Accelize webservice because deadline is reached." ); + + // Configure and execute CURL command + curl_easy_setopt( curl, CURLOPT_URL, url.c_str() ); + if ( mHeaders_p ) { + curl_easy_setopt( curl, CURLOPT_HTTPHEADER, mHeaders_p ); + } + curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "PUT"); + curl_easy_setopt( curl, CURLOPT_WRITEDATA, &response ); + curl_easy_setopt( curl, CURLOPT_CONNECTTIMEOUT_MS, mConnectionTimeoutMS ); + curl_easy_setopt( curl, CURLOPT_TIMEOUT_MS, timeout_ms ); + CURLcode res = curl_easy_perform( curl ); + + // Analyze HTTP answer + if ( res != CURLE_OK ) { + if ( res == CURLE_COULDNT_RESOLVE_PROXY + || res == CURLE_COULDNT_RESOLVE_HOST + || res == CURLE_COULDNT_CONNECT + || res == CURLE_OPERATION_TIMEDOUT ) { + Throw( DRM_WSMayRetry, "libcurl failed to perform HTTP request to Accelize webservice ({}) : {}", + curl_easy_strerror( res ), mErrBuff.data() ); + } else { + Throw( DRM_ExternFail, "libcurl failed to perform HTTP request to Accelize webservice ({}) : {}", + curl_easy_strerror( res ), mErrBuff.data() ); + } + } + curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &resp_code ); + Debug( "Received code {} from {} in {} ms", resp_code, url, getTotalTime() * 1000 ); + return response; +} + double CurlEasyPost::getTotalTime() { double ret; if ( !curl_easy_getinfo( curl, CURLINFO_TOTAL_TIME, &ret ) ) @@ -117,6 +170,7 @@ DrmWSClient::DrmWSClient( const std::string &conf_file_path, const std::string & mTokenExpirationMargin = cTokenExpirationMargin; mTokenExpirationTime = TClock::now(); + // Set properties based on file try { Json::Value conf_json = parseJsonFile( conf_file_path ); Json::Value webservice_json = JVgetRequired( conf_json, "licensing", Json::objectValue ); @@ -125,14 +179,25 @@ DrmWSClient::DrmWSClient( const std::string &conf_file_path, const std::string & mHostResolvesJson = JVgetOptional( webservice_json, "host_resolves", Json::objectValue ); url = JVgetRequired( webservice_json, "url", Json::stringValue ).asString(); - Debug( "Licensing URL: {}", url ); - mMeteringUrl = url + std::string("/auth/metering/genlicense/"); + + Json::Value settings = JVgetOptional( conf_json, "settings", Json::objectValue ); + mRequestTimeout = JVgetOptional( settings, "ws_request_timeout", + Json::uintValue, cRequestTimeout).asUInt() * 1000; + if ( mRequestTimeout == 0 ) + Throw( DRM_BadArg, "ws_request_timeout must not be 0"); + mVerbosity = JVgetOptional( settings, "ws_verbosity", + Json::uintValue, 0).asUInt(); } catch( Exception &e ) { Throw( e.getErrCode(), "Error with service configuration file '{}': {}", conf_file_path, e.what() ); } + // Temporarily change file log level to be sure not to capture the Client and Secret IDs + auto logFileHandler = sLogger->sinks()[1]; + spdlog::level::level_enum logFileLevel = logFileHandler->level(); + if ( logFileLevel <= spdlog::level::debug ) + logFileHandler->set_level( spdlog::level::info ); try { Json::Value cred_json = parseJsonFile( cred_file_path ); Json::Value client_id_json = JVgetRequired( cred_json, "client_id", Json::stringValue ); @@ -142,16 +207,42 @@ DrmWSClient::DrmWSClient( const std::string &conf_file_path, const std::string & } catch( Exception &e ) { Throw( e.getErrCode(), "Error with credential file '{}': {}", cred_file_path, e.what() ); } - + // Restore original file log level + if ( logFileLevel <= spdlog::level::debug ) + logFileHandler->set_level( logFileLevel ); + + // Overwrite properties with Environment Variables if defined + const char* url_var = std::getenv( "ONEPORTAL_URL" ); + if ( url_var != NULL ) + url = std::string( url_var ); + const char* client_id_var = std::getenv( "ONEPORTAL_CLIENT_ID" ); + if ( client_id_var != NULL ) + mClientId = std::string( client_id_var ); + const char* secret_id_var = std::getenv( "ONEPORTAL_CLIENT_SECRET" ); + if ( secret_id_var != NULL ) + mClientSecret = std::string( secret_id_var ); + + // Init Curl lib CurlSingleton::Init(); // Set header of OAuth2 request + std::string oauth_url = url + std::string("/o/token/"); mOAUth2Request.setHostResolves( mHostResolvesJson ); - mOAUth2Request.setURL( url + std::string("/o/token/") ); + mOAUth2Request.setURL( oauth_url ); + mOAUth2Request.setVerbosity( mVerbosity ); std::stringstream ss; ss << "client_id=" << mClientId << "&client_secret=" << mClientSecret; ss << "&grant_type=client_credentials"; mOAUth2Request.setPostFields( ss.str() ); + mOAUth2Request.setConnectionTimeoutMS( mRequestTimeout ); + + // Set URL of license and metering requests + mLicenseUrl = url + std::string("/auth/metering/genlicense/"); + mHealthUrl = url + std::string("/auth/metering/health/"); + + Debug( "OAuth URL: {}", oauth_url ); + Debug( "Licensing URL: {}", mLicenseUrl ); + Debug( "Health URL: {}", mHealthUrl ); } int32_t DrmWSClient::getTokenTimeLeft() const { @@ -159,12 +250,6 @@ int32_t DrmWSClient::getTokenTimeLeft() const { return (uint32_t)round( (double)delta.count() / 1000000000 ); } -void DrmWSClient::setOAuth2token( const std::string& token ) { - mOAuth2Token = token; - mTokenValidityPeriod = 10; - mTokenExpirationTime = TClock::now() + std::chrono::seconds( mTokenValidityPeriod ); -} - bool DrmWSClient::isTokenValid() const { uint32_t margin = ( mTokenExpirationMargin >= mTokenValidityPeriod ) ? ( mTokenValidityPeriod >> 1) : mTokenExpirationMargin; @@ -204,21 +289,10 @@ void DrmWSClient::requestOAuth2token( TClock::time_point deadline ) { json_resp = Json::nullValue; error_msg = e.what(); } - Debug( "Received code {} from OAuth2 Web Service in {} ms", - resp_code, mOAUth2Request.getTotalTime() * 1000 ); - // Analyze response - if ( resp_code != 200 ) { - // An error occurred - DRM_ErrorCode drm_error; - if ( CurlEasyPost::is_error_retryable( resp_code ) ) - drm_error = DRM_WSMayRetry; - else if ( ( resp_code >= 400 ) && ( resp_code < 500 ) ) - drm_error = DRM_WSReqError; - else - drm_error = DRM_WSError; + DRM_ErrorCode drm_error = CurlEasyPost::httpCode2DrmCode( resp_code ); + if ( drm_error != DRM_OK ) Throw( drm_error, "OAuth2 Web Service error {}: {}", resp_code, response ); - } // Verify response parsing if ( json_resp == Json::nullValue ) @@ -230,20 +304,22 @@ void DrmWSClient::requestOAuth2token( TClock::time_point deadline ) { mTokenExpirationTime = TClock::now() + std::chrono::seconds( mTokenValidityPeriod ); } - -Json::Value DrmWSClient::requestLicense( const Json::Value& json_req, TClock::time_point deadline ) { +Json::Value DrmWSClient::requestMetering( const std::string url, const Json::Value& json_req, TClock::time_point deadline ) { // Create new request CurlEasyPost req; + req.setVerbosity( mVerbosity ); + req.setConnectionTimeoutMS( mRequestTimeout ); req.setHostResolves( mHostResolvesJson ); - req.setURL( mMeteringUrl ); - req.appendHeader( "Accept: application/json" ); + req.setURL( url ); + req.appendHeader( "Accept: application/vnd.accelize.v1+json" ); req.appendHeader( "Content-Type: application/json" ); - req.appendHeader( std::string("Authorization: Bearer ") + mOAuth2Token ); + std::string token_header("Authorization: Bearer "); + token_header += mOAuth2Token; + req.appendHeader( token_header ); req.setPostFields( saveJsonToString( json_req ) ); // Send request and wait response - Debug( "Starting license request to {} with request:\n{}", mMeteringUrl, json_req.toStyledString() ); std::string response; long resp_code = req.perform( &response, deadline ); @@ -256,29 +332,33 @@ Json::Value DrmWSClient::requestLicense( const Json::Value& json_req, TClock::ti json_resp = Json::nullValue; error_msg = e.what(); } - Debug( "Received code {} from License Web Service in {} ms", - resp_code, req.getTotalTime() * 1000 ); // Analyze response - if ( resp_code != 200 ) { - // An error occurred - DRM_ErrorCode drm_error; - if ( CurlEasyPost::is_error_retryable( resp_code ) || ( resp_code == 401 ) ) - drm_error = DRM_WSMayRetry; - else if ( ( resp_code >= 400 ) && ( resp_code < 500 ) ) - drm_error = DRM_WSReqError; - else - drm_error = DRM_WSError; - Throw( drm_error, "License Web Service error {}: {}", resp_code, response ); - } + DRM_ErrorCode drm_error = CurlEasyPost::httpCode2DrmCode( resp_code ); + if ( resp_code == 401 ) + drm_error = DRM_WSMayRetry; + // An error occurred + if ( drm_error != DRM_OK ) + Throw( drm_error, "Metering Web Service error {}: {}", resp_code, response ); + // Verify response parsing if ( json_resp == Json::nullValue ) - Throw( DRM_WSRespError, "Failed to parse response from License Web Service because {}: {}", + Throw( DRM_WSRespError, "Failed to parse response from Metering Web Service because {}: {}", error_msg, response); // No error: return the response as JSON object return json_resp; } +Json::Value DrmWSClient::requestLicense( const Json::Value& json_req, TClock::time_point deadline ) { + Debug( "Starting License request to {} with request:\n{}", mLicenseUrl, json_req.toStyledString() ); + return requestMetering( mLicenseUrl, json_req, deadline ); +} + +Json::Value DrmWSClient::requestHealth( const Json::Value& json_req, TClock::time_point deadline ) { + Debug( "Starting Health request to {} with request:\n{}", mHealthUrl, json_req.toStyledString() ); + return requestMetering( mHealthUrl, json_req, deadline ); +} + } } diff --git a/spdlog b/spdlog index 1549ff12..616caa5d 160000 --- a/spdlog +++ b/spdlog @@ -1 +1 @@ -Subproject commit 1549ff12f1aa61ffc4d9a8727c519034724392a0 +Subproject commit 616caa5d30172b65cc3a06800894c575d70cb8e6 diff --git a/tests/conftest.py b/tests/conftest.py index ff6efa53..03e6a889 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,17 +1,24 @@ # -*- coding: utf-8 -*- """Configure Pytest""" +import pytest +import sys +import hashlib + from copy import deepcopy -from json import dump, load -from os import environ, getpid, listdir, remove +from json import dump, load, dumps +from os import environ, getpid, listdir, remove, makedirs, getcwd, urandom from os.path import basename, dirname, expanduser, isdir, isfile, join, \ realpath, splitext from random import randint from re import IGNORECASE, match, search - -import pytest - +from datetime import datetime +from time import time, sleep +from shutil import rmtree +from datetime import datetime, timedelta +from tests.proxy import create_app, get_context, set_context from tests.ws_admin_functions import WSListFunction + _SESSION = dict() _LICENSING_SERVERS = dict( dev='https://master.devmetering.accelize.com', @@ -20,12 +27,19 @@ ACT_STATUS_REG_OFFSET = 0x38 MAILBOX_REG_OFFSET = 0x3C INC_EVENT_REG_OFFSET = 0x40 +CNT_EVENT_REG_OFFSET = 0x44 + +HASH_FUNTION_TABLE = {} def bit_not(n, numbits=32): return (1 << numbits) - 1 - n +def cheap_hash(string_in, length=6): + return hashlib.md5(string_in).hexdigest()[:length] + + def get_default_conf_json(licensing_server_url): """ Get default "conf.json" file content as python dict. @@ -108,6 +122,10 @@ def param2dict(param_list): return d +def whoami(): + return sys._getframe(1).f_code.co_name + + # Pytest configuration def pytest_addoption(parser): """ @@ -140,7 +158,11 @@ def pytest_addoption(parser): parser.addoption( "--no_clear_fpga", action="store_true", help='Bypass clearing of FPGA at start-up') parser.addoption( - "--logfile", action="store_true", help='Save log to file') + "--logfile", nargs='?', type=str, const='', default=None, help='Save log to file path.') + parser.addoption( + "--logfilelevel", action="store", type=int, default=1, choices=(0,1,2,3,4,5), help='Specify verbosity for --logfile') + parser.addoption( + "--logfileappend", action="store_true", default=False, help='Append log message to same file. File path is specified by --logfile') parser.addoption( "--proxy_debug", action="store_true", default=False, help='Activate debug for proxy') @@ -167,6 +189,9 @@ def pytest_addoption(parser): help='Specify a list of key=value pairs separated by a coma used ' 'for one or multiple tests: ' '"--params key1=value1,key2=value2,..."') + parser.addoption( + "--artifacts_dir", action="store", default=getcwd(), + help='Specify pytest artifacts directory') def pytest_runtest_setup(item): @@ -191,6 +216,16 @@ def pytest_runtest_setup(item): if markers and skip_endurance: pytest.skip("Don't run endurance tests.") + # Check lgdn tests + m_option = item.config.getoption('-m') + if search(r'\blgdn\b', m_option) and not search(r'\nnot\n\s+\blgdn\b', m_option): + skip_lgdn = False + else: + skip_lgdn = True + markers = tuple(item.iter_markers(name='lgdn')) + if markers and skip_lgdn: + pytest.skip("Don't run LGDN tests.") + # Check AWS execution markers = tuple(item.iter_markers(name='aws')) if '${AWS}' == 'OFF' and markers: @@ -200,6 +235,11 @@ def pytest_runtest_setup(item): if 'security' == marker.name and 'security' not in item.config.option.markexpr: pytest.skip('"security" marker not selected') + # Skip 'long_run' test if not explicitly marked + for marker in item.iter_markers(): + if 'long_run' == marker.name and 'long_run' not in item.config.option.markexpr: + pytest.skip('"long_run" marker not selected') + class SingleActivator: """ @@ -209,6 +249,7 @@ def __init__(self, driver, base_address): self.driver = driver self.base_address = base_address self.metering_data = 0 + self.event_cnt_flag = self.driver.read_register(self.base_address + CNT_EVENT_REG_OFFSET) != 0xDEADDEAD def autotest(self, is_activated=None): """ @@ -234,7 +275,7 @@ def autotest(self, is_activated=None): # Test reading of the generate event register assert self.driver.read_register(self.base_address + INC_EVENT_REG_OFFSET) == 0x600DC0DE # Test address overflow - assert self.driver.read_register(self.base_address + INC_EVENT_REG_OFFSET + 0x4) == 0xDEADDEAD + assert self.driver.read_register(self.base_address + CNT_EVENT_REG_OFFSET + 0x4) == 0xDEADDEAD def get_status(self): """ @@ -243,7 +284,7 @@ def get_status(self): Returns: int: Status. """ - return self.driver.read_register(self.base_address+ACT_STATUS_REG_OFFSET) == 3 + return self.driver.read_register(self.base_address + ACT_STATUS_REG_OFFSET) == 3 def generate_coin(self, coins): """ @@ -253,7 +294,7 @@ def generate_coin(self, coins): coins (int): Number of coins to generate. """ for _ in range(coins): - self.driver.write_register(self.base_address+INC_EVENT_REG_OFFSET, 0) + self.driver.write_register(self.base_address + INC_EVENT_REG_OFFSET, 0) if self.get_status(): self.metering_data += coins @@ -262,6 +303,9 @@ def reset_coin(self): Reset the coins counter """ self.metering_data = 0 + self.driver.write_register(self.base_address + CNT_EVENT_REG_OFFSET, 0) + if self.event_cnt_flag: + assert self.driver.read_register(self.base_address + CNT_EVENT_REG_OFFSET) == 0 def check_coin(self, coins): """ @@ -270,7 +314,12 @@ def check_coin(self, coins): Args: coins (int): Number of coins to compare to. """ + # Check local counter with dmr value passed in argument assert self.metering_data == coins + # Check with counter in Activator's registery + if self.event_cnt_flag: + assert self.metering_data == self.driver.read_register(self.base_address + CNT_EVENT_REG_OFFSET) + class ActivatorsInFPGA: @@ -334,7 +383,6 @@ def reset_coin(self): - class RefDesign: """ Handle HDK versions and their related FPGA image ID @@ -431,6 +479,12 @@ def accelize_drm(pytestconfig): if build_source_dir.startswith('@'): build_source_dir = realpath('.') + # Create pytest artifacts directory + pytest_artifacts_dir = join(pytestconfig.getoption("artifacts_dir"), 'pytest_artifacts') + if not isdir(pytest_artifacts_dir): + makedirs(pytest_artifacts_dir) + print('pytest artifacts directory: ', pytest_artifacts_dir) + # Get Ref Designs available ref_designs = RefDesign(join(build_source_dir, 'tests', 'refdesigns', fpga_driver_name)) @@ -499,6 +553,31 @@ def accelize_drm(pytestconfig): raise IOError('No activator found on slot #%d' % driver._fpga_slot_id) print('Found %d activator(s) on slot #%d' % (len(base_addr_list), driver._fpga_slot_id)) + # Create pytest artifacts directory + pytest_artifacts_dir = join(pytestconfig.getoption("artifacts_dir"), 'pytest_artifacts') + if not isdir(pytest_artifacts_dir): + makedirs(pytest_artifacts_dir) + print('pytest artifacts directory: ', pytest_artifacts_dir) + + # Define function to create log file path + def create_log_path(prefix=None): + if prefix is None: + prefix = "pytest_drmlib" + while True: + log_path = realpath(join(pytest_artifacts_dir, "%s.%s.%d.log" % (prefix, time(), getpid()))) + if not isfile(log_path): + return log_path + + # Define function to create log file verbosity with regard of --logfile + def create_log_level(verbosity): + if not pytestconfig.getoption("logfile"): + return verbosity + verb_option = int(pytestconfig.getoption("logfilelevel")) + if verbosity > verb_option: + return verb_option + else: + return verbosity + # Store some values for access in tests import accelize_drm as _accelize_drm _accelize_drm.pytest_new_freq_method_supported = fpga_driver[0].read_register(drm_ctrl_base_addr + 0xFFF8) == 0x60DC0DE0 @@ -520,6 +599,9 @@ def accelize_drm(pytestconfig): _accelize_drm.clean_metering_env = lambda *kargs, **kwargs: clean_metering_env( *kargs, **kwargs, product_name=fpga_activators[0].product_id['name']) _accelize_drm.pytest_params = param2dict(pytestconfig.getoption("params")) + _accelize_drm.pytest_artifacts_dir = pytest_artifacts_dir + _accelize_drm.create_log_path = create_log_path + _accelize_drm.create_log_level = create_log_level return _accelize_drm @@ -636,9 +718,31 @@ def set_user(self, user=None): self[m.group(1)] = v self._user = user if ('client_id' not in self._content) or ('client_secret' not in self._content): - raise ValueError('User "%s" not found in "%s"' % (self._user, self._init_cred_path)) + raise ValueError('User "%s" not found in "%s"' % (user, self._init_cred_path)) self.save() + def get_user(self, user=None): + """ + Return user details. + + Args: + user (str): User to get. If not specified, use default user. + """ + content = {} + if user is None: + for k, v in [e for e in self._initial_content.items() if not e.endswith('__')]: + content[k] = v + content['user'] = '' + else: + for k, v in self._initial_content.items(): + m = match(r'(.+)__%s__' % user, k) + if m: + content[m.group(1)] = v + content['user'] = user + if ('client_id' not in content) or ('client_secret' not in content): + raise ValueError('User "%s" not found in "%s"' % (user, self._init_cred_path)) + return content + @property def user(self): return self._user @@ -665,20 +769,34 @@ def client_secret(self, s): @pytest.fixture -def conf_json(pytestconfig, tmpdir): +def conf_json(request, pytestconfig, tmpdir): """ Manage "conf.json" in testing environment. """ + # Compute hash of caller function + function_name = request.function.__name__ + hash_value = cheap_hash(function_name.encode('utf-8')) + if hash_value not in HASH_FUNTION_TABLE.keys(): + HASH_FUNTION_TABLE[hash_value] = function_name + with open(join(getcwd(),'hash_function_table.txt'), 'wt') as f: + f.write(dumps(HASH_FUNTION_TABLE, indent=4, sort_keys=True)) + design_param = {'boardType': hash_value} + # Build config content log_param = {'log_verbosity': pytestconfig.getoption("library_verbosity")} if pytestconfig.getoption("library_format") == 1: log_param['log_format'] = '%Y-%m-%d %H:%M:%S.%e - %18s:%-4# [%=8l] %=6t, %v' else: log_param['log_format'] = '[%^%=8l%$] %-6t, %v' - if pytestconfig.getoption("logfile"): + if pytestconfig.getoption("logfile") is not None: log_param['log_file_type'] = 1 - log_param['log_file_path'] = realpath("./drmlib.%d.log" % getpid()) - log_param['log_file_verbosity'] = pytestconfig.getoption("library_verbosity") - json_conf = ConfJson(tmpdir, pytestconfig.getoption("server"), settings=log_param) + if len(pytestconfig.getoption("logfile")) != 0: + log_param['log_file_path'] = pytestconfig.getoption("logfilepath") + else: + log_param['log_file_path'] = realpath("./tox_drmlib_t%f_pid%d.log" % (time(), getpid())) + log_param['log_file_verbosity'] = pytestconfig.getoption("logfilelevel") + log_param['log_file_append'] = True if pytestconfig.getoption("logfileappend") else False + # Save config to JSON file + json_conf = ConfJson(tmpdir, pytestconfig.getoption("server"), settings=log_param, design=design_param) json_conf.save() return json_conf @@ -783,6 +901,41 @@ def perform_once(test_name): pass +def wait_func_true(func, timeout=None, sleep_time=1): + """ + Wait until the func retursn a none 0 value + + Args: + func (__call__) : Function that is run and evaluated + timeout (int) : Specify a timeout in seconds for the loop + sleep_time (int) : Sleep in seconds befaore reexecuting the function + + Returns: + boolean: True if the output of the function has been evaluated to True, False otherwise + """ + start = datetime.now() + while not func(): + if timeout: + if (datetime.now() - start) > timedelta(seconds=timeout): + raise RuntimeError('Timeout!') + sleep(sleep_time) + + +def wait_deadline(start_time, duration): + """ + Wait until endtime is hit + + Args: + start_time (datetime): start time of the timer. + duration to wait for (int): duration in seconds to wait for. + """ + wait_period = start_time + timedelta(seconds=duration) - datetime.now() + if wait_period.total_seconds() <= 0: + return + sleep(wait_period.total_seconds()) + + + class AsyncErrorHandler: """ Asynchronous error callback @@ -852,6 +1005,12 @@ def remove_product_information(self, library, name, user): text, status = self._functions.remove_product_information(data) assert status == 200, text + def get_last_metering_information(self, session_id): + self._functions._get_user_token() + text, status = self._functions.metering_lastinformation({'session': session_id}) + assert status == 200, text + return text + @property def functions(self): return self._functions @@ -859,10 +1018,10 @@ def functions(self): @pytest.fixture def ws_admin(cred_json, conf_json): - cred_json.set_user('admin') - assert cred_json.user == 'admin' - return WSAdmin(conf_json['licensing']['url'], cred_json['client_id'], - cred_json['client_secret']) + cred = cred_json.get_user('admin') + assert cred['user'] == 'admin' + return WSAdmin(conf_json['licensing']['url'], cred['client_id'], + cred['client_secret']) class ExecFunction: @@ -936,36 +1095,9 @@ def exec_func(accelize_drm, cred_json, conf_json): # Proxy fixture #-------------- -class EndpointAction: - - def __init__(self, action): - self.action = action - - def __call__(self, *kargs, **kwargs): - return self.action(*kargs, **kwargs) - if isinstance(resp,Response): - return resp - return Response(msg, status=status, headers={}) - - -class FlaskAppWrapper: - def __init__(self, name=__name__): - import flask - self.app = flask.Flask(name) - environ['WERKZEUG_RUN_MAIN'] = 'true' - environ['FLASK_ENV'] = 'development' - - def run(self, host='127.0.0.1', port=5000, debug=False): - self.host = host - self.port = port - self.app.run(host=self.host, port=self.port, debug=debug) - - def add_endpoint(self, rule=None, endpoint=None, handler=None, **kwargs): - self.app.add_url_rule(rule, endpoint, EndpointAction(handler), **kwargs) - - -@pytest.fixture -def fake_server(): - name = "fake_server_%d" % randint(1,0xFFFFFFFF) - return FlaskAppWrapper(name) - +@pytest.fixture(scope='session') +def app(pytestconfig): + url = _LICENSING_SERVERS[pytestconfig.getoption("server")] + app = create_app(url) + app.debug = pytestconfig.getoption("proxy_debug") + return app diff --git a/tests/proxy.py b/tests/proxy.py new file mode 100644 index 00000000..48525595 --- /dev/null +++ b/tests/proxy.py @@ -0,0 +1,702 @@ +import os +from json import dumps +from flask import Flask, request, session, redirect, Response, jsonify, url_for +from requests import get, post +from datetime import datetime +from threading import Lock +from re import search +from time import sleep + +context = None +lock = Lock() + +def create_app(url): + app = Flask(__name__) + app.secret_key = 'You Will Never Guess' + #os.environ['WERKZEUG_RUN_MAIN'] = 'true' + os.environ['FLASK_ENV'] = 'development' + url = url.rstrip('/') + ''' + @app.errorhandler(Exception) + def all_exception_handler(error): + global context, lock + with lock: + if context: + context['exception'] = str(error) + return 'Proxy caught exception: %s' % str(error), 500 + ''' + @app.route('/get/', methods=['GET']) + def get(): + global lock + with lock: + return jsonify(context) + + @app.route('/set/', methods=['POST']) + def set(): + global context, lock + with lock: + context = request.get_json() + return 'OK' + + # Functions calling the real web services + @app.route('/o/token/', methods=['GET', 'POST']) + def otoken(): + new_url = url + '/o/token/' + return redirect(new_url, code=307) + + @app.route('/auth/metering/health/', methods=['GET', 'POST']) + def health(): + request_json = request.get_json() + new_url = url + '/auth/metering/health/' + response = post(new_url, json=request_json, headers=request.headers) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + return Response(dumps(response_json), response.status_code, headers) + + @app.route('/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense(): + request_json = request.get_json() + new_url = url + '/auth/metering/genlicense/' + response = post(new_url, json=request_json, headers=request.headers) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + return Response(dumps(response_json), response.status_code, headers) + + ############################################################################## + # test_authentication.py + + # test_authentication_bad_token + @app.route('/test_authentication_bad_token/o/token/', methods=['GET', 'POST']) + def otoken__test_authentication_bad_token(): + global context, lock + new_url = request.url.replace(request.url_root+'test_authentication_bad_token', url) + response = post(new_url, data=request.form, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request.form, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + response_json['access_token'] = context['access_token'] + return Response(dumps(response_json), response.status_code, headers) + + @app.route('/test_authentication_bad_token/auth/metering/health/', methods=['GET', 'POST']) + def health__test_authentication_bad_token(): + return redirect(request.url_root + '/auth/metering/health/', code=307) + + @app.route('/test_authentication_bad_token/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_authentication_bad_token_genlicense(): + return redirect(request.url_root + '/auth/metering/genlicense/', code=307) + + # test_authentication_token_renewal + @app.route('/test_authentication_token_renewal/o/token/', methods=['GET', 'POST']) + def otoken__test_authentication_token_renewal(): + global context, lock + new_url = url + '/o/token/' + response = post(new_url, data=request.form, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request.form, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + response_json['expires_in'] = context['expires_in'] + return Response(dumps(response_json), response.status_code, headers) + + @app.route('/test_authentication_token_renewal/auth/metering/health/', methods=['GET', 'POST']) + def health__test_authentication_token_renewal(): + return redirect(request.url_root + '/auth/metering/health/', code=307) + + @app.route('/test_authentication_token_renewal/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_authentication_token_renewal_genlicense(): + return redirect(request.url_root + '/auth/metering/genlicense/', code=307) + + ############################################################################## + # test_drm_license_error.py + + # test_header_error_on_key functions + @app.route('/test_header_error_on_key/o/token/', methods=['GET', 'POST']) + def otoken__test_header_error_on_key(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_header_error_on_key/auth/metering/health/', methods=['GET', 'POST']) + def health__test_header_error_on_key(): + return redirect(request.url_root + '/auth/metering/health/', code=307) + + @app.route('/test_header_error_on_key/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_header_error_on_key_genlicense(): + global context, lock + new_url = request.url.replace(request.url_root+'test_header_error_on_key', url) + request_json = request.get_json() + with lock: + if context['cnt'] > 0: + return ({'error':'Test did not run as expected'}, 408) + context['cnt'] += 1 + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + response_json = response.json() + dna, lic_json = list(response_json['license'].items())[0] + key = lic_json['key'] + key = '1' + key[1:] if key[0] == '0' else '0' + key[1:] + response_json['license'][dna]['key'] = key + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + return Response(dumps(response_json), response.status_code, headers) + + # test_header_error_on_licenseTimer functions + @app.route('/test_header_error_on_licenseTimer/o/token/', methods=['GET', 'POST']) + def otoken__test_header_error_on_licenseTimer(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_header_error_on_licenseTimer/auth/metering/health/', methods=['GET', 'POST']) + def health__test_header_error_on_licenseTimer(): + return redirect(request.url_root + '/auth/metering/health/', code=307) + + @app.route('/test_header_error_on_licenseTimer/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_header_error_on_licenseTimer(): + global context, lock + new_url = request.url.replace(request.url_root+'test_header_error_on_licenseTimer', url) + request_json = request.get_json() + with lock: + cnt = context['cnt'] + if cnt > 1: + return ({'error':'Test did not run as expected'}, 408) + context['cnt'] += 1 + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + response_json = response.json() + if cnt == 1: + dna, lic_json = list(response_json['license'].items())[0] + timer = lic_json['licenseTimer'] + timer = '1' + timer[1:] if timer[0] == '0' else '0' + timer[1:] + response_json['license'][dna]['licenseTimer'] = timer + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + return Response(dumps(response_json), response.status_code, headers) + + # test_session_id_error functions + @app.route('/test_session_id_error/o/token/', methods=['GET', 'POST']) + def otoken__test_session_id_error(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_session_id_error/auth/metering/health/', methods=['GET', 'POST']) + def health__test_session_id_error(): + return redirect(request.url_root + '/auth/metering/health/', code=307) + + @app.route('/test_session_id_error/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_session_id_error(): + global context, lock + new_url = request.url.replace(request.url_root+'test_session_id_error', url) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + response_json = response.json() + response_session_id = response_json['metering']['sessionId'] + with lock: + if context['session_id'] != response_session_id: + context['session_cnt'] += 1 + context['request_cnt'] = 0 + context['request_cnt'] += 1 + context['session_id'] = response_session_id + if context['session_cnt'] == 2: + if context['request_cnt'] == 2: + response = context['replay'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + return Response(response.content, response.status_code, headers) + else: + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + if context['request_cnt'] == 2: + context['replay'] = response + return Response(response.content, response.status_code, headers) + + ############################################################################## + # test_async_health.py + + # test_health_period_disabled functions + @app.route('/test_health_period_disabled/o/token/', methods=['GET', 'POST']) + def otoken__test_health_period_disabled(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_health_period_disabled/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_health_period_disabled(): + global context, lock + new_url = request.url.replace(request.url_root+'test_health_period_disabled', url) + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + return Response(dumps(response_json), response.status_code, headers) + + @app.route('/test_health_period_disabled/auth/metering/health/', methods=['GET', 'POST']) + def health__test_health_period_disabled(): + global context, lock + new_url = request.url.replace(request.url_root+'test_health_period_disabled', url) + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + context['cnt'] += 1 + if context['cnt'] < context['nb_health']: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + else: + response_json['metering']['healthPeriod'] = 0 + context['exit'] = True + return Response(dumps(response_json), response.status_code, headers) + + # test_health_period_modification functions + @app.route('/test_health_period_modification/o/token/', methods=['GET', 'POST']) + def otoken__test_health_period_modification(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_health_period_modification/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_health_period_modification(): + global context, lock + new_url = request.url.replace(request.url_root+'test_health_period_modification', url) + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + return Response(dumps(response_json), response.status_code, headers) + + @app.route('/test_health_period_modification/auth/metering/health/', methods=['GET', 'POST']) + def health__test_health_period_modification(): + global context, lock + start = str(datetime.now()) + new_url = request.url.replace(request.url_root+'test_health_period_modification', url) + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + response_json['metering']['healthRetry'] = context['healthRetry'] + response_json['metering']['healthRetrySleep'] = context['healthRetrySleep'] + context['healthPeriod'] += 1 + context['data'].append( (start,str(datetime.now())) ) + return Response(dumps(response_json), response.status_code, headers) + + # test_health_retry_disabled functions + @app.route('/test_health_retry_disabled/o/token/', methods=['GET', 'POST']) + def otoken__test_health_retry_disabled(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_health_retry_disabled/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_health_retry_disabled(): + new_url = request.url.replace(request.url_root+'test_health_retry_disabled', url) + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + return Response(dumps(response_json), response.status_code, headers) + + @app.route('/test_health_retry_disabled/auth/metering/health/', methods=['GET', 'POST']) + def health__test_health_retry_disabled(): + global context, lock + start = str(datetime.now()) + new_url = request.url.replace(request.url_root+'test_health_retry_disabled', url) + request_json = request.get_json() + health_id = request_json['health_id'] + with lock: + if len(context['data']) <= 1: + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + response_json['metering']['healthPeriod'] = context['healthPeriod'] + response_json['metering']['healthRetry'] = 0 + response_json['metering']['healthRetrySleep'] = context['healthRetrySleep'] + response_status_code = response.status_code + context['post'] = (response_json, headers) + else: + response_json, headers = context['post'] + response_status_code = 408 + context['data'].append( (health_id,start,str(datetime.now())) ) + return Response(dumps(response_json), response_status_code, headers) + + # test_health_retry_modification functions + @app.route('/test_health_retry_modification/o/token/', methods=['GET', 'POST']) + def otoken__test_health_retry_modification(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_health_retry_modification/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_health_retry_modification(): + global context, lock + new_url = request.url.replace(request.url_root+'test_health_retry_modification', url) + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + return Response(dumps(response_json), response.status_code, headers) + + @app.route('/test_health_retry_modification/auth/metering/health/', methods=['GET', 'POST']) + def health__test_health_retry_modification(): + global context, lock + start = str(datetime.now()) + new_url = request.url.replace(request.url_root+'test_health_retry_modification', url) + request_json = request.get_json() + health_id = request_json['health_id'] + with lock: + if len(context['data']) < 1: + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + response_json['metering']['healthPeriod'] = context['healthPeriod'] + response_json['metering']['healthRetry'] = context['healthRetry'] + response_json['metering']['healthRetrySleep'] = context['healthRetrySleep'] + response_status_code = response.status_code + context['post'] = (response_json, headers) + else: + response_json, headers = context['post'] + response_status_code = 408 + if health_id <= 1: + context['data'].append( (health_id,start,str(datetime.now())) ) + else: + context['exit'] = True + return Response(dumps(response_json), response_status_code, headers) + + # test_health_retry_sleep_modification functions + @app.route('/test_health_retry_sleep_modification/o/token/', methods=['GET', 'POST']) + def otoken__test_health_retry_sleep_modification(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_health_retry_sleep_modification/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_health_retry_sleep_modification(): + global context, lock + new_url = request.url.replace(request.url_root+'test_health_retry_sleep_modification', url) + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + return Response(dumps(response_json), response.status_code, headers) + + @app.route('/test_health_retry_sleep_modification/auth/metering/health/', methods=['GET', 'POST']) + def health__test_health_retry_sleep_modification(): + global context, lock + start = str(datetime.now()) + new_url = request.url.replace(request.url_root+'test_health_retry_sleep_modification', url) + request_json = request.get_json() + health_id = request_json['health_id'] + with lock: + if len(context['data']) < 1: + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + response_json['metering']['healthPeriod'] = context['healthPeriod'] + response_json['metering']['healthRetry'] = context['healthRetry'] + response_json['metering']['healthRetrySleep'] = context['healthRetrySleep'] + response_status_code = response.status_code + context['post'] = (response_json, headers) + else: + response_json, headers = context['post'] + response_status_code = 408 + if health_id <= 1: + context['data'].append( (health_id,start,str(datetime.now())) ) + else: + context['exit'] = True + return Response(dumps(response_json), response_status_code, headers) + + # test_health_metering_data functions + @app.route('/test_health_metering_data/o/token/', methods=['GET', 'POST']) + def otoken__test_health_metering_data(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_health_metering_data/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_health_metering_data(): + global context, lock + new_url = request.url.replace(request.url_root+'test_health_metering_data', url) + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + return Response(dumps(response_json), response.status_code, headers) + + @app.route('/test_health_metering_data/auth/metering/health/', methods=['GET', 'POST']) + def health__test_health_metering_data(): + global context, lock + new_url = request.url.replace(request.url_root+'test_health_metering_data', url) + request_json = request.get_json() + health_id = request_json['health_id'] + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + response_json['metering']['healthRetry'] = context['healthRetry'] + context['health_id']= health_id + return Response(dumps(response_json), response.status_code, headers) + + # test_segment_index functions + @app.route('/test_segment_index/o/token/', methods=['GET', 'POST']) + def otoken__test_segment_index(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_segment_index/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_segment_index(): + global context, lock + new_url = request.url.replace(request.url_root+'test_segment_index', url) + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + response_json['metering']['healthRetry'] = context['healthRetry'] + context['nb_genlic'] += 1 + return Response(dumps(response_json), response.status_code, headers) + + @app.route('/test_segment_index/auth/metering/health/', methods=['GET', 'POST']) + def health__test_segment_index(): + global context, lock + new_url = request.url.replace(request.url_root+'test_segment_index', url) + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + with lock: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + response_json['metering']['healthRetry'] = context['healthRetry'] + return Response(dumps(response_json), response.status_code, headers) + + ############################################################################## + # test_retry_mechanism.py + + # test_api_retry functions + @app.route('/test_api_retry/o/token/', methods=['GET', 'POST']) + def otoken__test_api_retry(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_api_retry/auth/metering/health/', methods=['GET', 'POST']) + def health__test_api_retry(): + return redirect(request.url_root + '/auth/metering/health/', code=307) + + @app.route('/test_api_retry/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_api_retry(): + global context, lock + start = str(datetime.now()) + new_url = request.url.replace(request.url_root+'test_api_retry', url) + request_json = request.get_json() + request_type = request_json['request'] + return ({'error':'Force retry for testing'}, 408) + + # test_long_to_short_retry_switch functions + @app.route('/test_long_to_short_retry_switch/o/token/', methods=['GET', 'POST']) + def otoken__test_long_to_short_retry_switch(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_long_to_short_retry_switch/auth/metering/health/', methods=['GET', 'POST']) + def health__test_long_to_short_retry_switch(): + return redirect(request.url_root + '/auth/metering/health/', code=307) + + @app.route('/test_long_to_short_retry_switch/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_long_to_short_retry_switch(): + global context, lock + with lock: + start = str(datetime.now()) + new_url = request.url.replace(request.url_root+'test_long_to_short_retry_switch', url) + request_json = request.get_json() + request_type = request_json['request'] + if context['cnt'] < 2 or request_type == 'close': + response = post(new_url, json=request_json, headers=request.headers) + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + if context['cnt'] == 0: + timeoutSecond = context['timeoutSecondFirst2'] + else: + timeoutSecond = context['timeoutSecond'] + response_json['metering']['timeoutSecond'] = timeoutSecond + context['post'] = (response_json, headers) + response_status_code = response.status_code + else: + response_json, headers = context['post'] + response_status_code = 408 + context['data'].append( (request_type,start,str(datetime.now())) ) + context['cnt'] += 1 + return Response(dumps(response_json), response_status_code, headers) + + # test_retry_on_no_connection functions + @app.route('/test_retry_on_no_connection/o/token/', methods=['GET', 'POST']) + def otoken__test_retry_on_no_connection(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_retry_on_no_connection/auth/metering/health/', methods=['GET', 'POST']) + def health__test_retry_on_no_connection(): + return redirect(request.url_root + '/auth/metering/health/', code=307) + + @app.route('/test_retry_on_no_connection/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_retry_on_no_connection(): + global context, lock + request_json = request.get_json() + request_type = request_json['request'] + with lock: + cnt = context['cnt'] + context['cnt'] += 1 + if cnt < 1 or request_type == 'close': + new_url = request.url.replace(request.url_root+'test_retry_on_no_connection', url) + response = post(new_url, json=request_json, headers=request.headers) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + response_json['metering']['timeoutSecond'] = context['timeoutSecond'] + return Response(dumps(response_json), response.status_code, headers) + else: + sleep(context['timeoutSecond']) + return ('', 204) + + + ############################################################################## + # test_unittest_on_hw.py + + # test_http_header_api_version functions + @app.route('/test_http_header_api_version/o/token/', methods=['GET', 'POST']) + def otoken__test_http_header_api_version(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_http_header_api_version/auth/metering/health/', methods=['GET', 'POST']) + def health__test_http_header_api_version(): + return redirect(request.url_root + '/auth/metering/health/', code=307) + + @app.route('/test_http_header_api_version/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_http_header_api_version(): + new_url = request.url.replace(request.url_root+'test_http_header_api_version', url) + request_json = request.get_json() + assert search(r'Accept:.*application/vnd\.accelize\.v1\+json', str(request.headers)) + response = post(new_url, json=request_json, headers=request.headers) + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + return Response(dumps(response_json), response.status_code, headers) + + ############################################################################## + # test_lgdn_topics.py + + # test_topic0_corrupted_segment_index functions + @app.route('/test_topic0_corrupted_segment_index/o/token/', methods=['GET', 'POST']) + def otoken__test_topic0_corrupted_segment_index(): + return redirect(request.url_root + '/o/token/', code=307) + + @app.route('/test_topic0_corrupted_segment_index/auth/metering/genlicense/', methods=['GET', 'POST']) + def genlicense__test_topic0_corrupted_segment_index(): + global context, lock + new_url = request.url.replace(request.url_root+'test_topic0_corrupted_segment_index', url) + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + try: + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + except AssertionError as e: + if 'Metering information is not consistent' in str(e): + with lock: + context['error'] += 1 + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + if 'metering' in response_json.keys(): + with lock: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + return Response(dumps(response_json), response.status_code, headers) + + @app.route('/test_topic0_corrupted_segment_index/auth/metering/health/', methods=['GET', 'POST']) + def health__test_topic0_corrupted_segment_index(): + global context, lock + new_url = request.url.replace(request.url_root+'test_topic0_corrupted_segment_index', url) + request_json = request.get_json() + response = post(new_url, json=request_json, headers=request.headers) + try: + assert response.status_code == 200, "Request:\n'%s'\nfailed with code %d and message: %s" % (dumps(request_json, + indent=4, sort_keys=True), response.status_code, response.text) + except AssertionError as e: + if 'Metering information is not consistent' in str(e): + with lock: + context['error'] += 1 + excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] + headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] + response_json = response.json() + if 'metering' in response_json.keys(): + with lock: + response_json['metering']['healthPeriod'] = context['healthPeriod'] + return Response(dumps(response_json), response.status_code, headers) + + return app + + +def get_context(): + r = get(url_for('get', _external=True)) + assert r.status_code == 200 + return r.json() + + +def set_context(data): + r = post(url_for('set', _external=True), json=data) + assert r.status_code == 200 + + +def get_proxy_error(): + r = get_context() + try: + return r['exception'] + except KeyError: + return None + diff --git a/tests/refdesigns/aws_f1/unmask_usage_v4.2.0.json b/tests/refdesigns/aws_f1/unmask_usage_v4.2.0.json new file mode 100644 index 00000000..25827192 --- /dev/null +++ b/tests/refdesigns/aws_f1/unmask_usage_v4.2.0.json @@ -0,0 +1,4 @@ +{ + "FpgaImageId": "afi-024829360f9aa59df", + "FpgaImageGlobalId": "agfi-0279c25ede2a93f04" +} diff --git a/tests/refdesigns/aws_f1/v2.3.2.json b/tests/refdesigns/aws_f1/v2.3.2.json index 8d6e4d95..d42b0128 100644 --- a/tests/refdesigns/aws_f1/v2.3.2.json +++ b/tests/refdesigns/aws_f1/v2.3.2.json @@ -1,4 +1,4 @@ { "FpgaImageId": "afi-07a8fa5b7a01534fc", "FpgaImageGlobalId": "agfi-05dd92fe7a8accbbb" -} +} \ No newline at end of file diff --git a/tests/refdesigns/aws_f1/v4.2.0.0_2activators.json b/tests/refdesigns/aws_f1/v4.2.0.0_2activators.json new file mode 100644 index 00000000..1bd3a63a --- /dev/null +++ b/tests/refdesigns/aws_f1/v4.2.0.0_2activators.json @@ -0,0 +1,4 @@ +{ + "FpgaImageId": "afi-0a7d45f7ee7d9a25a", + "FpgaImageGlobalId": "agfi-066cbb07d2acd4242" +} \ No newline at end of file diff --git a/tests/refdesigns/aws_f1/v4.2.1.0_2activators.json b/tests/refdesigns/aws_f1/v4.2.1.0_2activators.json new file mode 100644 index 00000000..5682af8f --- /dev/null +++ b/tests/refdesigns/aws_f1/v4.2.1.0_2activators.json @@ -0,0 +1,4 @@ +{ + "FpgaImageId": "afi-0391fd2919f0cd562", + "FpgaImageGlobalId": "agfi-0ffed2f5a68797c06" +} diff --git a/tests/test_abi_compliance.py b/tests/test_abi_compliance.py index 720e4ecc..0ac29ed3 100644 --- a/tests/test_abi_compliance.py +++ b/tests/test_abi_compliance.py @@ -4,8 +4,9 @@ """ import os import re - import pytest +from shutil import copy +from os.path import join, isdir, basename, splitext from tests.conftest import perform_once @@ -16,15 +17,12 @@ def _run(*command, **kwargs): """ Run a command. - Args: command (list of str): - Returns: subprocess.CompletedProcess """ from subprocess import run, CalledProcessError, PIPE - result = run(*command, stdout=PIPE, stderr=PIPE, universal_newlines=True, **kwargs) try: @@ -37,7 +35,6 @@ def _run(*command, **kwargs): def make(path, target=None): """ Make. - Args: path (str): Path of sources to make. target (str): Target @@ -49,7 +46,6 @@ def make(path, target=None): def dump_abi(dump_file, so_file, include, version, name): """ Dump library ABI. - Args: dump_file (str): Path to target ".abidump" file so_file (str): Path to source "libaccelize_drm.so" or @@ -57,25 +53,24 @@ def dump_abi(dump_file, so_file, include, version, name): include (str): Path to public headers "include" directory. version (str): Library version name (str): Library name. - Returns: tuple of str: version and dump_file """ - _run(['abi-dumper', so_file, '-public-headers', include, '-o', dump_file, + result = _run(['abi-dumper', so_file, '-public-headers', include, '-o', dump_file, '-lver', version]) + if re.search(r'\berror\b', result.stderr, re.I): + raise RuntimeError('abi-dumper error: %s' % result.stderr) return version, dump_file, name def checks_abi_compliance(old_dump, new_dump, name, report_path): """ Checks ABI compliance. - Args: old_dump (str): Path to old library version dump. new_dump (str): Path to new library version dump. name (str): Library name. report_path (str): HTML report path. - Returns: str: Report """ @@ -83,14 +78,12 @@ def checks_abi_compliance(old_dump, new_dump, name, report_path): new_dump, '-report-path', report_path]).stdout -def make_tag(version, path): +def build_tag_version(version, path): """ Clone and make DRMlib previous versions sources - Args: version (str): version to clone. path (str): Path to target directory. - Returns: tuple of str: version and path """ @@ -109,11 +102,9 @@ def make_tag(version, path): def get_reference_versions(tmpdir, abi_version): """ Get reference versions (Same ABI, ignoring "patch" versions). - Args: tmpdir: pytest tmpdir from test abi_version: (str): ABI version. - Returns: dict: version, directory """ @@ -122,6 +113,8 @@ def get_reference_versions(tmpdir, abi_version): tag.group(1) : str(tmpdir.join(tag.group(1))) for tag in list(map( lambda x: re.search(r'v((\d+)\.\d+\.\d+)$', x), tags.splitlines())) if (tag and int(tag.group(2))==abi_version) } + for k,v in sorted(versions.items(), key=lambda x: x[0], reverse=True): + return {k:v} return versions @@ -138,11 +131,10 @@ def test_abi_compliance(tmpdir, accelize_drm): # Initialize test from concurrent.futures import ThreadPoolExecutor, as_completed - build_futures = [] - dump_futures = [] - latest_futures = [] - tools_futures = [] - latest_dumps = {} + build_tag_futures = [] + dump_tag_futures = [] + dump_current_futures = [] + current_dumps = {} reports = {} with ThreadPoolExecutor() as executor: @@ -150,21 +142,20 @@ def test_abi_compliance(tmpdir, accelize_drm): def dumps_library(lib_version, lib_path, futures): """ Dumps a version asynchronously. - Args: lib_version (str): version. lib_path (str): Library directory. futures (list): Future list. """ - include = os.path.join(lib_path, 'include') + include = join(lib_path, 'include') for lib_name in LIB_NAMES: futures.append(executor.submit( dump_abi, str(tmpdir.join( '%s_%s.abidump' % (lib_name, lib_version))), - os.path.join(lib_path, '%s.so' % lib_name), include, + join(lib_path, '%s.so' % lib_name), include, lib_version, lib_name)) - # Get references versions + # Get reference versions abi_version = accelize_drm.get_api_version().major versions = executor.submit(get_reference_versions, tmpdir, abi_version) @@ -175,42 +166,46 @@ def dumps_library(lib_version, lib_path, futures): 'No previous versions with ABI version %s' % abi_version) print('CHECKING ABI/API AGAINST VERSIONS:', ', '.join(versions)) + # Close each tag with the same major version for version, path in versions.items(): - build_futures.append(executor.submit(make_tag, version, path)) + build_tag_futures.append(executor.submit(build_tag_version, version, path)) - # Waits for tools build completion - for future in as_completed(tools_futures): - future.result() - - # Dump latest version ABI and API - dumps_library('latest', '.', latest_futures) + # Dump current version ABI and API + dumps_library('current', '.', dump_current_futures) # Dumps reference versions ABI and API - for future in as_completed(build_futures): + for future in as_completed(build_tag_futures): version, path = future.result() - dumps_library(version, path, dump_futures) + dumps_library(version, path, dump_tag_futures) - # Waits for latest version dump completion - for future in as_completed(latest_futures): + # Waits for current version dump completion + for future in as_completed(dump_current_futures): _, dump_file, name = future.result() - latest_dumps[name] = dump_file + current_dumps[name] = dump_file - # Compare latest ABI / API dumps with reference versions - for future in as_completed(dump_futures): + # Compare current ABI / API dumps with reference versions + for future in as_completed(dump_tag_futures): version, dump_file, name = future.result() - - reports[' '.join((name, version))] = executor.submit( - checks_abi_compliance, old_dump=dump_file, - new_dump=latest_dumps[name], name=name, - report_path=str(tmpdir.join('%s%s.html' % (name, version)))) + report_file = join(accelize_drm.pytest_artifacts_dir, '%s%s.html' % (name, version)) + reports[' '.join((name, version))] = ( + report_file, + executor.submit( + checks_abi_compliance, + old_dump=dump_file, + new_dump=current_dumps[name], + name=name, + report_path=report_file) + ) # Analyses reports abi_broken = False - for title, future in reports.items(): - report = future.result() - if ('Total binary compatibility problems: 0' not in report or - 'Total source compatibility problems: 0,' not in report): + for title, (report_file, future) in reports.items(): + stdout = future.result() + if ('Total binary compatibility problems: 0' not in stdout or + 'Total source compatibility problems: 0,' not in stdout): + print('Comparison against %s shows issues:\n%s\n' % (title, stdout)) abi_broken = True - print('Comparison against %s:\n%s\n' % (title, report)) + else: + print('Comparison against %s shows no issue:\n%s\n' % (title, stdout)) assert not abi_broken diff --git a/tests/test_async_health.py b/tests/test_async_health.py new file mode 100644 index 00000000..0b8cad27 --- /dev/null +++ b/tests/test_async_health.py @@ -0,0 +1,463 @@ +# -*- coding: utf-8 -*- +""" +Test asynchronous metering behaviors of DRM Library. +""" +import pytest +from time import sleep +from random import randrange +from re import search, findall, MULTILINE +from dateutil import parser +from itertools import groupby +from flask import request +from requests import get, post +from os import remove +from os.path import realpath, isfile + +from tests.conftest import wait_func_true, whoami +from tests.proxy import get_context, set_context, get_proxy_error + + +@pytest.mark.no_parallel +@pytest.mark.minimum +def test_health_period_disabled(accelize_drm, conf_json, cred_json, async_handler, live_server): + """ + Test the asynchronous health feature can be disabled. + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_health_period_disabled' + logpath = accelize_drm.create_log_path(whoami()) + conf_json['settings']['log_file_verbosity'] = accelize_drm.create_log_level(1) + conf_json['settings']['log_file_type'] = 1 + conf_json['settings']['log_file_path'] = logpath + conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + + # Set initial context on the live server + nb_health = 2 + healthPeriod = 2 + context = {'cnt':0, 'healthPeriod':healthPeriod, 'nb_health':nb_health, 'exit':False} + set_context(context) + assert get_context() == context + + drm_manager.activate() + try: + assert drm_manager.get('health_period') == healthPeriod + wait_func_true(lambda: get_context()['exit'], + timeout=healthPeriod * (nb_health + 1) * 2) + assert drm_manager.get('health_period') == 0 + assert get_context()['cnt'] == nb_health + sleep(healthPeriod + 1) + assert get_context()['cnt'] == nb_health + finally: + drm_manager.deactivate() + del drm_manager + wait_func_true(lambda: isfile(logpath), 10) + with open(logpath, 'rt') as f: + log_content = f.read() + assert search(r'Exiting background thread which checks health', log_content, MULTILINE) + assert search(r'Health thread is disabled', log_content, MULTILINE) + assert search(r'Exiting background thread which checks health', log_content, MULTILINE) + health_req = findall(r'"request"\s*:\s*"health"', log_content) + assert len(list(health_req)) == nb_health + assert get_proxy_error() is None + async_cb.assert_NoError() + remove(logpath) + + +@pytest.mark.no_parallel +@pytest.mark.minimum +def test_health_period_modification(accelize_drm, conf_json, cred_json, async_handler, live_server): + """ + Test the asynchronous health feature can be modified dynamically. + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_health_period_modification' + conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + + # Set initial context on the live server + nb_health = 4 + healthPeriod = 2 + healthRetry = 0 # no retry + healthRetrySleep = 1 + context = {'data': list(), + 'healthPeriod':healthPeriod, + 'healthRetry':healthRetry, + 'healthRetrySleep':healthRetrySleep + } + set_context(context) + assert get_context() == context + + drm_manager.activate() + try: + wait_func_true(lambda: len(get_context()['data']) >= nb_health, + timeout=(healthPeriod+3) * (nb_health+2)) + finally: + drm_manager.deactivate() + async_cb.assert_NoError() + data_list = get_context()['data'] + assert len(data_list) >= nb_health + wait_start = data_list.pop(0)[1] + for i, (start, end) in enumerate(data_list): + delta = parser.parse(start) - parser.parse(wait_start) + assert int(delta.total_seconds()) == healthPeriod + i + wait_start = end + assert get_proxy_error() is None + + +@pytest.mark.no_parallel +@pytest.mark.minimum +def test_health_retry_disabled(accelize_drm, conf_json, cred_json, async_handler, live_server): + """ + Test the asynchronous health retry feature can be disabled. + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_health_retry_disabled' + conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + + # Set initial context on the live server + nb_health = 2 + healthPeriod = 3 + healthRetrySleep = 1 + context = {'data': list(), + 'healthPeriod':healthPeriod, + 'healthRetrySleep':healthRetrySleep + } + set_context(context) + assert get_context() == context + + drm_manager.activate() + try: + wait_func_true(lambda: len(get_context()['data']) >= nb_health, + timeout=(healthPeriod+3) * (nb_health+2)) + finally: + drm_manager.deactivate() + async_cb.assert_NoError() + data_list = get_context()['data'] + assert len(data_list) >= nb_health + # Check there is no duplicated health_id + id_list = tuple(map(lambda x: x[0], data_list)) + assert id_list == tuple(set(id_list)) + # Check the time between 2 period + wait_start = data_list.pop(0)[2] + for hid, start, end in data_list: + delta = parser.parse(start) - parser.parse(wait_start) + assert int(delta.total_seconds()) == healthPeriod + wait_start = end + assert get_proxy_error() is None + + +@pytest.mark.no_parallel +@pytest.mark.minimum +def test_health_retry_modification(accelize_drm, conf_json, cred_json, async_handler, live_server): + """ + Test the asynchronous health retry can be modified dynamically. + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_health_retry_modification' + conf_json.save() + + healthPeriod = 3 + healthRetry = 10 + healthRetrySleep = 1 + nb_run = 3 + + for i in range(nb_run): + + retry_timeout = healthRetry+5*i + + # Set initial context on the live server + context = {'data': list(), + 'healthPeriod':healthPeriod, + 'healthRetry':retry_timeout, + 'healthRetrySleep':healthRetrySleep, + 'exit':False + } + set_context(context) + assert get_context() == context + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.activate() + try: + wait_func_true(lambda: get_context()['exit'], + timeout=(retry_timeout+3) * 2) + finally: + drm_manager.deactivate() + + async_cb.assert_NoError() + data_list = get_context()['data'] + data0 = data_list.pop(0) + assert len(data_list) > 1 + assert data0[0] == 0 + # Check health_id is unchanged during the retry period + assert sum(map(lambda x: x[0], data_list)) == len(data_list) + # Check the retry period is correct + start = data_list[0][1] + end = data_list[-1][2] + delta = parser.parse(end) - parser.parse(start) + error_gap = drm_manager.get('health_retry_sleep') + 1 + assert retry_timeout - error_gap <= int(delta.total_seconds()) <= retry_timeout + error_gap + assert get_proxy_error() is None + + +@pytest.mark.no_parallel +@pytest.mark.minimum +def test_health_retry_sleep_modification(accelize_drm, conf_json, cred_json, async_handler, live_server): + """ + Test the asynchronous health retry sleep value when changed dynamically. + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_health_retry_sleep_modification' + conf_json.save() + + healthPeriod = 3 + healthRetry = 10 + healthRetrySleep = 1 + nb_run = 3 + + for i in range(nb_run): + + health_retry_sleep = healthRetrySleep + i + + # Set initial context on the live server + context = {'data': list(), + 'healthPeriod':healthPeriod, + 'healthRetry':healthRetry, + 'healthRetrySleep':health_retry_sleep, + 'exit':False + } + set_context(context) + assert get_context() == context + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.activate() + try: + wait_func_true(lambda: get_context()['exit'], + timeout=(healthRetry + healthRetry)*2) + finally: + drm_manager.deactivate() + + async_cb.assert_NoError() + data_list = get_context()['data'] + data0 = data_list.pop(0) + nb_sleep_prev = 0 + # Check the retry sleep period is correct + for health_id, group in groupby(data_list, lambda x: x[0]): + group = list(group) + assert len(group) > nb_sleep_prev + nb_sleep_prev = len(group) + start = group.pop(0)[2] + for _, lstart, lend in group: + delta = parser.parse(lstart) - parser.parse(start) + assert int(delta.total_seconds()) == health_retry_sleep + start = lend + assert get_proxy_error() is None + + +@pytest.mark.skip(reason='Asynchronous feature is still not working because of the corruption of metering data') +@pytest.mark.no_parallel +@pytest.mark.minimum +def test_health_metering_data(accelize_drm, conf_json, cred_json, async_handler, live_server, ws_admin): + """ + Test the metering data returned to the web service is correct. + """ + driver = accelize_drm.pytest_fpga_driver[0] + activators = accelize_drm.pytest_fpga_activators[0] + activators.reset_coin() + activators.autotest() + async_cb = async_handler.create() + async_cb.reset() + + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_health_metering_data' + conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + + # Set initial context on the live server + healthPeriod = 3 + healthRetry = 0 # No retry + context = {'health_id':0, + 'healthPeriod':healthPeriod, + 'healthRetry':healthRetry + } + set_context(context) + assert get_context() == context + + def wait_and_check_on_next_health(drm): + next_health_id = get_context()['health_id'] + 1 + wait_func_true(lambda: get_context()['health_id'] >= next_health_id) + session_id = drm.get('session_id') + saas_data = ws_admin.get_last_metering_information(session_id) + assert saas_data['session'] == session_id + assert saas_data['metering'] == drm.get('metered_data') + + assert not drm_manager.get('license_status') + drm_manager.activate() + try: + # First round without no unit + assert drm_manager.get('license_status') + assert drm_manager.get('metered_data') == 0 + activators[0].check_coin(drm_manager.get('metered_data')) + wait_and_check_on_next_health(drm_manager) + # Second round with 10 units + activators[0].generate_coin(10) + activators[0].check_coin(drm_manager.get('metered_data')) + wait_and_check_on_next_health(drm_manager) + # Second round with 10 more units for a total of 20 units + activators[0].generate_coin(10) + activators[0].check_coin(drm_manager.get('metered_data')) + wait_and_check_on_next_health(drm_manager) + # Third round with 80 more units for a total of 100 units + activators[0].generate_coin(80) + activators[0].check_coin(drm_manager.get('metered_data')) + wait_and_check_on_next_health(drm_manager) + assert drm_manager.get('metered_data') == 100 + finally: + drm_manager.deactivate() + assert not drm_manager.get('license_status') + assert get_proxy_error() is None + async_cb.assert_NoError() + + +@pytest.mark.skip(reason='Segment index corruption issue to be fixed') +@pytest.mark.no_parallel +def test_segment_index(accelize_drm, conf_json, cred_json, async_handler, live_server): + """ + Test the DRM Controller capacity to handle stressfully health and license requests + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_segment_index' + logpath = accelize_drm.create_log_path(whoami()) + conf_json['settings']['log_file_verbosity'] = accelize_drm.create_log_level(1) + conf_json['settings']['log_file_type'] = 1 + conf_json['settings']['log_file_path'] = logpath + conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + + # Set initial context on the live server + nb_genlic = 3 + healthPeriod = 300 + healthRetry = 0 # no retry + context = {'nb_genlic':0, + 'healthPeriod':healthPeriod, + 'healthRetry':healthRetry + } + set_context(context) + assert get_context() == context + + # First, get license duration to align health period on it + drm_manager.activate() + lic_dur = drm_manager.get('license_duration') + drm_manager.deactivate() + + # Adjust health period to license duration + healthPeriod = lic_dur + context = {'nb_genlic':0, + 'healthPeriod':healthPeriod, + 'healthRetry':healthRetry + } + set_context(context) + assert get_context() == context + + drm_manager.activate() + assert drm_manager.get('health_period') == healthPeriod + try: + wait_func_true(lambda: get_context()['nb_genlic'] >= nb_genlic, + timeout=lic_dur * nb_genlic + 2) + session_id_exp = drm_manager.get('session_id') + finally: + drm_manager.deactivate() + del drm_manager + async_cb.assert_NoError() + wait_func_true(lambda: isfile(logpath), 10) + with open(logpath, 'rt') as f: + log_content = f.read() + segment_idx_expected = 0 + for m in findall(r'"meteringFile"\s*:\s*"([^"]*)"', log_content): + assert len(m) > 0 + session_id = m[0:16] + close_flag = m[20] + segment_idx = int(m[24:32],16) + if session_id == "0000000000000000": + assert close_flag == '0' + assert segment_idx == 0 + else: + assert session_id == session_id_exp + assert segment_idx == segment_idx_expected + segment_idx_expected += 1 + if close_flag == '1': + segment_idx_expected = 0 + assert get_proxy_error() is None + remove(logpath) diff --git a/tests/test_authentication.py b/tests/test_authentication.py new file mode 100644 index 00000000..bc86f56a --- /dev/null +++ b/tests/test_authentication.py @@ -0,0 +1,202 @@ +# -*- coding: utf-8 -*- +""" +Test node-locked behavior of DRM Library. +""" +import pytest +from glob import glob +from os import remove, getpid +from os.path import getsize, isfile, dirname, join, realpath +from re import match, search, finditer, MULTILINE, IGNORECASE +from time import sleep, time +from json import loads, dumps +from datetime import datetime, timedelta +from random import randint +from multiprocessing import Process +import requests +from flask import request + +from tests.conftest import wait_func_true, wait_deadline, whoami +from tests.proxy import get_context, set_context + + +@pytest.mark.no_parallel +def test_authentication_bad_token(accelize_drm, conf_json, cred_json, async_handler, live_server): + """Test when a bad authentication token is used""" + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + + file_log_level = accelize_drm.create_log_level(3) + file_log_type = 1 + file_log_path = accelize_drm.create_log_path(whoami()) + + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_authentication_bad_token' + conf_json['settings']['log_file_verbosity'] = file_log_level + conf_json['settings']['log_file_path'] = file_log_path + conf_json['settings']['log_file_type'] = file_log_type + conf_json.save() + + # Set initial context on the live server + access_token = 'BAD_TOKEN' + context = {'access_token':access_token} + set_context(context) + assert get_context() == context + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + try: + with pytest.raises(accelize_drm.exceptions.DRMWSError) as excinfo: + drm_manager.activate() + assert search(r'Timeout on License request after \d+ attempts', str(excinfo.value)) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSError.error_code + assert drm_manager.get('token_string') == access_token + finally: + drm_manager.deactivate() + del drm_manager + wait_func_true(lambda: isfile(file_log_path), 10) + with open(file_log_path, 'rt') as f: + file_log_content = f.read() + assert search(r'\bAuthentication credentials were not provided\b', file_log_content) + async_cb.assert_NoError() + remove(file_log_path) + + +def test_authentication_validity_after_deactivation(accelize_drm, conf_json, cred_json, async_handler): + """Test authentication token is still valid after deactivate""" + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + conf_json.reset() + cred_json.set_user('accelize_accelerator_test_02') + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + try: + drm_manager.activate() + token_time_left = drm_manager.get('token_time_left') + if token_time_left <= 15: + drm_manager.deactivate() + # Wait expiration of current oauth2 token before starting test + sleep(16) + drm_manager.activate() + token_validity = drm_manager.get('token_validity') + assert token_validity > 15 + exp_token_string = drm_manager.get('token_string') + drm_manager.deactivate() + token_string = drm_manager.get('token_string') + assert token_string == exp_token_string + drm_manager.activate() + token_string = drm_manager.get('token_string') + assert token_string == exp_token_string + drm_manager.deactivate() + token_string = drm_manager.get('token_string') + assert token_string == exp_token_string + async_cb.assert_NoError() + print('Test token validity after deactivate: PASS') + finally: + drm_manager.deactivate() + + +@pytest.mark.no_parallel +@pytest.mark.hwtst +def test_authentication_token_renewal(accelize_drm, conf_json, cred_json, async_handler, live_server): + """Test a different authentication token is given after expiration""" + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + cred_json.set_user('accelize_accelerator_test_02') + + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_authentication_token_renewal' + conf_json.save() + + # Set initial context on the live server + expires_in = 6 + context = {'expires_in':expires_in} + set_context(context) + assert get_context() == context + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + try: + drm_manager.activate() + start = datetime.now() + lic_duration = drm_manager.get('license_duration') + token_string = drm_manager.get('token_string') + token_time_left = drm_manager.get('token_time_left') + sleep(token_time_left) # Wait expiration of token + # Compute expiration of license for the token to be renewed + q = int(expires_in / lic_duration) + next_lic_expiration = ((q+1) * lic_duration) % expires_in + sleep(next_lic_expiration + 5) # Wait current license expiration + assert drm_manager.get('token_string') != token_string + finally: + drm_manager.deactivate() + + +@pytest.mark.endurance +def test_authentication_endurance(accelize_drm, conf_json, cred_json, async_handler): + """Test the continuity of service for a long period""" + from random import sample + driver = accelize_drm.pytest_fpga_driver[0] + activators = accelize_drm.pytest_fpga_activators[0] + async_cb = async_handler.create() + cred_json.set_user('accelize_accelerator_test_02') + + # Get test duration + try: + test_duration = accelize_drm.pytest_params['duration'] + except: + test_duration = 14000 + print('Warning: Missing argument "duration". Using default value %d' % test_duration) + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + activators[0].generate_coin(1000) + assert not drm_manager.get('license_status') + activators[0].autotest(is_activated=False) + drm_manager.activate() + try: + lic_duration = drm_manager.get('license_duration') + assert drm_manager.get('license_status') + activators[0].autotest(is_activated=True) + activators[0].check_coin(drm_manager.get('metered_ta')) + start = datetime.now() + while True: + assert drm_manager.get('license_status') + activators[0].generate_coin(1) + activators[0].check_coin(drm_manager.get('metered_data')) + seconds_left = test_duration - (datetime.now() - start).total_seconds() + print('Remaining time: %0.1fs / current coins=%d' % (seconds_left, activators[0].metering_data)) + if seconds_left < 0: + break + sleep(60) + finally: + drm_manager.deactivate() + assert not drm_manager.get('license_status') + activators[0].autotest(is_activated=False) + print('Endurance test has completed') diff --git a/tests/test_controller_memory.py b/tests/test_controller_memory.py new file mode 100644 index 00000000..bb3c02e5 --- /dev/null +++ b/tests/test_controller_memory.py @@ -0,0 +1,215 @@ +# -*- coding: utf-8 -*- +""" +Test node-locked behavior of DRM Library. +""" +import pytest +from re import search + + +@pytest.mark.minimum +def test_wrong_drm_controller_address(accelize_drm, conf_json, cred_json, async_handler): + """Test when a wrong DRM Controller offset is given""" + async_cb = async_handler.create() + async_cb.reset() + driver = accelize_drm.pytest_fpga_driver[0] + ctrl_base_addr_backup = driver._drm_ctrl_base_addr + driver._drm_ctrl_base_addr += 0x10000 + try: + with pytest.raises(accelize_drm.exceptions.DRMCtlrError) as excinfo: + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert 'Unable to find DRM Controller registers.' in str(excinfo.value) + assert 'Please verify' in str(excinfo.value) + finally: + driver._drm_ctrl_base_addr = ctrl_base_addr_backup + + +def test_mailbox_write_overflow(accelize_drm, conf_json, cred_json, async_handler): + from random import sample + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + # Test with a null crendential file + async_cb.reset() + cred_json.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + mb_size = drm_manager.get('mailbox_size') + assert mb_size > 0 + + mb_data = sample(range(0xFFFFFFFF), mb_size + 1) + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(mailbox_data=mb_data) + assert 'Trying to write out of Mailbox memory space' in str(excinfo.value) + err_code = async_handler.get_error_code(str(excinfo.value)) + assert err_code == accelize_drm.exceptions.DRMBadArg.error_code + async_cb.assert_NoError() + + +def test_mailbox_type_error(accelize_drm, conf_json, cred_json, async_handler): + from random import sample + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + # Test with a null crendential file + async_cb.reset() + cred_json.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(mailbox_data='this is bad type') + assert 'Value must be an array of integers' in str(excinfo.value) + err_code = async_handler.get_error_code(str(excinfo.value)) + assert err_code == accelize_drm.exceptions.DRMBadArg.error_code + async_cb.assert_NoError() + + +def test_configuration_file_empty_and_corrupted_product_id(accelize_drm, conf_json, cred_json, async_handler): + """Test errors when an incorrect product ID is requested to Web Server""" + + refdesign = accelize_drm.pytest_ref_designs + driver = accelize_drm.pytest_fpga_driver[0] + fpga_image_bkp = driver.fpga_image + async_cb = async_handler.create() + cred_json.set_user('accelize_accelerator_test_02') + + try: + # Test Web Service when an empty product ID is provided + empty_fpga_image = refdesign.get_image_id('empty_product_id') + if empty_fpga_image is None: + pytest.skip("No FPGA image found for 'empty_product_id'") + driver.program_fpga(empty_fpga_image) + async_cb.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('product_info') is None + with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: + drm_manager.activate() + assert 'Metering Web Service error 400' in str(excinfo.value) + assert 'DRM WS request failed' in str(excinfo.value) + assert search(r'\\"Unknown Product ID\\" for ', str(excinfo.value)) is not None + assert 'Product ID from license request is not set' in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code + async_cb.assert_NoError() + print('Test Web Service when an empty product ID is provided: PASS') + + # Test when a misformatted product ID is provided + bad_fpga_image = refdesign.get_image_id('bad_product_id') + if bad_fpga_image is None: + pytest.skip("No FPGA image found for 'bad_product_id'") + driver.program_fpga(bad_fpga_image) + async_cb.reset() + with pytest.raises(accelize_drm.exceptions.DRMBadFormat) as excinfo: + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert 'Failed to parse Read-Only Mailbox in DRM Controller:' in str(excinfo.value) + assert search(r'Cannot parse JSON string ', str(excinfo.value)) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadFormat.error_code + async_cb.assert_NoError() + print('Test Web Service when a misformatted product ID is provided: PASS') + + finally: + # Reprogram FPGA with original image + driver.program_fpga(fpga_image_bkp) + + +@pytest.mark.skip(reason='Two concurrent objects on the same board is not supported') +def test_2_drm_manager_concurrently(accelize_drm, conf_json, cred_json, async_handler): + """Test errors when 2 DrmManager instances are used.""" + + driver = accelize_drm.pytest_fpga_driver[0] + + async_cb1 = async_handler.create() + async_cb2 = async_handler.create() + + cred_json.set_user('accelize_accelerator_test_02') + + drm_manager1 = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb1.callback + ) + + with pytest.raises(accelize_drm.exceptions.DRMBadUsage) as excinfo: + drm_manager2 = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb2.callback + ) + assert 'Another instance of the DRM Manager is currently owning the HW' in str(excinfo.value) + + +@pytest.mark.hwtst +def test_drm_manager_bist(accelize_drm, conf_json, cred_json, async_handler): + """Test register access BIST""" + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + # Test read callback error + def my_wrong_read_callback(register_offset, returned_data): + addr = register_offset + if register_offset > 0 and register_offset <= 0x40: + addr += 0x4 + return driver.read_register_callback(addr, returned_data, driver) + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + my_wrong_read_callback, + driver.write_register_callback, + async_cb.callback + ) + assert 'DRM Communication Self-Test 2 failed' in str(excinfo.value) + assert 'Please verify' in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadArg.error_code + async_cb.assert_NoError() + + # Test write callback error + def my_wrong_write_callback(register_offset, data_to_write): + return driver.write_register_callback(register_offset*2, data_to_write, driver) + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + my_wrong_write_callback, + async_cb.callback + ) + assert 'DRM Communication Self-Test 2 failed' in str(excinfo.value) + assert 'Please verify' in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadArg.error_code + async_cb.assert_NoError() diff --git a/tests/test_drm_license_error.py b/tests/test_drm_license_error.py index f945a7da..c5e093f7 100644 --- a/tests/test_drm_license_error.py +++ b/tests/test_drm_license_error.py @@ -2,24 +2,24 @@ """ Test metering and floating behaviors of DRM Library. """ +import pytest +from os import remove from time import sleep from random import randint from datetime import datetime, timedelta from re import search from json import loads, dumps -import pytest -from multiprocessing import Process -import requests - -PROXY_HOST = "127.0.0.1" +from flask import request +from requests import get, post +from tests.proxy import get_context, set_context +from tests.conftest import whoami @pytest.mark.no_parallel -def test_header_error_on_key(accelize_drm, conf_json, cred_json, async_handler, fake_server): +def test_header_error_on_key(accelize_drm, conf_json, cred_json, async_handler, live_server): """ Test a MAC error is returned if the key value in the response has been modified """ - from flask import request, redirect, Response, session driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() async_cb.reset() @@ -29,122 +29,39 @@ def test_header_error_on_key(accelize_drm, conf_json, cred_json, async_handler, activators.autotest() conf_json.reset() - url = conf_json['licensing']['url'] - proxy_port = randint(1,65535) - proxy_url = "http://%s:%s" % (PROXY_HOST, proxy_port) - conf_json['licensing']['url'] = proxy_url + conf_json['licensing']['url'] = request.url + 'test_header_error_on_key' + logpath = accelize_drm.create_log_path(whoami()) + conf_json['settings']['log_file_verbosity'] = accelize_drm.create_log_level(0) + conf_json['settings']['log_file_type'] = 1 + conf_json['settings']['log_file_path'] = logpath conf_json.save() - def proxy(context, path=''): - url_path = '%s/%s' % (context["url"],path) - if path == 'o/token/': - return redirect(url_path, code=307) - else: - context['cnt'] += 1 - request_json = request.get_json() - response = requests.post(url_path, json=request_json, headers=request.headers) - response_json = response.json() - if context['cnt'] == 1: - dna, lic_json = list(response_json['license'].items())[0] - key = lic_json['key'] - key = '1' + key[1:] if key[0] == '0' else '0' + key[1:] - response_json['license'][dna]['key'] = key - excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] - headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] - return Response(dumps(response_json), response.status_code, headers) - - context = {'url': url, 'cnt': 0} - fake_server.add_endpoint('/', 'proxy', lambda path: proxy(context, path), methods=['GET', 'POST']) - proxy_debug = accelize_drm.pytest_proxy_debug - server = Process(target=fake_server.run, args=(PROXY_HOST, proxy_port, proxy_debug)) - server.start() - try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - with pytest.raises(accelize_drm.exceptions.DRMCtlrError) as excinfo: - drm_manager.activate() - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMCtlrError.error_code - assert "License header check error" in str(excinfo.value) - async_cb.assert_NoError() - finally: - server.terminate() - server.join() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + # Set initial context on the live server + context = {'cnt':0} + set_context(context) + assert get_context() == context -@pytest.mark.skip -@pytest.mark.no_parallel -def test_mac_error_on_key(accelize_drm, conf_json, cred_json, async_handler, fake_server): - """ - Test a MAC error is returned if the key value in the response has been modified - """ - from flask import request, redirect, Response, session - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - async_cb.reset() - - activators = accelize_drm.pytest_fpga_activators[0] - activators.reset_coin() - activators.autotest() - - conf_json.reset() - url = conf_json['licensing']['url'] - proxy_port = randint(1,65535) - proxy_url = "http://%s:%s" % (PROXY_HOST, proxy_port) - conf_json['licensing']['url'] = proxy_url - conf_json.save() - - def proxy(context, path=''): - url_path = '%s/%s' % (context["url"],path) - if path == 'o/token/': - return redirect(url_path, code=307) - else: - context['cnt'] += 1 - request_json = request.get_json() - response = requests.post(url_path, json=request_json, headers=request.headers) - response_json = response.json() - if context['cnt'] == 1: - dna, lic_json = list(response_json['license'].items())[0] - key = lic_json['key'] - key = key[:-1] + '1' if key[-1] == '0' else key[:-1] + '0' - response_json['license'][dna]['key'] = key - excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] - headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] - return Response(dumps(response_json), response.status_code, headers) - - context = {'url': url, 'cnt': 0} - fake_server.add_endpoint('/', 'proxy', lambda path: proxy(context, path), methods=['GET', 'POST']) - proxy_debug = accelize_drm.pytest_proxy_debug - server = Process(target=fake_server.run, args=(PROXY_HOST, proxy_port, proxy_debug)) - server.start() - try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - with pytest.raises(accelize_drm.exceptions.DRMCtlrError) as excinfo: - drm_manager.activate() - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMCtlrError.error_code - assert "License MAC check error" in str(excinfo.value) - async_cb.assert_NoError() - finally: - server.terminate() - server.join() + with pytest.raises(accelize_drm.exceptions.DRMCtlrError) as excinfo: + drm_manager.activate() + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMCtlrError.error_code + assert "License header check error" in str(excinfo.value) + async_cb.assert_NoError() + remove(logpath) @pytest.mark.no_parallel -def test_header_error_on_licenseTimer(accelize_drm, conf_json, cred_json, async_handler, fake_server): +def test_header_error_on_licenseTimer(accelize_drm, conf_json, cred_json, async_handler, live_server): """ - Test a MAC error is returned if the licesnseTimer value in the response has been modified + Test a MAC error is returned if the licenseTimer value in the response has been modified """ - from flask import request, redirect, Response, session driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() async_cb.reset() @@ -154,148 +71,47 @@ def test_header_error_on_licenseTimer(accelize_drm, conf_json, cred_json, async_ activators.autotest() conf_json.reset() - url = conf_json['licensing']['url'] - proxy_port = randint(1,65535) - proxy_url = "http://%s:%s" % (PROXY_HOST, proxy_port) - conf_json['licensing']['url'] = proxy_url + conf_json['licensing']['url'] = request.url + 'test_header_error_on_licenseTimer' conf_json.save() - def proxy(context, path=''): - url_path = '%s/%s' % (context["url"],path) - if path == 'o/token/': - return redirect(url_path, code=307) - else: - context['cnt'] += 1 - request_json = request.get_json() - response = requests.post(url_path, json=request_json, headers=request.headers) - response_json = response.json() - if context['cnt'] == 2: - dna, lic_json = list(response_json['license'].items())[0] - timer = lic_json['licenseTimer'] - timer = '1' + timer[1:] if timer[0] == '0' else '0' + timer[1:] - response_json['license'][dna]['licenseTimer'] = timer - excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] - headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] - return Response(dumps(response_json), response.status_code, headers) - - context = {'url': url, 'cnt': 0} - fake_server.add_endpoint('/', 'proxy', lambda path: proxy(context, path), methods=['GET', 'POST']) - proxy_debug = accelize_drm.pytest_proxy_debug - server = Process(target=fake_server.run, args=(PROXY_HOST, proxy_port, proxy_debug)) - server.start() - try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - try: - drm_manager.activate() - start = datetime.now() - lic_duration = drm_manager.get('license_duration') - assert drm_manager.get('license_status') - activators.autotest(is_activated=True) - wait_period = start + timedelta(seconds=lic_duration+2) - datetime.now() - sleep(wait_period.total_seconds()) - assert not drm_manager.get('license_status') - activators.autotest(is_activated=False) - finally: - drm_manager.deactivate() - assert not drm_manager.get('license_status') - activators.autotest(is_activated=False) - assert async_cb.was_called - assert async_cb.message is not None - assert async_cb.errcode == accelize_drm.exceptions.DRMCtlrError.error_code - assert "License header check error" in async_cb.message - finally: - server.terminate() - server.join() - + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) -@pytest.mark.skip -@pytest.mark.no_parallel -def test_mac_error_on_licenseTimer(accelize_drm, conf_json, cred_json, async_handler, fake_server): - """ - Test a MAC error is returned if the licesnseTimer value in the response has been modified - """ - from flask import request, redirect, Response, session - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - async_cb.reset() + # Set initial context on the live server + context = {'cnt':0} + set_context(context) + assert get_context() == context - activators = accelize_drm.pytest_fpga_activators[0] - activators.reset_coin() - activators.autotest() - - conf_json.reset() - url = conf_json['licensing']['url'] - proxy_port = randint(1,65535) - proxy_url = "http://%s:%s" % (PROXY_HOST, proxy_port) - conf_json['licensing']['url'] = proxy_url - conf_json.save() - - def proxy(context, path=''): - url_path = '%s/%s' % (context["url"],path) - if path == 'o/token/': - return redirect(url_path, code=307) - else: - context['cnt'] += 1 - request_json = request.get_json() - response = requests.post(url_path, json=request_json, headers=request.headers) - response_json = response.json() - if context['cnt'] == 2: - dna, lic_json = list(response_json['license'].items())[0] - timer = lic_json['licenseTimer'] - timer = timer[:-1] + '1' if timer[-1] == '0' else timer[:-1] + '0' - response_json['license'][dna]['licenseTimer'] = timer - excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] - headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] - return Response(dumps(response_json), response.status_code, headers) - - context = {'url': url, 'cnt': 0} - fake_server.add_endpoint('/', 'proxy', lambda path: proxy(context, path), methods=['GET', 'POST']) - proxy_debug = accelize_drm.pytest_proxy_debug - server = Process(target=fake_server.run, args=(PROXY_HOST, proxy_port, proxy_debug)) - server.start() + drm_manager.activate() try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - try: - drm_manager.activate() - start = datetime.now() - lic_duration = drm_manager.get('license_duration') - assert drm_manager.get('license_status') - activators.autotest(is_activated=True) - wait_period = start + timedelta(seconds=lic_duration+2) - datetime.now() - sleep(wait_period.total_seconds()) - assert not drm_manager.get('license_status') - activators.autotest(is_activated=False) - finally: - drm_manager.deactivate() - assert not drm_manager.get('license_status') - activators.autotest(is_activated=False) - assert async_cb.was_called - assert async_cb.message is not None - assert async_cb.errcode == accelize_drm.exceptions.DRMCtlrError.error_code - assert "License MAC check error" in async_cb.message + start = datetime.now() + lic_duration = drm_manager.get('license_duration') + assert drm_manager.get('license_status') + activators.autotest(is_activated=True) + wait_period = start + timedelta(seconds=lic_duration+2) - datetime.now() + sleep(wait_period.total_seconds()) + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) finally: - server.terminate() - server.join() + drm_manager.deactivate() + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) + assert async_cb.was_called + assert async_cb.message is not None + assert async_cb.errcode == accelize_drm.exceptions.DRMCtlrError.error_code + assert "License header check error" in async_cb.message @pytest.mark.no_parallel -def test_session_id_error(accelize_drm, conf_json, cred_json, async_handler, fake_server): +def test_session_id_error(accelize_drm, conf_json, cred_json, async_handler, live_server): """ Test an error is returned if a wrong session id is provided """ - from flask import request, redirect, Response, session driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() async_cb.reset() @@ -305,83 +121,52 @@ def test_session_id_error(accelize_drm, conf_json, cred_json, async_handler, fak activators.autotest() conf_json.reset() - url = conf_json['licensing']['url'] - proxy_port = randint(1,65535) - proxy_url = "http://%s:%s" % (PROXY_HOST, proxy_port) - conf_json['licensing']['url'] = proxy_url + conf_json['licensing']['url'] = request.url + 'test_session_id_error' conf_json.save() - def proxy(context, path=''): - url_path = '%s/%s' % (context["url"],path) - if path == 'o/token/': - return redirect(url_path, code=307) - else: - excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] - request_json = request.get_json() - response = requests.post(url_path, json=request_json, headers=request.headers) - response_json = response.json() - response_session_id = response_json['metering']['sessionId'] - if context['session_id'] != response_session_id: - context['session_cnt'] += 1 - context['request_cnt'] = 0 - context['request_cnt'] += 1 - context['session_id'] = response_session_id - if context['session_cnt'] == 2: - if context['request_cnt'] == 2: - response = context['replay'] - headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] - return Response(response.content, response.status_code, headers) - else: - headers = [(name, value) for (name, value) in response.raw.headers.items() if name.lower() not in excluded_headers] - if context['request_cnt'] == 2: - context['replay'] = response - return Response(response.content, response.status_code, headers) - - context = {'url':url, 'session_id':None, 'session_cnt':0, 'request_cnt':0} - fake_server.add_endpoint('/', 'proxy', lambda path: proxy(context, path), methods=['GET', 'POST']) - proxy_debug = accelize_drm.pytest_proxy_debug - server = Process(target=fake_server.run, args=(PROXY_HOST, proxy_port, proxy_debug)) - server.start() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + + # Set initial context on the live server + context = {'session_id':'0', 'session_cnt':0, 'request_cnt':0} + set_context(context) + assert get_context() == context + + # Start session #1 to record + drm_manager.activate() + start = datetime.now() try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - try: - # Start session #1 - drm_manager.activate() - start = datetime.now() - lic_duration = drm_manager.get('license_duration') - assert drm_manager.get('license_status') - activators.autotest(is_activated=True) - wait_period = start + timedelta(seconds=lic_duration/2) - datetime.now() - sleep(wait_period.total_seconds()) - finally: - drm_manager.deactivate() - assert not drm_manager.get('license_status') - activators.autotest(is_activated=False) - async_cb.assert_NoError() - try: - # Start session #2 - drm_manager.activate() - start = datetime.now() - assert drm_manager.get('license_status') - activators.autotest(is_activated=True) - lic_duration = drm_manager.get('license_duration') - wait_period = start + timedelta(seconds=lic_duration+2) - datetime.now() - sleep(wait_period.total_seconds()) - assert not drm_manager.get('license_status') - activators.autotest(is_activated=False) - finally: - drm_manager.deactivate() - assert async_cb.was_called - assert async_cb.message is not None - assert async_cb.errcode == accelize_drm.exceptions.DRMCtlrError.error_code - assert "License header check error" in async_cb.message + lic_duration = drm_manager.get('license_duration') + assert drm_manager.get('license_status') + activators.autotest(is_activated=True) + wait_period = start + timedelta(seconds=lic_duration+2) - datetime.now() + sleep(wait_period.total_seconds()) + assert drm_manager.get('license_status') finally: - server.terminate() - server.join() - + drm_manager.deactivate() + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) + async_cb.assert_NoError() + + # Start session #2 to replay session #1 + drm_manager.activate() + start = datetime.now() + try: + assert drm_manager.get('license_status') + activators.autotest(is_activated=True) + lic_duration = drm_manager.get('license_duration') + wait_period = start + timedelta(seconds=lic_duration+2) - datetime.now() + sleep(wait_period.total_seconds()) + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) + finally: + drm_manager.deactivate() + assert async_cb.was_called + assert async_cb.message is not None + assert async_cb.errcode == accelize_drm.exceptions.DRMCtlrError.error_code + assert "License header check error" in async_cb.message diff --git a/tests/test_entitlement.py b/tests/test_entitlement.py new file mode 100644 index 00000000..aefd7717 --- /dev/null +++ b/tests/test_entitlement.py @@ -0,0 +1,200 @@ +# -*- coding: utf-8 -*- +""" +Test node-locked behavior of DRM Library. +""" +import pytest +from re import search + + +@pytest.mark.minimum +@pytest.mark.hwtst +@pytest.mark.no_parallel +def test_users_entitlements(accelize_drm, conf_json, cred_json, async_handler, ws_admin): + """ + Test the entitlements for all accounts used in regression + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + print() + + # Test user-01 entitlements + # Request metering license + async_cb.reset() + cred_json.set_user('accelize_accelerator_test_01') + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('license_type') == 'Floating/Metering' + drmLicType = drm_manager.get('drm_license_type') + with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: + drm_manager.activate() + assert "Metering Web Service error 400" in str(excinfo.value) + assert "DRM WS request failed" in str(excinfo.value) + assert search(r'\\"No Entitlement\\" with .+ for \S+_test_01@accelize.com', str(excinfo.value)) + assert "User account has no entitlement. Purchase additional licenses via your portal" in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code + async_cb.assert_NoError() + # Request nodelock license + try: + async_cb.reset() + cred_json.set_user('accelize_accelerator_test_01') + conf_json.reset() + conf_json.addNodelock() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('license_type') == 'Node-Locked' + assert drm_manager.get('drm_license_type') == drmLicType + with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: + drm_manager.activate() + assert "Metering Web Service error 400" in str(excinfo.value) + assert "DRM WS request failed" in str(excinfo.value) + assert search(r'\\"No Entitlement\\" with .+ for \S+_test_01@accelize.com', str(excinfo.value)) + assert "User account has no entitlement. Purchase additional licenses via your portal" in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code + async_cb.assert_NoError() + finally: + accelize_drm.clean_nodelock_env(conf_json=conf_json) + print('Test user-01 entitlements: PASS') + + # Test user-02 entitlements + # Request metering license + async_cb.reset() + cred_json.set_user('accelize_accelerator_test_02') + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('license_type') == 'Floating/Metering' + assert drm_manager.get('drm_license_type') == drmLicType + drm_manager.activate() + assert drm_manager.get('drm_license_type') == 'Floating/Metering' + drm_manager.deactivate() + async_cb.assert_NoError() + # Request nodelock license + try: + async_cb.reset() + conf_json.reset() + conf_json.addNodelock() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('license_type') == 'Node-Locked' + assert drm_manager.get('drm_license_type') == 'Floating/Metering' + with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: + drm_manager.activate() + assert "Metering Web Service error 400" in str(excinfo.value) + assert "DRM WS request failed" in str(excinfo.value) + assert search(r'\\"No Entitlement\\" with .+ for \S+_test_02@accelize.com', str(excinfo.value)) + assert 'No valid NodeLocked entitlement found for your account' in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code + async_cb.assert_NoError() + finally: + accelize_drm.clean_nodelock_env(conf_json=conf_json) + print('Test user-02 entitlements: PASS') + + # Test user-03 entitlements + # Request metering license + cred_json.set_user('accelize_accelerator_test_03') + async_cb.reset() + conf_json.reset() + accelize_drm.clean_metering_env(cred_json, ws_admin) + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('license_type') == 'Floating/Metering' + assert drm_manager.get('drm_license_type') == 'Floating/Metering' + drm_manager.activate() + assert drm_manager.get('drm_license_type') == 'Floating/Metering' + drm_manager.deactivate() + async_cb.assert_NoError() + # Request nodelock license + try: + async_cb.reset() + conf_json.reset() + conf_json.addNodelock() + accelize_drm.clean_nodelock_env(None, driver, conf_json, cred_json, ws_admin) + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('license_type') == 'Node-Locked' + # Start application + assert drm_manager.get('drm_license_type') == 'Idle' + drm_manager.activate() + assert drm_manager.get('drm_license_type') == 'Node-Locked' + drm_manager.deactivate() + async_cb.assert_NoError() + finally: + accelize_drm.clean_nodelock_env(drm_manager, driver, conf_json, cred_json, ws_admin) + print('Test user-03 entitlements: PASS') + + # Test user-04 entitlements + # Request metering license + cred_json.set_user('accelize_accelerator_test_04') + async_cb.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.set(log_verbosity=1) + assert drm_manager.get('license_type') == 'Floating/Metering' + assert drm_manager.get('drm_license_type') == 'Idle' + drm_manager.activate() + assert drm_manager.get('drm_license_type') == 'Floating/Metering' + drm_manager.deactivate() + async_cb.assert_NoError() + # Request nodelock license + try: + async_cb.reset() + conf_json.reset() + conf_json.addNodelock() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('license_type') == 'Node-Locked' + assert drm_manager.get('drm_license_type') == 'Floating/Metering' + with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: + drm_manager.activate() + assert "Metering Web Service error 400" in str(excinfo.value) + assert "DRM WS request failed" in str(excinfo.value) + assert search(r'\\"No Entitlement\\" with .+ for \S+_test_04@accelize.com', str(excinfo.value)) + assert 'No valid NodeLocked entitlement found for your account' in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code + async_cb.assert_NoError() + finally: + accelize_drm.clean_nodelock_env(conf_json=conf_json) + print('Test user-04 entitlements: PASS') diff --git a/tests/test_environment_variable.py b/tests/test_environment_variable.py new file mode 100644 index 00000000..a142d9ec --- /dev/null +++ b/tests/test_environment_variable.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +""" +Test environment variables behavior to set parameters of the DRM Library. +""" +import pytest +from os import environ + + +def test_env_var_ONEPORTAL_URL(accelize_drm, conf_json, cred_json, async_handler): + """ + Test ONEPORTAL_URL environment variable overwrite value in config file + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + # Check when ONEPORTAL_URL is set + environ['ONEPORTAL_URL'] = conf_json['licensing']['url'] + conf_json['licensing']['url'] = 'http://acme.com' + conf_json.save() + assert conf_json['licensing']['url'] != environ['ONEPORTAL_URL'] + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.activate() + drm_manager.deactivate() + async_cb.assert_NoError() + + # Check when ONEPORTAL_URL is unset + del environ['ONEPORTAL_URL'] + assert 'ONEPORTAL_URL' not in environ.keys() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: + drm_manager.activate() + assert "OAuth2 Web Service error 404" in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code + async_cb.assert_NoError() + + +def test_env_var_ONEPORTAL_CLIENT_ID(accelize_drm, conf_json, cred_json, async_handler): + """ + Test ONEPORTAL_CLIENT_ID environment variable overwrite value in cred file + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + # Check when ONEPORTAL_CLIENT_ID is set + environ['ONEPORTAL_CLIENT_ID'] = cred_json['client_id'] + cred_json['client_id'] = 'acme_is_a_great_company' + cred_json.save() + assert cred_json['client_id'] != environ['ONEPORTAL_CLIENT_ID'] + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.activate() + drm_manager.deactivate() + async_cb.assert_NoError() + + # Check when ONEPORTAL_CLIENT_ID is unset + del environ['ONEPORTAL_CLIENT_ID'] + assert 'ONEPORTAL_CLIENT_ID' not in environ.keys() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: + drm_manager.activate() + assert "OAuth2 Web Service error 401" in str(excinfo.value) + assert "invalid_client" in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code + async_cb.assert_NoError() diff --git a/tests/test_frequency_detection.py b/tests/test_frequency_detection.py new file mode 100644 index 00000000..81cfb4b7 --- /dev/null +++ b/tests/test_frequency_detection.py @@ -0,0 +1,298 @@ +# -*- coding: utf-8 -*- +""" +Test frequency detetion mechanism. +""" +import pytest +from os import remove, getpid +from os.path import isfile, realpath +from time import sleep, time +from re import search + +from tests.conftest import wait_func_true, whoami + + +def test_configuration_file_with_bad_frequency(accelize_drm, conf_json, cred_json, async_handler): + """Test errors when wrong frequency is given to DRM Controller Constructor""" + from math import ceil, floor + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + cred_json.set_user('accelize_accelerator_test_02') + conf_json.reset() + + # Before any test, get the real DRM frequency and the gap threshold + async_cb.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + freq_threshold = drm_manager.get('frequency_detection_threshold') + freq_period = drm_manager.get('frequency_detection_period') + drm_manager.activate() + sleep(2) + frequency = drm_manager.get('drm_frequency') + drm_manager.deactivate() + + # Test no error is returned by asynchronous error callback when the frequency + # in configuration file differs from the DRM frequency by less than the threshold + async_cb.reset() + conf_json.reset() + conf_json['drm']['frequency_mhz'] = int(floor(frequency * (100.0 + freq_threshold/2) / 100.0)) + conf_json.save() + assert abs(conf_json['drm']['frequency_mhz'] - frequency) * 100.0 / frequency < freq_threshold + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.activate() + sleep(2) + drm_manager.deactivate() + async_cb.assert_NoError('freq_period=%d ms, freq_threshold=%d%%, frequency=%d MHz' + % (freq_period, freq_threshold, frequency)) + print('Test frequency mismatch < threshold: PASS') + + # Test a BADFrequency error is returned by asynchronous error callback when the frequency + # in configuration file differs from the DRM frequency by more than the threshold + async_cb.reset() + conf_json.reset() + conf_json['drm']['frequency_mhz'] = int(ceil(frequency * (100.0 + 2*freq_threshold) / 100.0)) + assert abs(conf_json['drm']['frequency_mhz'] - frequency) * 100.0 / frequency > freq_threshold + conf_json.save() + + if accelize_drm.pytest_new_freq_method_supported: + with pytest.raises(accelize_drm.exceptions.DRMBadFrequency) as excinfo: + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert search(r'DRM frequency .* differs from .* configuration file', + str(excinfo.value)) is not None + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadFrequency.error_code + else: + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.activate() + sleep(1) + drm_manager.deactivate() + assert async_cb.was_called, 'Asynchronous callback NOT called' + assert async_cb.message is not None, 'Asynchronous callback did not report any message' + assert search(r'DRM frequency .* differs from .* configuration file', + async_cb.message) is not None, 'Unexpected message reported by asynchronous callback' + assert async_cb.errcode == accelize_drm.exceptions.DRMBadFrequency.error_code, \ + 'Unexpected error code reported by asynchronous callback' + print('Test frequency mismatch > threshold: PASS') + + # Test web service detects a frequency underflow + async_cb.reset() + conf_json.reset() + conf_json['drm']['bypass_frequency_detection'] = True + conf_json['drm']['frequency_mhz'] = 40 + conf_json.save() + assert conf_json['drm']['frequency_mhz'] == 40 + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback + ) + with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: + drm_manager.activate() + assert 'Metering Web Service error 400' in str(excinfo.value) + assert 'Ensure this value is greater than or equal to 50' in str(excinfo.value) + err_code = async_handler.get_error_code(str(excinfo.value)) + assert err_code == accelize_drm.exceptions.DRMWSReqError.error_code + print('Test frequency underflow: PASS') + + # Test web service detects a frequency overflow + async_cb.reset() + conf_json.reset() + conf_json['drm']['bypass_frequency_detection'] = True + conf_json['drm']['frequency_mhz'] = 400 + conf_json.save() + assert conf_json['drm']['frequency_mhz'] == 400 + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback + ) + with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: + drm_manager.activate() + assert 'Metering Web Service error 400' in str(excinfo.value) + assert 'Ensure this value is less than or equal to 320' in str(excinfo.value) + err_code = async_handler.get_error_code(str(excinfo.value)) + assert err_code == accelize_drm.exceptions.DRMWSReqError.error_code + print('Test frequency overflow: PASS') + + +@pytest.mark.minimum +def test_drm_manager_frequency_detection_method1(accelize_drm, conf_json, cred_json, async_handler): + """Test method1 (based on dedicated counter in AXI wrapper) to estimate drm frequency is working""" + + if not accelize_drm.pytest_new_freq_method_supported: + pytest.skip("New frequency detection method is not supported: test skipped") + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + conf_json.reset() + logpath = accelize_drm.create_log_path(whoami()) + conf_json['settings']['log_file_verbosity'] = accelize_drm.create_log_level(1) + conf_json['settings']['log_file_type'] = 1 + conf_json['settings']['log_file_path'] = logpath + conf_json.save() + if isfile(logpath): + remove(logpath) + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('frequency_detection_method') == 1 + del drm_manager + wait_func_true(lambda: isfile(logpath), 10) + with open(logpath, 'rt') as f: + log_content = f.read() + assert "Use dedicated counter to compute DRM frequency (method 1)" in log_content + remove(logpath) + + +def test_drm_manager_frequency_detection_method1_exception(accelize_drm, conf_json, cred_json, async_handler): + """Test method1 (based on dedicated counter in AXI wrapper) to estimate drm frequency is working""" + + if not accelize_drm.pytest_new_freq_method_supported: + pytest.skip("New frequency detection method is not supported: test skipped") + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + conf_json.reset() + conf_json['settings']['frequency_detection_period'] = (int)(2**32 / 125000000 * 1000) + 2 + conf_json.save() + with pytest.raises(accelize_drm.exceptions.DRMBadFrequency) as excinfo: + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert search(r'Frequency auto-detection failed: frequency_detection_period parameter \([^)]+\) is too long', + str(excinfo.value)) is not None + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadFrequency.error_code + async_cb.assert_NoError() + + +@pytest.mark.minimum +def test_drm_manager_frequency_detection_method2(accelize_drm, conf_json, cred_json, async_handler): + """Test method2 (based on license timer) to estimate drm frequency is still working""" + + refdesign = accelize_drm.pytest_ref_designs + driver = accelize_drm.pytest_fpga_driver[0] + fpga_image_bkp = driver.fpga_image + async_cb = async_handler.create() + + # Program FPGA with HDK 3.x.x (with frequency detection method 2) + hdk = list(filter(lambda x: x.startswith('3.'), refdesign.hdk_versions))[-1] + assert hdk.startswith('3.') + image_id = refdesign.get_image_id(hdk) + logpath = accelize_drm.create_log_path(whoami()) + if isfile(logpath): + remove(logpath) + try: + driver.program_fpga(image_id) + conf_json.reset() + conf_json['settings']['log_file_verbosity'] = accelize_drm.create_log_level(1) + conf_json['settings']['log_file_type'] = 1 + conf_json['settings']['log_file_path'] = logpath + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('frequency_detection_method') == 2 + drm_manager.activate() + assert drm_manager.get('frequency_detection_method') == 2 + drm_manager.deactivate() + del drm_manager + wait_func_true(lambda: isfile(logpath), 10) + with open(logpath, 'rt') as f: + log_content = f.read() + assert "Use license timer counter to compute DRM frequency (method 2)" in log_content + remove(logpath) + finally: + # Reprogram FPGA with original image + driver.program_fpga(fpga_image_bkp) + + +def test_drm_manager_frequency_detection_bypass(accelize_drm, conf_json, cred_json, async_handler): + """Test bypass of frequency detection""" + + if not accelize_drm.pytest_new_freq_method_supported: + pytest.skip("New frequency detection method is not supported: test skipped") + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + # Test when bypass = True + conf_json.reset() + conf_json['drm']['bypass_frequency_detection'] = True + conf_json['drm']['frequency_mhz'] = 80 + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('drm_frequency') == 80 + drm_manager.activate() + try: + sleep(1) + assert drm_manager.get('drm_frequency') == 80 + except: + drm_manager.deactivate() + async_cb.assert_NoError() + print('Test bypass_frequency_detection=true: PASS') + + # Test when bypass = False + conf_json.reset() + conf_json['drm']['frequency_mhz'] = 80 + conf_json.save() + with pytest.raises(accelize_drm.exceptions.DRMBadFrequency) as excinfo: + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert search(r'DRM frequency .* differs from .* configuration file', + str(excinfo.value)) is not None + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadFrequency.error_code + async_cb.assert_NoError() + print('Test bypass_frequency_detection=false: PASS') diff --git a/tests/test_function_arguments.py b/tests/test_function_arguments.py index 6c1d31f4..ba2237b8 100644 --- a/tests/test_function_arguments.py +++ b/tests/test_function_arguments.py @@ -2,19 +2,19 @@ """ Test DRM Library with bad arguments. Make sure errors are detected and reported as expected. """ -from re import search - import pytest +from re import search def test_drm_manager_constructor_with_bad_arguments(accelize_drm, conf_json, cred_json, - async_handler): + async_handler, tmpdir): """Test errors when missing arguments are given to DRM Controller Constructor""" + from os.path import isdir driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() - # Test when no configuration file is given + # Test when unexisting configuration file is given with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: accelize_drm.DrmManager( "wrong_path_to_conf.json", @@ -23,11 +23,10 @@ def test_drm_manager_constructor_with_bad_arguments(accelize_drm, conf_json, cre driver.write_register_callback, async_cb.callback ) - assert 'Cannot find JSON file' in str(excinfo.value) - print('Test when no configuration file is given: PASS') + assert 'Path is not a valid file:' in str(excinfo.value) + print('Test when unexisting configuration file is given: PASS') - # Test when no credentials file is given - conf_json.reset() + # Test when unexisting credentials file is given with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: accelize_drm.DrmManager( conf_json.path, @@ -36,11 +35,38 @@ def test_drm_manager_constructor_with_bad_arguments(accelize_drm, conf_json, cre driver.write_register_callback, async_cb.callback ) - assert 'Cannot find JSON file' in str(excinfo.value) - print('Test when no credentials file is given: PASS') + assert 'Path is not a valid file:' in str(excinfo.value) + print('Test when unexisting credentials file is given: PASS') + + # Test when configuration path is a directory + tmp_dir = str(tmpdir) + assert isdir(tmp_dir) + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + accelize_drm.DrmManager( + tmp_dir, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert 'Path is not a valid file:' in str(excinfo.value) + print('Test when configuration path is a directory: PASS') + + # Test when credentials path is a directory + tmp_dir = str(tmpdir) + assert isdir(tmp_dir) + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + accelize_drm.DrmManager( + conf_json.path, + tmp_dir, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert 'Path is not a valid file:' in str(excinfo.value) + print('Test when credentials path is a directory: PASS') # Test when no hardware read register function is given - conf_json.reset() with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: accelize_drm.DrmManager( conf_json.path, @@ -53,7 +79,6 @@ def test_drm_manager_constructor_with_bad_arguments(accelize_drm, conf_json, cre print('Test when no hardware read register function is given: PASS') # Test when no hardware write register function is given - conf_json.reset() with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: accelize_drm.DrmManager( conf_json.path, @@ -65,7 +90,6 @@ def test_drm_manager_constructor_with_bad_arguments(accelize_drm, conf_json, cre print('Test when no hardware write register function is given: PASS') # Test when read register function is not a callable - conf_json.reset() with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: accelize_drm.DrmManager( conf_json.path, @@ -78,7 +102,6 @@ def test_drm_manager_constructor_with_bad_arguments(accelize_drm, conf_json, cre print('Test when read register function is not a callable: PASS') # Test when write register function is not a callable - conf_json.reset() with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: accelize_drm.DrmManager( conf_json.path, @@ -91,7 +114,6 @@ def test_drm_manager_constructor_with_bad_arguments(accelize_drm, conf_json, cre print('Test when write register function is not a callable: PASS') # Test when asynchronous error function is not a callable - conf_json.reset() with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: accelize_drm.DrmManager( conf_json.path, @@ -110,25 +132,6 @@ def test_drm_manager_with_bad_configuration_file(accelize_drm, conf_json, cred_j driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() - # Test with a null configuration file - async_cb.reset() - conf_json.reset() - conf_json._content = None - conf_json.save() - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert search(r'JSON file .* is empty', str(excinfo.value)) is not None - errcode = async_handler.get_error_code(str(excinfo.value)) - assert errcode == accelize_drm.exceptions.DRMBadArg.error_code - async_cb.assert_NoError() - print('Test null config file: PASS') - # Test with an empty configuration file async_cb.reset() conf_json.reset() @@ -418,28 +421,9 @@ def test_drm_manager_with_bad_credential_file(accelize_drm, conf_json, cred_json driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() - - # Test with a null crendential file async_cb.reset() - cred_json.reset() - cred_json._content = None - cred_json.save() - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert search(r'JSON file .* is empty', str(excinfo.value)) is not None - errcode = async_handler.get_error_code(str(excinfo.value)) - assert errcode == accelize_drm.exceptions.DRMBadArg.error_code - async_cb.assert_NoError() - print('Test null crendential file: PASS') - + # Test with an empty crendential file - async_cb.reset() cred_json.reset() cred_json._content = {} cred_json.save() @@ -563,3 +547,54 @@ def test_drm_manager_get_and_set_bad_arguments(accelize_drm, conf_json, cred_jso err_code = async_handler.get_error_code(str(excinfo.value)) assert err_code == accelize_drm.exceptions.DRMBadArg.error_code print("Test when bad argument is given to set: PASS") + + +@pytest.mark.aws +def test_c_unittests(accelize_drm, exec_func): + """Test errors when missing arguments are given to DRM Controller Constructor""" + driver = accelize_drm.pytest_fpga_driver[0] + if 'aws' not in accelize_drm.pytest_fpga_driver_name: + pytest.skip("C unit-tests are only supported with AWS driver.") + + exec_lib = exec_func.load('unittests', driver._fpga_slot_id) + + # Test when read register callback is null + exec_lib.run('test_null_read_callback') + assert exec_lib.returncode == accelize_drm.exceptions.DRMBadArg.error_code + assert 'Read register callback function must not be NULL' in exec_lib.stdout + assert exec_lib.asyncmsg is None + + # Test when write register callback is null + exec_lib.run('test_null_write_callback') + assert exec_lib.returncode == accelize_drm.exceptions.DRMBadArg.error_code + assert 'Write register callback function must not be NULL' in exec_lib.stdout + assert exec_lib.asyncmsg is None + + # Test when asynchronous error callback is null + exec_lib.run('test_null_error_callback') + assert exec_lib.returncode == accelize_drm.exceptions.DRMBadArg.error_code + assert 'Asynchronous error callback function must not be NULL' in exec_lib.stdout + assert exec_lib.asyncmsg is None + + # Test various types of get and set functions + exec_lib.run('test_types_of_get_and_set_functions') + assert exec_lib.returncode == 0 + assert exec_lib.asyncmsg is None + + # Test out of range of get function + exec_lib.run('test_get_function_out_of_range') + assert exec_lib.returncode == accelize_drm.exceptions.DRMBadArg.error_code + assert 'Cannot find parameter with ID: ' in exec_lib.stdout + assert exec_lib.asyncmsg is None + + # Test get_json_string with bad format + exec_lib.run('test_get_json_string_with_bad_format') + assert exec_lib.returncode == accelize_drm.exceptions.DRMBadFormat.error_code + assert 'Cannot parse JSON string ' in exec_lib.stdout + assert exec_lib.asyncmsg is None + + # Test get_json_string with empty string + exec_lib.run('test_get_json_string_with_empty_string') + assert exec_lib.returncode == accelize_drm.exceptions.DRMBadFormat.error_code + assert 'Cannot parse an empty JSON string' in exec_lib.stdout + assert exec_lib.asyncmsg is None diff --git a/tests/test_hdk_compatibility.py b/tests/test_hdk_compatibility.py new file mode 100644 index 00000000..9316cb89 --- /dev/null +++ b/tests/test_hdk_compatibility.py @@ -0,0 +1,186 @@ +# -*- coding: utf-8 -*- +""" +Test node-locked behavior of DRM Library. +""" +import pytest +from os import remove +from itertools import groupby +from re import match, search, IGNORECASE +from tests.conftest import whoami + + +def test_hdk_stability_on_programming(accelize_drm, conf_json, cred_json, async_handler): + """Test reprogramming multiple times does not produce any issue""" + driver = accelize_drm.pytest_fpga_driver[0] + image_id = driver.fpga_image + async_cb = async_handler.create() + async_cb.reset() + drm_manager = None + + conf_json.reset() + logpath = accelize_drm.create_log_path(whoami()) + conf_json['settings']['log_file_verbosity'] = accelize_drm.create_log_level(0) + conf_json['settings']['log_file_type'] = 1 + conf_json['settings']['log_file_path'] = logpath + conf_json['settings']['log_file_append'] = True + conf_json.save() + + nb_reset = 10 + for i in range(nb_reset): + # Program FPGA with lastest HDK per major number + driver.program_fpga(image_id) + + # Test no compatibility issue + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert not drm_manager.get('license_status') + try: + drm_manager.activate() + assert drm_manager.get('license_status') + finally: + drm_manager.deactivate() + assert not drm_manager.get('license_status') + async_cb.assert_NoError() + remove(logpath) + + +@pytest.mark.minimum +def test_uncompatibilities(accelize_drm, conf_json, cred_json, async_handler): + """Test API is not compatible with DRM HDK inferior major number""" + refdesign = accelize_drm.pytest_ref_designs + hdk_version = accelize_drm.pytest_hdk_version + if hdk_version is None: + pytest.skip("No HDK version found with FPGA image") + + driver = accelize_drm.pytest_fpga_driver[0] + fpga_image_bkp = driver.fpga_image + async_cb = async_handler.create() + async_cb.reset() + drm_manager = None + + try: + # First instanciate an object to get the HDK compatbility version + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + try: + HDK_Limit = float(drm_manager.get('hdk_compatibility')) + except: + HDK_Limit = 3.1 + + # Then test all HDK versions that are not compatible + current_num = float(match(r'^(\d+.\d+)', hdk_version).group(1)) + refdesignByMajor = ((float(match(r'^(\d+.\d+)', x).group(1)), x) for x in refdesign.hdk_versions) + + tested = False + + for num, versions in groupby(refdesignByMajor, lambda x: x[0]): + if HDK_Limit <= num and num <= current_num: + print('Test uncompatible HDK: HDK version %s is in the compatiblity range[%s : %s]: skip version' % (num, HDK_Limit, current_num)) + continue + tested = True + + print('Testing HDK version %s is not compatible ...' % num) + # Program FPGA with older HDK + hdk = sorted((e[1] for e in versions))[0] + image_id = refdesign.get_image_id(hdk) + driver.program_fpga(image_id) + + # Test compatibility issue + with pytest.raises(accelize_drm.exceptions.DRMCtlrError) as excinfo: + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + hit = False + if 'Unable to find DRM Controller registers' in str(excinfo.value): + hit =True + if search(r'This DRM Library version \S+ is not compatible with the DRM HDK version', str(excinfo.value), IGNORECASE): + hit =True + assert hit + assert tested + + finally: + if drm_manager: + del drm_manager + # Reprogram FPGA with original image + driver.program_fpga(fpga_image_bkp) + + +@pytest.mark.minimum +def test_compatibilities(accelize_drm, conf_json, cred_json, async_handler): + """Test API is compatible with DRM HDK with the same major number""" + refdesign = accelize_drm.pytest_ref_designs + hdk_version = accelize_drm.pytest_hdk_version + if hdk_version is None: + pytest.skip("FPGA image is not corresponding to a known HDK version") + + driver = accelize_drm.pytest_fpga_driver[0] + fpga_image_bkp = driver.fpga_image + async_cb = async_handler.create() + async_cb.reset() + drm_manager = None + + try: + # First instanciate an object to get the HDK compatbility version + try: + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + HDK_Limit = float(drm_manager.get('hdk_compatibility')) + except: + HDK_Limit = 3.1 + + # Then test all HDK versions that are compatible + current_num = float(match(r'^(\d+.\d+)', hdk_version).group(1)) + refdesignByMajor = ((float(match(r'^(\d+.\d+)', x).group(1)), x) for x in refdesign.hdk_versions) + tested = False + + for num, versions in groupby(refdesignByMajor, lambda x: x[0]): + if num < HDK_Limit or num > current_num: + print('Test compatible HDK: HDK version %s is not in the range ]%s : %s[: skip version' % (num, HDK_Limit, current_num)) + continue + tested = True + + print('Testing HDK version %s is compatible ...' % num) + # Program FPGA with lastest HDK per major number + hdk = sorted((e[1] for e in versions))[-1] + image_id = refdesign.get_image_id(hdk) + driver.program_fpga(image_id) + + # Test no compatibility issue + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert not drm_manager.get('license_status') + drm_manager.activate() + assert drm_manager.get('license_status') + drm_manager.deactivate() + assert not drm_manager.get('license_status') + async_cb.assert_NoError() + assert tested + finally: + if drm_manager: + del drm_manager + # Reprogram FPGA with original image + driver.program_fpga(fpga_image_bkp) diff --git a/tests/test_host_card_info.py b/tests/test_host_card_info.py new file mode 100644 index 00000000..296bdb9a --- /dev/null +++ b/tests/test_host_card_info.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +""" +Test host and card information releated feature +""" +import pytest +from os import environ + + +def test_host_data_verbosity(accelize_drm, conf_json, cred_json, async_handler): + """ + Test all supported verbosity + """ + if 'XRT_PATH' not in environ: + pytest.skip("XRT_PATH is not defined: skip host and card tests") + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + conf_json.reset() + + # Get full data + conf_json['settings']['host_data_verbosity'] = 0 + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('host_data_verbosity') == 0 + data_full = drm_manager.get('host_data') + assert type(data_full) == dict + assert len(data_full) + async_cb.assert_NoError() + + # Get partial data + conf_json['settings']['host_data_verbosity'] = 1 + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('host_data_verbosity') == 1 + data_partial = drm_manager.get('host_data') + assert type(data_partial) == dict + assert len(data_partial) + + # Get none data + conf_json['settings']['host_data_verbosity'] = 2 + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('host_data_verbosity') == 2 + data_none = drm_manager.get('host_data') + assert type(data_none) == type(None) + assert len(data_full) > len(data_partial) > 0 + + +def test_format(accelize_drm, conf_json, cred_json, async_handler): + """ + Test the format in the request is as expected + """ + if 'XRT_PATH' not in environ: + pytest.skip("XRT_PATH is not defined: skip host and card tests") + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + conf_json.reset() + conf_json['settings']['host_data_verbosity'] = 0 + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('host_data_verbosity') == 0 + data = drm_manager.get('host_data') + assert type(data) == dict + assert len(data) + assert 'board' in data.keys() + assert 'error' in data['board'].keys() + assert 'info' in data['board'].keys() + assert 'dsa_name' in data['board']['info'].keys() + assert 'xclbin' in data['board'].keys() + assert 'runtime' in data.keys() + assert 'system' in data.keys() + async_cb.assert_NoError() diff --git a/tests/test_lgdn_topics.py b/tests/test_lgdn_topics.py new file mode 100644 index 00000000..8d274854 --- /dev/null +++ b/tests/test_lgdn_topics.py @@ -0,0 +1,132 @@ +# -*- coding: utf-8 -*- +""" +Test metering and floating behaviors of DRM Library. +""" +import pytest +from time import sleep +from random import randint +from datetime import datetime +from itertools import groupby +from re import match +from flask import request + +from tests.conftest import wait_deadline, wait_func_true +from tests.proxy import get_context, set_context + + +@pytest.mark.no_parallel +@pytest.mark.lgdn +def test_topic0_corrupted_segment_index(accelize_drm, conf_json, cred_json, async_handler, live_server): + """ + Test to reproduce the issue that corrupts the segment ID with both async and syn requests. + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_topic0_corrupted_segment_index' + conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + + # Set initial context on the live server + healthPeriod = 10 + context = {'error':0, + 'healthPeriod':healthPeriod + } + set_context(context) + assert get_context() == context + + drm_manager.activate() + try: + wait_func_true(lambda: get_context()['error']) + finally: + drm_manager.deactivate() + async_cb.assert_NoError() + + +@pytest.mark.lgdn +def test_topic1_corrupted_metering(accelize_drm, conf_json, cred_json, async_handler): + """ + Test to reproduce the metering corruption issue on pause/resume operating mode + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + activators = accelize_drm.pytest_fpga_activators[0] + activators.reset_coin() + activators.autotest() + cred_json.set_user('accelize_accelerator_test_02') + + async_cb.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + nb_run = 100 + nb_pause_resume_max = 100 + for r in range(nb_run): + print('Run #%d' % r) + try: + activators[0].reset_coin() + assert not drm_manager.get('session_status') + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) + async_cb.assert_NoError() + drm_manager.activate() + start = datetime.now() + assert drm_manager.get('metered_data') == 0 + assert drm_manager.get('session_status') + assert drm_manager.get('license_status') + session_id = drm_manager.get('session_id') + assert len(session_id) > 0 + lic_duration = drm_manager.get('license_duration') + activators.autotest(is_activated=True) + for i in range(nb_pause_resume_max): + print('Pause #%d' % i) + try: + new_coins = randint(1, 100) + activators[0].generate_coin(new_coins) + data = drm_manager.get('metered_data') + try: + activators[0].check_coin(data) + except AssertionError: + print("ERROR detected!!!!!!!!") + print("1st read gives:", data) + print("Waiting 5s ...") + sleep(5) + print("... and double check the metering") + data = drm_manager.get('metered_data') + print("2nd read gives:", data) + activators[0].check_coin(drm_manager.get('metered_data')) + drm_manager.deactivate(True) + async_cb.assert_NoError() + assert drm_manager.get('session_status') + assert drm_manager.get('license_status') + assert drm_manager.get('session_id') == session_id + # Wait for the limit of the expiration + random_wait = lic_duration*2 + wait_deadline(start, random_wait) + drm_manager.activate(True) + start = datetime.now() + except: + raise + drm_manager.deactivate() + assert not drm_manager.get('session_status') + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) + assert drm_manager.get('session_id') != session_id + async_cb.assert_NoError() + finally: + drm_manager.deactivate() + diff --git a/tests/test_logging.py b/tests/test_logging.py index a65f0adf..0b69b4e2 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -1,16 +1,17 @@ # -*- coding: utf-8 -*- """ -Test node-locked behavior of DRM Library. +Test logging mechanism of DRM Library. """ import pytest -import gc from glob import glob -from os import remove, getpid -from os.path import getsize, isfile, dirname, join, realpath +from os import remove, getpid, makedirs, access, R_OK, W_OK +from os.path import getsize, isfile, dirname, join, realpath, isdir, expanduser from re import search, findall, finditer, MULTILINE -from time import sleep, time -from json import loads -from datetime import datetime, timedelta +from time import time, sleep +from shutil import rmtree +from random import randrange + +from tests.conftest import wait_func_true, whoami LOG_FORMAT_SHORT = "[%^%=8l%$] %-6t, %v" @@ -20,40 +21,32 @@ REGEX_FORMAT_LONG = r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3} - \s*\S+:\d+\s* \[\s*(\w+)\s*\] \s*\d+\s*, %s' -## TEST LOG FILE - def test_file_path(accelize_drm, conf_json, cred_json, async_handler): - """Test logging file verbosity""" + """Test logging file path""" driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() - log_path = realpath("./test_drmlib-%d.log" % getpid()) + log_path = accelize_drm.create_log_path(whoami()) log_type= 1 async_cb.reset() - if isfile(log_path): - remove(log_path) - assert not isfile(log_path) conf_json.reset() conf_json['settings']['log_verbosity'] = 6 conf_json['settings']['log_file_path'] = log_path conf_json['settings']['log_file_type'] = log_type conf_json.save() - try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - del drm_manager - gc.collect() - assert isfile(log_path) - async_cb.assert_NoError() - finally: - if isfile(log_path): - remove(log_path) + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + del drm_manager + wait_func_true(lambda: isfile(log_path), 10) + async_cb.assert_NoError() + remove(log_path) def test_file_verbosity(accelize_drm, conf_json, cred_json, async_handler): @@ -61,129 +54,123 @@ def test_file_verbosity(accelize_drm, conf_json, cred_json, async_handler): driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() - log_path = realpath("./drmlib-%d.log" % getpid()) log_type = 1 msg = 'This is a %s message' level_dict = {0:'trace', 1:'debug', 2:'info', 3:'warning', 4:'error', 5:'critical'} for verbosity in range(len(level_dict)+1): async_cb.reset() - if isfile(log_path): - remove(log_path) - assert not isfile(log_path) + log_path = accelize_drm.create_log_path(whoami() + '_verbosity%d' % verbosity) conf_json.reset() conf_json['settings']['log_verbosity'] = 6 conf_json['settings']['log_file_format'] = LOG_FORMAT_LONG conf_json['settings']['log_file_path'] = log_path conf_json['settings']['log_file_type'] = log_type conf_json.save() - try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - drm_manager.set(log_file_verbosity=verbosity) - assert drm_manager.get('log_file_verbosity') == verbosity - for i in sorted(level_dict.keys()): - drm_manager.set(log_message_level=i) - drm_manager.set(log_message=msg % level_dict[i]) - del drm_manager - gc.collect() - assert isfile(log_path) - with open(log_path, 'rt') as f: - log_content = f.read() - regex = REGEX_FORMAT_LONG % (msg % '(.*)') - trace_hit = 0 - for i, m in enumerate(finditer(regex, log_content)): - assert m.group(1) == m.group(2) - assert m.group(1) == level_dict[verbosity + i] - trace_hit += 1 - assert trace_hit == 6-verbosity - async_cb.assert_NoError() - finally: - if isfile(log_path): - remove(log_path) - - -def test_file_format(accelize_drm, conf_json, cred_json, async_handler): - """Test logging file formats""" + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.set(log_file_verbosity=verbosity) + assert drm_manager.get('log_file_verbosity') == verbosity + for i in sorted(level_dict.keys()): + drm_manager.set(log_message_level=i) + drm_manager.set(log_message=msg % level_dict[i]) + del drm_manager + wait_func_true(lambda: isfile(log_path), 10) + with open(log_path, 'rt') as f: + log_content = f.read() + regex = REGEX_FORMAT_LONG % (msg % '(.*)') + trace_hit = 0 + for i, m in enumerate(finditer(regex, log_content)): + assert m.group(1) == m.group(2) + assert m.group(1) == level_dict[verbosity + i] + trace_hit += 1 + assert trace_hit == 6-verbosity + async_cb.assert_NoError() + remove(log_path) + + +def test_file_short_format(accelize_drm, conf_json, cred_json, async_handler): + """Test logging file short format""" driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() - log_path = realpath("./drmlib-%d.log" % getpid()) + log_path = accelize_drm.create_log_path(whoami()) log_type = 1 msg = 'This is a message' regex_short = REGEX_FORMAT_SHORT % msg - regex_long = REGEX_FORMAT_LONG % msg - # Test logging with short format async_cb.reset() conf_json.reset() conf_json['settings']['log_verbosity'] = 6 - conf_json['settings']['log_file_verbosity'] = 2 + conf_json['settings']['log_file_verbosity'] = accelize_drm.create_log_level(2) conf_json['settings']['log_file_format'] = LOG_FORMAT_SHORT conf_json['settings']['log_file_path'] = log_path conf_json['settings']['log_file_type'] = log_type conf_json.save() - try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - drm_manager.set(log_message_level=2) - drm_manager.set(log_message=msg) - del drm_manager - gc.collect() - assert isfile(log_path) - with open(log_path, 'rt') as f: - log_content = f.read() - m = search(regex_short, log_content, MULTILINE) - assert m is not None - assert m.group(1) == 'info' - async_cb.assert_NoError() - finally: - if isfile(log_path): - remove(log_path) - print('Test logging file short format: PASS') - # Test logging with long format + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.set(log_message_level=2) + drm_manager.set(log_message=msg) + del drm_manager + wait_func_true(lambda: isfile(log_path), 10) + with open(log_path, 'rt') as f: + log_content = f.read() + m = search(regex_short, log_content, MULTILINE) + assert m is not None + assert m.group(1) == 'info' + async_cb.assert_NoError() + remove(log_path) + + +def test_file_long_format(accelize_drm, conf_json, cred_json, async_handler): + """Test logging file long format""" + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + log_path = accelize_drm.create_log_path(whoami()) + log_type = 1 + msg = 'This is a message' + regex_long = REGEX_FORMAT_LONG % msg + async_cb.reset() conf_json.reset() conf_json['settings']['log_verbosity'] = 6 - conf_json['settings']['log_file_verbosity'] = 2 + conf_json['settings']['log_file_verbosity'] = accelize_drm.create_log_level(2) conf_json['settings']['log_file_format'] = LOG_FORMAT_LONG conf_json['settings']['log_file_path'] = log_path conf_json['settings']['log_file_type'] = log_type conf_json.save() - try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - drm_manager.set(log_message_level=2) - drm_manager.set(log_message=msg) - del drm_manager - gc.collect() - assert isfile(log_path) - with open(log_path, 'rt') as f: - log_content = f.read() - m = search(regex_long, log_content, MULTILINE) - assert m is not None - assert m.group(1) == 'info' - async_cb.assert_NoError() - finally: - if isfile(log_path): - remove(log_path) - print('Test logging file long format: PASS') + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.set(log_message_level=2) + drm_manager.set(log_message=msg) + del drm_manager + wait_func_true(lambda: isfile(log_path), 10) + with open(log_path, 'rt') as f: + log_content = f.read() + m = search(regex_long, log_content, MULTILINE) + assert m is not None + assert m.group(1) == 'info' + async_cb.assert_NoError() + remove(log_path) def test_file_types(accelize_drm, conf_json, cred_json, async_handler): @@ -191,18 +178,15 @@ def test_file_types(accelize_drm, conf_json, cred_json, async_handler): driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() - log_path = realpath("./drmlib-%d.log" % getpid()) msg = 'This is a message' - verbosity = 2 - rotating_size = 1024 + verbosity = accelize_drm.create_log_level(2) + rotating_size = 1 rotating_num = 5 - size = rotating_size * rotating_num + size = rotating_size * 1024 * rotating_num for log_type in range(3): + log_path = accelize_drm.create_log_path(whoami() + '_log_type%d' % log_type) async_cb.reset() - for f in glob(log_path[:-3] + '*log'): - remove(f) - assert not isfile(log_path) conf_json.reset() conf_json['settings']['log_verbosity'] = 6 conf_json['settings']['log_file_verbosity'] = verbosity @@ -218,35 +202,103 @@ def test_file_types(accelize_drm, conf_json, cred_json, async_handler): driver.write_register_callback, async_cb.callback ) - try: - if log_type == 0: - assert not isfile(log_path) + if log_type == 0: + assert not isfile(log_path) + else: + assert isfile(log_path) + assert rotating_size == drm_manager.get('log_file_rotating_size') + assert rotating_num == drm_manager.get('log_file_rotating_num') + drm_manager.set(log_message_level=verbosity) + assert drm_manager.get('log_message_level') == verbosity + for _ in range(2 * int(size / len(msg)) + 1): + drm_manager.set(log_message=msg) + del drm_manager + wait_func_true(lambda: isfile(log_path), 10) + if log_type == 1: + # Basic file + assert getsize(log_path) >= 2 * size else: - assert isfile(log_path) - assert rotating_size == drm_manager.get('log_file_rotating_size') - assert rotating_num == drm_manager.get('log_file_rotating_num') - drm_manager.set(log_message_level=verbosity) - assert drm_manager.get('log_message_level') == verbosity - for _ in range(2 * int(size / len(msg)) + 1): - drm_manager.set(log_message=msg) - del drm_manager - gc.collect() - if log_type == 1: - # Basic file - assert getsize(log_path) >= 2 * size - else: - # Rotating file - log_f_list = glob(log_path[:-3] + '*log') - assert len(log_f_list) == rotating_num + 1 - for log_f in log_f_list: - assert isfile(log_f) - if log_f != log_path: - assert getsize(log_f) >= rotating_size / 2 - assert getsize(log_f) < 2 * rotating_size - async_cb.assert_NoError() - finally: - for f in glob(log_path[:-3] + '*log'): - remove(f) + # Rotating file + log_f_list = glob(log_path[:-3] + '*log') + assert len(log_f_list) == rotating_num + 1 + for log_f in log_f_list: + assert isfile(log_f) + if log_f != log_path: + assert getsize(log_f) >= rotating_size*1024 / 2 + assert getsize(log_f) < 2 * rotating_size*1024 + async_cb.assert_NoError() + for f in glob(log_path[:-3] + '*log'): + remove(f) + + +def test_file_append(accelize_drm, conf_json, cred_json, async_handler): + """Test logging file append mode""" + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + log_path = accelize_drm.create_log_path(whoami()) + log_type= 1 + + async_cb.reset() + conf_json.reset() + conf_json['settings']['log_verbosity'] = 6 + conf_json['settings']['log_file_path'] = log_path + conf_json['settings']['log_file_type'] = log_type + conf_json['settings']['log_file_append'] = True + conf_json.save() + + nb_loop = 5 + for i in range(nb_loop): + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + del drm_manager + wait_func_true(lambda: isfile(log_path), 10) + async_cb.assert_NoError() + assert len(glob(log_path)) == 1 + with open(log_path, 'rt') as f: + log_content = f.read() + assert len(findall(r'Installed versions', log_content)) == nb_loop + remove(log_path) + + +def test_file_truncate(accelize_drm, conf_json, cred_json, async_handler): + """Test logging file truncate mode""" + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + log_path = accelize_drm.create_log_path(whoami()) + log_type= 1 + + async_cb.reset() + conf_json.reset() + conf_json['settings']['log_verbosity'] = 6 + conf_json['settings']['log_file_path'] = log_path + conf_json['settings']['log_file_type'] = log_type + conf_json['settings']['log_file_append'] = False + conf_json.save() + + nb_loop = 5 + for i in range(nb_loop): + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + del drm_manager + wait_func_true(lambda: isfile(log_path), 10) + async_cb.assert_NoError() + assert len(glob(log_path)) == 1 + with open(log_path, 'rt') as f: + log_content = f.read() + assert len(findall(r'Installed versions', log_content)) == 1 + remove(log_path) def test_file_rotating_parameters(accelize_drm, conf_json, cred_json, async_handler): @@ -254,17 +306,14 @@ def test_file_rotating_parameters(accelize_drm, conf_json, cred_json, async_hand driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() - log_path = realpath("./drmlib-%d.log" % getpid()) + log_path = accelize_drm.create_log_path(whoami()) log_type = 2 msg = 'This is a message' - verbosity = 2 - rotating_size = 1024 + verbosity = accelize_drm.create_log_level(2) + rotating_size = 1 rotating_num = 5 async_cb.reset() - for f in glob(log_path[:-3] + '*log'): - remove(f) - assert not isfile(log_path) conf_json.reset() conf_json['settings']['log_verbosity'] = 6 conf_json['settings']['log_file_verbosity'] = verbosity @@ -280,35 +329,34 @@ def test_file_rotating_parameters(accelize_drm, conf_json, cred_json, async_hand driver.write_register_callback, async_cb.callback ) - try: - assert isfile(log_path) - assert drm_manager.get('log_file_rotating_size') == rotating_size - assert drm_manager.get('log_file_rotating_num') == rotating_num - drm_manager.set(log_message_level=verbosity) - assert drm_manager.get('log_message_level') == verbosity - for _ in range(2 * rotating_num * int(rotating_size / len(msg) + 10)): - drm_manager.set(log_message=msg) - del drm_manager - gc.collect() - log_list = glob(log_path[:-3] + '*log') - assert len(log_list) == rotating_num + 1 - index_list = list(range(rotating_num + 1)) - for log_f in log_list: - assert isfile(log_f) - assert getsize(log_f) < 2 * rotating_size - m = search(r'drmlib-\d+(\.\d)?\.log', log_f) - assert m is not None - if m.group(1) is None: - index = 0 - else: - index = int(m.group(1)[1]) - assert index in index_list - index_list.remove(index) - assert len(index_list) == 0 - async_cb.assert_NoError() - finally: - for f in glob(log_path[:-3] + '*log'): - remove(f) + assert isfile(log_path) + assert drm_manager.get('log_file_rotating_size') == rotating_size + assert drm_manager.get('log_file_rotating_num') == rotating_num + drm_manager.set(log_message_level=verbosity) + assert drm_manager.get('log_message_level') == verbosity + for _ in range(2 * rotating_num * int(rotating_size*1024 / len(msg) + 10)): + drm_manager.set(log_message=msg) + del drm_manager + wait_func_true(lambda: len(glob(log_path[:-3] + '*log')), 10) + log_list = glob(log_path[:-3] + '*log') + assert len(log_list) == rotating_num + 1 + index_list = list(range(rotating_num + 1)) + bname = log_path[:-4] + for log_f in log_list: + assert isfile(log_f) + assert getsize(log_f) < 2 * rotating_size*1024 + m = search(r'%s(\.\d+)?\.log' % bname, log_f) + assert m is not None + if m.group(1) is None: + index = 0 + else: + index = int(m.group(1)[1]) + assert index in index_list + index_list.remove(index) + assert len(index_list) == 0 + async_cb.assert_NoError() + for f in glob(log_path[:-3] + '*log'): + remove(f) def test_versions_displayed_in_log_file(accelize_drm, conf_json, cred_json, async_handler): @@ -316,9 +364,9 @@ def test_versions_displayed_in_log_file(accelize_drm, conf_json, cred_json, asyn driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() - log_path = realpath("./drmlib-%d.log" % getpid()) + log_path = accelize_drm.create_log_path(whoami()) log_type = 1 - verbosity = 5 + verbosity = accelize_drm.create_log_level(5) async_cb.reset() conf_json.reset() @@ -327,28 +375,25 @@ def test_versions_displayed_in_log_file(accelize_drm, conf_json, cred_json, asyn conf_json['settings']['log_file_path'] = log_path conf_json['settings']['log_file_type'] = log_type conf_json.save() - try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('log_file_verbosity') == verbosity - del drm_manager - gc.collect() - assert isfile(log_path) - with open(log_path, 'rt') as f: - log_content = f.read() - assert search(r'drmlib\s*:\s*\d+\.\d+\.\d+', log_content, MULTILINE) - assert search(r'libcurl\s*:(\s*\w+/\d+\.\d+(\.\d+)?)+\n', log_content, MULTILINE) - assert search(r'jsoncpp\s*:\s*\d+\.\d+\.\d+\n', log_content, MULTILINE) - assert search(r'spdlog\s*:\s*\d+\.\d+\.\d+\n', log_content, MULTILINE) - async_cb.assert_NoError() - finally: - if isfile(log_path): - remove(log_path) + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_file_verbosity') == verbosity + del drm_manager + wait_func_true(lambda: isfile(log_path), 10) + with open(log_path, 'rt') as f: + log_content = f.read() + assert search(r'drmlib\s*:\s*\d+\.\d+\.\d+', log_content) + assert search(r'libcurl\s*:(\s+[^/]+/\d+\.\d+(\.\d+)?)+', log_content) + assert search(r'jsoncpp\s*:\s*\d+\.\d+\.\d+\n', log_content) + assert search(r'spdlog\s*:\s*\d+\.\d+\.\d+\n', log_content) + async_cb.assert_NoError() + remove(log_path) def test_log_file_parameters_modifiability(accelize_drm, conf_json, cred_json, async_handler): @@ -357,10 +402,10 @@ def test_log_file_parameters_modifiability(accelize_drm, conf_json, cred_json, a async_cb = async_handler.create() log_verbosity = 3 - log_path = realpath("./drmservice-%d.log" % getpid()) + log_path = accelize_drm.create_log_path(whoami()) log_format = LOG_FORMAT_LONG log_type = 2 - log_rotating_size = 10*1024 + log_rotating_size = 10 # =10KB log_rotating_num = 0 # Test from config file @@ -375,7 +420,109 @@ def test_log_file_parameters_modifiability(accelize_drm, conf_json, cred_json, a conf_json['settings']['log_file_rotating_size'] = log_rotating_size conf_json['settings']['log_file_rotating_num'] = log_rotating_num conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_file_verbosity') == log_verbosity + assert drm_manager.get('log_file_format') == log_format + assert drm_manager.get('log_file_path') == log_path + assert drm_manager.get('log_file_type') == log_type + assert drm_manager.get('log_file_rotating_size') == log_rotating_size + assert drm_manager.get('log_file_rotating_num') == log_rotating_num + # Try to modify verbosity => authorized + exp_value = log_verbosity - 1 + drm_manager.set(log_file_verbosity=exp_value) + assert drm_manager.get('log_file_verbosity') == exp_value + # Try to modify format => authorized + exp_value = LOG_FORMAT_SHORT + drm_manager.set(log_file_format=exp_value) + assert drm_manager.get('log_file_format') == exp_value + # Try to modify path => not authorized + exp_value = realpath("./unexpected-%d.%d.log" % (getpid(), randrange(0xFFFFFFFF))) + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(log_file_path=exp_value) + assert drm_manager.get('log_file_path') == log_path + # Try to modify rotating size => not authorized + exp_value = int(log_rotating_size / 2) + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(log_file_rotating_size=exp_value) + assert drm_manager.get('log_file_rotating_size') == log_rotating_size + # Try to modify rotating num => not authorized + exp_value = int(log_rotating_num / 2) + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(log_file_rotating_num=exp_value) + assert drm_manager.get('log_file_rotating_num') == log_rotating_num + del drm_manager + wait_func_true(lambda: isfile(log_path), 10) + with open(log_path, 'rt') as f: + log_content = f.read() + critical_list = findall(r'\[\s*critical\s*\].* Parameter \S* cannot be overwritten', log_content) + assert len(critical_list) == 3 + async_cb.assert_NoError() + remove(log_path) + + +def test_log_file_error_on_directory_creation(accelize_drm, conf_json, cred_json, async_handler): + """ Test an error occurred when log file directory does not exist and cannot be created """ + from subprocess import check_call + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + log_type = 1 + log_dir = realpath(expanduser('~/tmp_log_dir.%s.%d' % (str(time()), randrange(0xFFFFFFFF)))) + if not isdir(log_dir): + makedirs(log_dir) + log_path = join(log_dir, "tmp", "drmlib.%d.%s.log" % (getpid(), str(time()))) try: + # Create immutable folder + check_call('sudo chattr +i %s' % log_dir, shell=True) + assert not access(log_dir, W_OK) + assert not isdir(dirname(log_path)) + async_cb.reset() + conf_json.reset() + conf_json['settings']['log_file_path'] = log_path + conf_json['settings']['log_file_type'] = log_type + conf_json.save() + with pytest.raises(accelize_drm.exceptions.DRMExternFail) as excinfo: + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert "Failed to create log file %s" % log_path in str(excinfo.value) + finally: + # Restore to mutable folder + check_call('sudo chattr -i %s' % log_dir, shell=True) + assert access(log_dir, W_OK) + if isdir(log_dir): + rmtree(log_dir) + + +def test_log_file_on_existing_directory(accelize_drm, conf_json, cred_json, async_handler): + """ Test when log file directory already exists """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + log_type = 1 + log_dir = realpath(expanduser('~/tmp_log_dir.%s.%d' % (str(time()), randrange(0xFFFFFFFF)))) + if not isdir(log_dir): + makedirs(log_dir) + log_path = join(log_dir, "drmlib.%d.%s.log" % (getpid(), time())) + try: + assert isdir(log_dir) + assert access(log_dir, W_OK) + assert not isfile(log_path) + async_cb.reset() + conf_json.reset() + conf_json['settings']['log_file_path'] = log_path + conf_json['settings']['log_file_type'] = log_type + conf_json.save() drm_manager = accelize_drm.DrmManager( conf_json.path, cred_json.path, @@ -383,44 +530,104 @@ def test_log_file_parameters_modifiability(accelize_drm, conf_json, cred_json, a driver.write_register_callback, async_cb.callback ) - assert drm_manager.get('log_file_verbosity') == log_verbosity - assert drm_manager.get('log_file_format') == log_format - assert drm_manager.get('log_file_path') == log_path - assert drm_manager.get('log_file_type') == log_type - assert drm_manager.get('log_file_rotating_size') == log_rotating_size - assert drm_manager.get('log_file_rotating_num') == log_rotating_num - # Try to modify verbosity => authorized - exp_value = log_verbosity - 1 - drm_manager.set(log_file_verbosity=exp_value) - assert drm_manager.get('log_file_verbosity') == exp_value - # Try to modify format => authorized - exp_value = LOG_FORMAT_SHORT - drm_manager.set(log_file_format=exp_value) - assert drm_manager.get('log_file_format') == exp_value - # Try to modify path => not authorized - exp_value = realpath("./unexpected-%d.log" % getpid()) - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager.set(log_file_path=exp_value) - assert drm_manager.get('log_file_path') == log_path - # Try to modify rotating size => not authorized - exp_value = int(log_rotating_size / 2) - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager.set(log_file_rotating_size=exp_value) - assert drm_manager.get('log_file_rotating_size') == log_rotating_size - # Try to modify rotating num => not authorized - exp_value = int(log_rotating_num / 2) - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager.set(log_file_rotating_num=exp_value) - assert drm_manager.get('log_file_rotating_num') == log_rotating_num del drm_manager - gc.collect() - assert isfile(log_path) - with open(log_path, 'rt') as f: - log_content = f.read() - critical_list = findall(r'[\s*critical\s*].* Parameter \S* cannot be overwritten', log_content) - assert len(critical_list) == 3 - async_cb.assert_NoError() + wait_func_true(lambda: isfile(log_path), 10) + + finally: + if isdir(log_dir): + rmtree(log_dir) + + +def test_log_file_directory_creation(accelize_drm, conf_json, cred_json, async_handler): + """ Test the non existing sub-directories in the log file path are created by the DRMLib """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + log_type = 1 + log_dir = realpath(expanduser('~/tmp_log_dir.%s.%d' % (str(time()), randrange(0xFFFFFFFF)))) + if not isdir(log_dir): + makedirs(log_dir) + log_path = join(log_dir, 'tmp', "drmlib.%d.%s.log" % (getpid(), time())) + try: + assert isdir(log_dir) + assert access(log_dir, W_OK) + async_cb.reset() + conf_json.reset() + conf_json['settings']['log_file_path'] = log_path + conf_json['settings']['log_file_type'] = log_type + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + del drm_manager + wait_func_true(lambda: isfile(log_path), 10) finally: - if isfile(log_path): - remove(log_path) - print('Test log file parameters modifiability from config: PASS') + if isdir(log_dir): + rmtree(log_dir) + + +def test_log_file_without_credential_data_in_debug(accelize_drm, conf_json, cred_json, async_handler): + """ Test no credential information is saved into log file """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + log_type = 1 + log_path = accelize_drm.create_log_path(whoami()) + async_cb.reset() + conf_json.reset() + conf_json['settings']['log_file_path'] = log_path + conf_json['settings']['log_file_type'] = log_type + conf_json['settings']['log_file_verbosity'] = 1 + conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.activate() + sleep(1) + drm_manager.deactivate() + del drm_manager + wait_func_true(lambda: isfile(log_path), 10) + with open(log_path, 'rt') as f: + log_content = f.read() + assert not search(cred_json['client_id'], log_content) + assert not search(cred_json['client_secret'], log_content) + remove(log_path) + + +def test_log_file_without_credential_data_in_debug2(accelize_drm, conf_json, cred_json, async_handler): + """ Test no credential information is saved into log file """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + log_type = 1 + log_path = accelize_drm.create_log_path(whoami()) + async_cb.reset() + conf_json.reset() + conf_json['settings']['log_file_path'] = log_path + conf_json['settings']['log_file_type'] = log_type + conf_json['settings']['log_file_verbosity'] = 0 + conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.activate() + sleep(1) + drm_manager.deactivate() + del drm_manager + wait_func_true(lambda: isfile(log_path), 10) + with open(log_path, 'rt') as f: + log_content = f.read() + assert not search(cred_json['client_id'], log_content) + assert not search(cred_json['client_secret'], log_content) + remove(log_path) diff --git a/tests/test_metered_mode_on_hw.py b/tests/test_metered_mode_on_hw.py index da43b39f..6cb8497d 100644 --- a/tests/test_metered_mode_on_hw.py +++ b/tests/test_metered_mode_on_hw.py @@ -2,12 +2,87 @@ """ Test metering and floating behaviors of DRM Library. """ -import gc +import pytest from time import sleep -from random import randint +from random import randint, randrange from datetime import datetime, timedelta -from re import search -import pytest +from re import search, findall +from os.path import realpath, isfile +from os import remove + +from tests.conftest import wait_deadline, wait_func_true, whoami + + +def test_metered_start_stop_in_raw(accelize_drm, conf_json, cred_json, async_handler): + """ + Test no error occurs in normal start/stop metering mode during a short period of time + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + activators = accelize_drm.pytest_fpga_activators[0] + activators.reset_coin() + activators.autotest() + cred_json.set_user('accelize_accelerator_test_02') + + async_cb.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) + activators[0].generate_coin(1000) + try: + drm_manager.activate() + assert drm_manager.get('metered_data') == 0 + activators[0].check_coin(drm_manager.get('metered_data')) + drm_manager.deactivate() + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) + async_cb.assert_NoError() + finally: + drm_manager.deactivate() + + +def test_metered_start_stop_1_coin_in_raw(accelize_drm, conf_json, cred_json, async_handler): + """ + Test no error occurs in normal start/stop metering mode during a short period of time + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + activators = accelize_drm.pytest_fpga_activators[0] + activators.reset_coin() + activators.autotest() + cred_json.set_user('accelize_accelerator_test_02') + + async_cb.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + try: + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) + activators[0].generate_coin(1000) + activators[0].check_coin(drm_manager.get('metered_data')) + drm_manager.activate() + activators[0].generate_coin(1) + assert drm_manager.get('metered_data') == 1 + drm_manager.deactivate() + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) + assert drm_manager.get('metered_data') == 0 + async_cb.assert_NoError() + finally: + drm_manager.deactivate() @pytest.mark.minimum @@ -37,7 +112,6 @@ def test_metered_start_stop_short_time(accelize_drm, conf_json, cred_json, async activators.autotest(is_activated=False) activators[0].generate_coin(1000) drm_manager.activate() - sleep(1) activators[0].check_coin(drm_manager.get('metered_data')) assert drm_manager.get('license_status') activators.autotest(is_activated=True) @@ -46,8 +120,7 @@ def test_metered_start_stop_short_time(accelize_drm, conf_json, cred_json, async drm_manager.deactivate() assert not drm_manager.get('license_status') activators.autotest(is_activated=False) - coins = drm_manager.get('metered_data') - assert coins == 0 + assert drm_manager.get('metered_data') == 0 async_cb.assert_NoError() finally: drm_manager.deactivate() @@ -79,7 +152,6 @@ def test_metered_start_stop_short_time_in_debug(accelize_drm, conf_json, cred_js assert not drm_manager.get('license_status') activators.autotest(is_activated=False) drm_manager.activate() - sleep(1) assert drm_manager.get('metered_data') == 0 assert drm_manager.get('license_status') activators.autotest(is_activated=True) @@ -183,16 +255,14 @@ def test_metered_pause_resume_short_time(accelize_drm, conf_json, cred_json, asy activators[0].generate_coin(10) activators[0].check_coin(drm_manager.get('metered_data')) # Wait enough time to be sure the 2nd license has been provisioned - wait_period = start + timedelta(seconds=lic_duration/2) - datetime.now() - sleep(wait_period.total_seconds()) + wait_deadline(start, lic_duration/2) drm_manager.deactivate(True) assert drm_manager.get('session_status') assert drm_manager.get('license_status') assert drm_manager.get('session_id') == session_id activators.autotest(is_activated=True) # Wait right before license expiration - wait_period = start + timedelta(seconds=2*lic_duration-2) - datetime.now() - sleep(wait_period.total_seconds()) + wait_deadline(start, 2*lic_duration-2) assert drm_manager.get('session_status') assert drm_manager.get('license_status') assert drm_manager.get('session_id') == session_id @@ -218,7 +288,6 @@ def test_metered_pause_resume_short_time(accelize_drm, conf_json, cred_json, asy drm_manager.deactivate() -@pytest.mark.long_run @pytest.mark.hwtst def test_metered_pause_resume_long_time(accelize_drm, conf_json, cred_json, async_handler): """ @@ -240,6 +309,7 @@ def test_metered_pause_resume_long_time(accelize_drm, conf_json, cred_json, asyn driver.write_register_callback, async_cb.callback ) + nb_pause_resume = 5 try: assert not drm_manager.get('session_status') assert not drm_manager.get('license_status') @@ -254,8 +324,7 @@ def test_metered_pause_resume_long_time(accelize_drm, conf_json, cred_json, asyn assert len(session_id) > 0 lic_duration = drm_manager.get('license_duration') activators.autotest(is_activated=True) - coins = drm_manager.get('metered_data') - for i in range(3): + for i in range(nb_pause_resume): new_coins = randint(1, 100) activators[0].generate_coin(new_coins) activators[0].check_coin(drm_manager.get('metered_data')) @@ -264,11 +333,9 @@ def test_metered_pause_resume_long_time(accelize_drm, conf_json, cred_json, asyn assert drm_manager.get('session_status') assert drm_manager.get('license_status') assert drm_manager.get('session_id') == session_id - # Wait randomly - nb_lic_expired = int((datetime.now() - start).total_seconds() / lic_duration) - random_wait = randint((nb_lic_expired+2)*lic_duration-2, (nb_lic_expired+2)*lic_duration+2) - wait_period = start + timedelta(seconds=random_wait) - datetime.now() - sleep(wait_period.total_seconds()) + # Wait randomly at the limit of the expiration + random_wait = randint(lic_duration*2-1, lic_duration*2+1) + wait_deadline(start, random_wait) drm_manager.activate(True) start = datetime.now() assert drm_manager.get('session_status') @@ -323,18 +390,15 @@ def test_metered_pause_resume_from_new_object(accelize_drm, conf_json, cred_json activators[0].check_coin(drm_manager1.get('metered_data')) assert drm_manager1.get('metered_data') == 10 # Wait enough time to be sure the 2nd license has been provisioned - wait_period = start + timedelta(seconds=lic_duration/2) - datetime.now() - sleep(wait_period.total_seconds()) + wait_deadline(start, lic_duration/2) drm_manager1.deactivate(True) assert drm_manager1.get('session_status') assert drm_manager1.get('license_status') assert drm_manager1.get('session_id') == session_id activators.autotest(is_activated=True) - # Kill object - del drm_manager1 - gc.collect() async_cb.assert_NoError() sleep(1) + # Create new object drm_manager2 = accelize_drm.DrmManager( conf_json.path, @@ -343,10 +407,11 @@ def test_metered_pause_resume_from_new_object(accelize_drm, conf_json, cred_json driver.write_register_callback, async_cb.callback ) - assert drm_manager2.get('license_duration') == 30 + assert drm_manager1 != drm_manager2 assert drm_manager2.get('session_status') assert drm_manager2.get('license_status') activators.autotest(is_activated=True) + assert drm_manager2.get('session_id') == '' # Resume session drm_manager2.activate(True) assert drm_manager2.get('session_status') @@ -354,19 +419,122 @@ def test_metered_pause_resume_from_new_object(accelize_drm, conf_json, cred_json activators.autotest(is_activated=True) assert drm_manager2.get('metered_data') == 10 # Wait for license renewal - wait_period = start + timedelta(seconds=lic_duration+2) - datetime.now() - sleep(wait_period.total_seconds()) + sleep(lic_duration+2) + assert drm_manager2.get('session_id') == session_id + assert drm_manager2.get('license_duration') == lic_duration activators[0].generate_coin(10) activators[0].check_coin(drm_manager2.get('metered_data')) assert drm_manager2.get('metered_data') == 20 drm_manager2.deactivate() assert not drm_manager2.get('session_status') assert not drm_manager2.get('license_status') + assert drm_manager2.get('session_id') == '' activators.autotest(is_activated=False) - assert drm_manager2.get('session_id') != session_id async_cb.assert_NoError() +@pytest.mark.minimum +@pytest.mark.hwtst +def test_async_on_pause(accelize_drm, conf_json, cred_json, async_handler): + """ + Test an async health commande is executed on pause. + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + activators = accelize_drm.pytest_fpga_activators[0] + cred_json.set_user('accelize_accelerator_test_02') + conf_json.reset() + logpath = accelize_drm.create_log_path(whoami()) + conf_json['settings']['log_file_verbosity'] = 0 + conf_json['settings']['log_file_type'] = 1 + conf_json['settings']['log_file_path'] = logpath + conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + try: + assert not drm_manager.get('session_status') + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) + drm_manager.activate() + start = datetime.now() + if drm_manager.get('health_period') == 0: + remove(logpath) + pytest.skip('Health is not active: skip async test') + lic_duration = drm_manager.get('license_duration') + assert drm_manager.get('session_status') + assert drm_manager.get('license_status') + session_id = drm_manager.get('session_id') + assert len(session_id) > 0 + activators.autotest(is_activated=True) + drm_manager.deactivate(True) # Pause session + assert drm_manager.get('session_status') + assert drm_manager.get('license_status') + assert drm_manager.get('session_id') == session_id + activators.autotest(is_activated=True) + finally: + drm_manager.deactivate() + del drm_manager + wait_func_true(lambda: isfile(logpath), 10) + with open(logpath, 'rt') as f: + log_content = f.read() + assert len(list(findall(r'"request"\s*:\s*"health"', log_content))) == 1 + async_cb.assert_NoError() + remove(logpath) + + +@pytest.mark.minimum +@pytest.mark.hwtst +def test_stop_after_pause(accelize_drm, conf_json, cred_json, async_handler): + """ + Test an async health commande is executed on pause. + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + activators = accelize_drm.pytest_fpga_activators[0] + cred_json.set_user('accelize_accelerator_test_02') + conf_json.reset() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert not drm_manager.get('session_status') + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) + drm_manager.activate() + try: + start = datetime.now() + lic_duration = drm_manager.get('license_duration') + assert drm_manager.get('session_status') + assert drm_manager.get('license_status') + session_id = drm_manager.get('session_id') + assert len(session_id) > 0 + activators.autotest(is_activated=True) + drm_manager.deactivate(True) # Pause session + assert drm_manager.get('session_status') + assert drm_manager.get('license_status') + assert drm_manager.get('session_id') == session_id + activators.autotest(is_activated=True) + finally: + drm_manager.deactivate() + assert not drm_manager.get('session_status') + assert not drm_manager.get('license_status') + assert drm_manager.get('session_id') != session_id + assert drm_manager.get('session_id') == '' + activators.autotest(is_activated=False) + + @pytest.mark.minimum @pytest.mark.no_parallel @pytest.mark.hwtst @@ -415,7 +583,7 @@ def test_metering_limits(accelize_drm, conf_json, cred_json, async_handler, ws_a assert not drm_manager.get('license_status') with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: drm_manager.activate() - assert 'License Web Service error 400' in str(excinfo.value) + assert 'Metering Web Service error 400' in str(excinfo.value) assert 'DRM WS request failed' in str(excinfo.value) assert search(r'\\"Entitlement Limit Reached\\" with .+ for \S+_test_03@accelize.com', str(excinfo.value)) assert 'You have reached the maximum quantity of 1000. usage_unit for metered entitlement (licensed)' in str(excinfo.value) @@ -450,8 +618,7 @@ def test_metering_limits(accelize_drm, conf_json, cred_json, async_handler, ws_a activators[0].generate_coin(1000) activators[0].check_coin(drm_manager.get('metered_data')) # Wait right before expiration - wait_period = start + timedelta(seconds=3*lic_duration-3) - datetime.now() - sleep(wait_period.total_seconds()) + wait_deadline(start, 3*lic_duration-3) assert drm_manager.get('license_status') activators.autotest(is_activated=True) sleep(5) @@ -459,7 +626,7 @@ def test_metering_limits(accelize_drm, conf_json, cred_json, async_handler, ws_a activators.autotest(is_activated=False) # Verify asynchronous callback has been called assert async_cb.was_called - assert 'License Web Service error 400' in async_cb.message + assert 'Metering Web Service error 400' in async_cb.message assert 'DRM WS request failed' in async_cb.message assert search(r'\\"Entitlement Limit Reached\\" with .+ for \S+_test_03@accelize.com', async_cb.message) assert 'You have reached the maximum quantity of 1000. usage_unit for metered entitlement (licensed)' in async_cb.message @@ -529,3 +696,69 @@ def test_floating_limits(accelize_drm, conf_json, cred_json, async_handler): drm_manager1.deactivate() assert not drm_manager1.get('license_status') async_cb1.assert_NoError() + + +def test_async_call_during_pause(accelize_drm, conf_json, cred_json, async_handler): + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + activators = accelize_drm.pytest_fpga_activators[0] + activators.reset_coin() + activators.autotest() + cred_json.set_user('accelize_accelerator_test_02') + conf_json.reset() + logpath = accelize_drm.create_log_path(whoami()) + conf_json['settings']['log_file_verbosity'] = accelize_drm.create_log_level(2) + conf_json['settings']['log_file_type'] = 1 + conf_json['settings']['log_file_path'] = logpath + conf_json.save() + async_cb.reset() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + activators[0].reset_coin() + assert not drm_manager.get('session_status') + assert not drm_manager.get('license_status') + activators.autotest(is_activated=False) + activators[0].generate_coin(randint(1,100)) + assert drm_manager.get('metered_data') == 0 + drm_manager.activate() + try: + assert drm_manager.get('metered_data') == 0 + coins = randint(1,100) + activators[0].generate_coin(coins) + activators[0].check_coin(drm_manager.get('metered_data')) + drm_manager.deactivate(True) + sleep(1) + #assert drm_manager.get('metered_data') == coins + activators[0].check_coin(drm_manager.get('metered_data')) + assert drm_manager.get('session_status') + assert drm_manager.get('license_status') + session_id = drm_manager.get('session_id') + assert len(session_id) > 0 + lic_duration = drm_manager.get('license_duration') + activators.autotest(is_activated=True) + sleep(lic_duration * 2 + 1) + activators.autotest(is_activated=False) + assert not drm_manager.get('license_status') + assert drm_manager.get('session_status') + assert session_id == drm_manager.get('session_id') + #assert drm_manager.get('metered_data') == coins + activators[0].check_coin(drm_manager.get('metered_data')) + activators[0].generate_coin(5) + activators[0].check_coin(drm_manager.get('metered_data')) + assert drm_manager.get('metered_data') == coins + finally: + drm_manager.deactivate() + assert drm_manager.get('metered_data') == 0 + del drm_manager + wait_func_true(lambda: isfile(logpath), 10) + with open(logpath, 'rt') as f: + log_content = f.read() + assert len(list(findall(r'warning\b.*\bCannot access metering data when no session is running', log_content))) == 2 + async_cb.assert_NoError() + remove(logpath) diff --git a/tests/test_nodelock_mode_on_hw.py b/tests/test_nodelock_mode_on_hw.py index 8cd923bb..a28c7bf8 100644 --- a/tests/test_nodelock_mode_on_hw.py +++ b/tests/test_nodelock_mode_on_hw.py @@ -78,7 +78,7 @@ def test_nodelock_license_is_not_given_to_inactive_user(accelize_drm, conf_json, assert not drm_manager.get('license_status') with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: drm_manager.activate() - assert 'License Web Service error 400' in str(excinfo.value) + assert 'Metering Web Service error 400' in str(excinfo.value) assert search(r'\\"No Entitlement\\" with .+ for \S+_test_01@accelize.com', str(excinfo.value)) assert 'User account has no entitlement. Purchase additional licenses via your portal.' in str(excinfo.value) err_code = async_handler.get_error_code(str(excinfo.value)) @@ -276,7 +276,7 @@ def test_nodelock_limits(accelize_drm, conf_json, cred_json, async_handler, ws_a assert drm_manager1.get('license_type') == 'Node-Locked' with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: drm_manager1.activate() - assert 'License Web Service error 400' in str(excinfo.value) + assert 'Metering Web Service error 400' in str(excinfo.value) assert 'DRM WS request failed' in str(excinfo.value) assert search(r'\\"Entitlement Limit Reached\\" with .+ for \S+_test_03@accelize.com', str(excinfo.value)) assert 'You have reached the maximum quantity of 1 nodes for Nodelocked entitlement' in str(excinfo.value) @@ -456,7 +456,7 @@ def test_parsing_of_nodelock_files(accelize_drm, conf_json, cred_json, async_han move(req_file_path, req_file_path_bad) with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: drm_manager.activate() - assert 'Cannot find JSON file' in str(excinfo.value) + assert 'Path is not a valid file' in str(excinfo.value) err_code = async_handler.get_error_code(str(excinfo.value)) assert err_code == accelize_drm.exceptions.DRMBadArg.error_code async_cb.assert_NoError() diff --git a/tests/test_parameters.py b/tests/test_parameters.py new file mode 100644 index 00000000..8ed68859 --- /dev/null +++ b/tests/test_parameters.py @@ -0,0 +1,1205 @@ +# -*- coding: utf-8 -*- +""" +Test node-locked behavior of DRM Library. +""" +import pytest +from os import remove, getpid, environ +from os.path import isfile, realpath +from re import match, search, finditer +from time import sleep, time + +from tests.conftest import wait_func_true, whoami + + +LOG_FORMAT_SHORT = "[%^%=8l%$] %-6t, %v" +LOG_FORMAT_LONG = "%Y-%m-%d %H:%M:%S.%e - %18s:%-4# [%=8l] %=6t, %v" + +_PARAM_LIST = ('license_type', + 'license_duration', + 'num_activators', + 'session_id', + 'session_status', + 'license_status', + 'metered_data', + 'nodelocked_request_file', + 'drm_frequency', + 'drm_license_type', + 'product_info', + 'mailbox_size', + 'token_string', + 'token_validity', + 'token_time_left', + 'log_verbosity', + 'log_format', + 'log_file_verbosity', + 'log_file_format', + 'log_file_path', + 'log_file_type', + 'log_file_rotating_size', + 'log_file_rotating_num', + 'bypass_frequency_detection', + 'frequency_detection_method', + 'frequency_detection_threshold', + 'frequency_detection_period', + 'custom_field', + 'mailbox_data', + 'ws_retry_period_long', + 'ws_retry_period_short', + 'ws_request_timeout', + 'log_message_level', + 'list_all', + 'dump_all', + 'page_ctrlreg', + 'page_vlnvfile', + 'page_licfile', + 'page_tracefile', + 'page_meteringfile', + 'page_mailbox', + 'hw_report', + 'trigger_async_callback', + 'log_message', + 'hdk_compatibility', + 'health_period', + 'health_retry', + 'health_retry_sleep', + 'ws_api_retry_duration', + 'host_data_verbosity', + 'host_data', + 'log_file_append', + 'ws_verbosity' +) + + +@pytest.mark.minimum +def test_parameter_key_modification_with_config_file(accelize_drm, conf_json, cred_json, + async_handler): + """Test accesses to parameters""" + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + # First get all default value for all tested parameters + async_cb.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + orig_log_verbosity = drm_manager.get('log_verbosity') + orig_log_format = drm_manager.get('log_format') + orig_frequency_mhz = drm_manager.get('drm_frequency') + orig_frequency_detect_period = drm_manager.get('frequency_detection_period') + orig_frequency_detect_threshold = drm_manager.get('frequency_detection_threshold') + orig_retry_period_long = drm_manager.get('ws_retry_period_long') + orig_retry_period_short = drm_manager.get('ws_retry_period_short') + orig_api_retry_duration = drm_manager.get('ws_api_retry_duration') + orig_request_timeout = drm_manager.get('ws_request_timeout') + + # Test parameter: log_verbosity + from random import choice + async_cb.reset() + conf_json.reset() + log_level_choice = list(range(0,6)) + log_level_choice.remove(orig_log_verbosity) + exp_value = choice(log_level_choice) + assert exp_value != orig_log_verbosity + conf_json['settings']['log_verbosity'] = exp_value + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_verbosity') == exp_value + drm_manager.set(log_verbosity=orig_log_verbosity) + print("Test parameter 'log_verbosity': PASS") + + # Test parameter: log_format + async_cb.reset() + conf_json.reset() + exp_value = LOG_FORMAT_LONG + conf_json['settings']['log_format'] = exp_value + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_format') == exp_value + async_cb.assert_NoError() + print("Test parameter 'log_format': PASS") + + # Test parameter: log_file_verbosity + async_cb.reset() + conf_json.reset() + exp_value = 0 + conf_json['settings']['log_file_verbosity'] = exp_value + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_file_verbosity') == exp_value + async_cb.assert_NoError() + print("Test parameter 'log_file_verbosity': PASS") + + # Test parameter: log_file_format + async_cb.reset() + conf_json.reset() + exp_value = LOG_FORMAT_SHORT + conf_json['settings']['log_file_format'] = exp_value + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_file_format') == exp_value + async_cb.assert_NoError() + print("Test parameter 'log_file_format': PASS") + + # Test parameter: log_file_path + async_cb.reset() + conf_json.reset() + exp_value = accelize_drm.create_log_path(whoami()) + conf_json['settings']['log_file_path'] = exp_value + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_file_path') == exp_value + async_cb.assert_NoError() + print("Test parameter 'log_file_path': PASS") + + # Test parameter: log_file_type + async_cb.reset() + conf_json.reset() + exp_value = 1 + conf_json['settings']['log_file_type'] = exp_value + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_file_type') == exp_value + async_cb.assert_NoError() + print("Test parameter 'log_file_type': PASS") + + # Test parameter: log_file_rotating_size + async_cb.reset() + conf_json.reset() + exp_value = 1024 + conf_json['settings']['log_file_rotating_size'] = exp_value + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_file_rotating_size') == exp_value + async_cb.assert_NoError() + print("Test parameter 'log_file_rotating_size': PASS") + + # Test parameter: log_file_rotating_num + async_cb.reset() + conf_json.reset() + exp_value = 10 + conf_json['settings']['log_file_rotating_num'] = exp_value + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_file_rotating_num') == exp_value + async_cb.assert_NoError() + print("Test parameter 'log_file_rotating_num': PASS") + + # Test parameter: frequency_detection_method + if accelize_drm.pytest_new_freq_method_supported: + async_cb.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('frequency_detection_method') == 1 + print("Test parameter 'frequency_detection_method': PASS") + + # Test parameter: bypass_frequency_detection + if accelize_drm.pytest_new_freq_method_supported: + async_cb.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert not drm_manager.get('bypass_frequency_detection') + conf_json.reset() + conf_json['drm']['bypass_frequency_detection'] = True + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('bypass_frequency_detection') + print("Test parameter 'bypass_frequency_detection': PASS") + + # Test parameter: drm_frequency + async_cb.reset() + conf_json.reset() + exp_value = 2*orig_frequency_mhz + conf_json['drm']['bypass_frequency_detection'] = True + conf_json['drm']['frequency_mhz'] = exp_value + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('drm_frequency') == exp_value + async_cb.assert_NoError() + print("Test parameter 'drm_frequency': PASS") + + # Test parameter: frequency_detection_period + async_cb.reset() + conf_json.reset() + exp_value = 2*orig_frequency_detect_period + conf_json['settings'] = {'frequency_detection_period': exp_value} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + value = drm_manager.get('frequency_detection_period') + assert value == exp_value + async_cb.assert_NoError() + print("Test parameter 'frequency_detection_period': PASS") + + # Test parameter: frequency_detection_threshold + async_cb.reset() + conf_json.reset() + exp_value = 2*orig_frequency_detect_threshold + conf_json['settings'] = {'frequency_detection_threshold': exp_value} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + value = drm_manager.get('frequency_detection_threshold') + assert value == exp_value + async_cb.assert_NoError() + print("Test parameter 'frequency_detection_threshold': PASS") + + # Test parameter: ws_retry_period_long + async_cb.reset() + conf_json.reset() + # Check error: ws_retry_period_long must be != ws_retry_period_short + conf_json['settings'] = {'ws_retry_period_long': orig_retry_period_short} + conf_json.save() + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert search(r'ws_retry_period_long .+ must be greater than ws_retry_period_short .+', + str(excinfo.value)) is not None + err_code = async_handler.get_error_code(str(excinfo.value)) + assert err_code == accelize_drm.exceptions.DRMBadArg.error_code + async_cb.assert_NoError() + + async_cb.reset() + conf_json.reset() + exp_value = orig_retry_period_long + 1 + conf_json['settings'] = {'ws_retry_period_long': exp_value} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + value = drm_manager.get('ws_retry_period_long') + assert value == exp_value + async_cb.assert_NoError() + print("Test parameter 'ws_retry_period_long': PASS") + + # Test parameter: ws_retry_period_short + async_cb.reset() + conf_json.reset() + # Check error: ws_retry_period_long must be != ws_retry_period_short + conf_json['settings'] = {'ws_retry_period_short': orig_retry_period_long} + conf_json.save() + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert search(r'ws_retry_period_long .+ must be greater than ws_retry_period_short .+', + str(excinfo.value)) is not None + err_code = async_handler.get_error_code(str(excinfo.value)) + assert err_code == accelize_drm.exceptions.DRMBadArg.error_code + async_cb.assert_NoError() + + async_cb.reset() + conf_json.reset() + exp_value = orig_retry_period_short + 1 + conf_json['settings'] = {'ws_retry_period_short': exp_value} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + value = drm_manager.get('ws_retry_period_short') + assert value == exp_value + async_cb.assert_NoError() + print("Test parameter 'ws_retry_period_short': PASS") + + # Test parameter: ws_api_retry_duration + async_cb.reset() + conf_json.reset() + conf_json['settings'] = {'ws_api_retry_duration': 0} + conf_json.save() + accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + async_cb.reset() + conf_json.reset() + exp_value = orig_api_retry_duration + 1 + conf_json['settings'] = {'ws_api_retry_duration': exp_value} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + value = drm_manager.get('ws_api_retry_duration') + assert value == exp_value + async_cb.assert_NoError() + print("Test parameter 'ws_api_retry_duration': PASS") + + # Test parameter: ws_request_timeout + async_cb.reset() + conf_json.reset() + conf_json['settings'] = {'ws_request_timeout': 0} + conf_json.save() + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert "ws_request_timeout must not be 0" in str(excinfo.value) + err_code = async_handler.get_error_code(str(excinfo.value)) + assert err_code == accelize_drm.exceptions.DRMBadArg.error_code + async_cb.reset() + conf_json.reset() + exp_value = 2*orig_request_timeout + conf_json['settings'] = {'ws_request_timeout': exp_value} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + value = drm_manager.get('ws_request_timeout') + assert value == exp_value + async_cb.assert_NoError() + print("Test parameter 'ws_request_timeout': PASS") + + # Test parameter: host_data_verbosity + async_cb.reset() + conf_json.reset() + expectVal = 0 + conf_json['settings'] = {'host_data_verbosity': expectVal} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('host_data_verbosity') == expectVal + + conf_json.reset() + expectVal = 2 + conf_json['settings'] = {'host_data_verbosity': expectVal} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('host_data_verbosity') == expectVal + async_cb.assert_NoError() + print("Test parameter 'host_data_verbosity': PASS") + + # Test parameter: log_file_append + async_cb.reset() + conf_json.reset() + expectVal = False + conf_json['settings'] = {'log_file_append': expectVal} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_file_append') == expectVal + + conf_json.reset() + expectVal = True + conf_json['settings'] = {'log_file_append': expectVal} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_file_append') == expectVal + async_cb.assert_NoError() + print("Test parameter 'log_file_append': PASS") + + # Test parameter: ws_verbosity + async_cb.reset() + conf_json.reset() + expectVal = 1 + conf_json['settings'] = {'ws_verbosity': expectVal} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('ws_verbosity') == expectVal + + conf_json.reset() + expectVal = 0 + conf_json['settings'] = {'ws_verbosity': expectVal} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('ws_verbosity') == expectVal + async_cb.assert_NoError() + print("Test parameter 'ws_verbosity': PASS") + + # Test unsupported parameter + async_cb.reset() + conf_json.reset() + conf_json['settings'] = {'unsupported_param': 10.2} + conf_json.save() + accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + async_cb.assert_NoError() + print("Test unsupported parameter: PASS") + + # Test empty parameter + async_cb.reset() + conf_json.reset() + conf_json['settings'] = {'': 10.2} + conf_json.save() + accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + async_cb.assert_NoError() + print("Test empty parameter: PASS") + + +def test_parameter_key_modification_with_get_set(accelize_drm, conf_json, cred_json, async_handler, + ws_admin): + """Test accesses to parameter""" + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + activators = accelize_drm.pytest_fpga_activators[0] + activators.reset_coin() + + print() + + # Test with a nodelocked user + + # Test parameter: license_type and drm_license_type in nodelocked and nodelocked_request_file + # => Done in test_nodelock_mode_on_hw + + # Test with a floating/metered user + + async_cb.reset() + cred_json.set_user('accelize_accelerator_test_02') + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + + # Test when parameter is a list + value = drm_manager.get('num_activators','license_type') + assert isinstance(value, dict) + assert value['num_activators'] == activators.length + assert value['license_type'] == 'Floating/Metering' + async_cb.assert_NoError() + print("Test when parameter is a list: PASS") + + # Test parameter: log_verbosity + orig_val = drm_manager.get('log_verbosity') + exp_val = 1 if orig_val == 0 else 0 + drm_manager.set(log_verbosity=exp_val) + assert drm_manager.get('log_verbosity') == exp_val + drm_manager.set(log_verbosity=orig_val) + async_cb.assert_NoError() + print("Test parameter 'log_verbosity': PASS") + + # Test parameter: log_format + orig_val = drm_manager.get('log_format') + exp_val = LOG_FORMAT_LONG + drm_manager.set(log_format=exp_val) + assert drm_manager.get('log_format') == exp_val + drm_manager.set(log_format=orig_val) + async_cb.assert_NoError() + print("Test parameter 'log_format': PASS") + + # Test parameter: log_file_verbosity + orig_val = drm_manager.get('log_file_verbosity') + exp_val = 1 if orig_val == 0 else 0 + drm_manager.set(log_file_verbosity=exp_val) + assert drm_manager.get('log_file_verbosity') == exp_val + drm_manager.set(log_file_verbosity=orig_val) + async_cb.assert_NoError() + print("Test parameter 'log_file_verbosity': PASS") + + # Test parameter: log_file_format + orig_val = drm_manager.get('log_file_format') + assert orig_val == LOG_FORMAT_LONG + exp_val = LOG_FORMAT_SHORT + drm_manager.set(log_file_format=exp_val) + assert drm_manager.get('log_file_format') == exp_val + drm_manager.set(log_file_format=orig_val) + async_cb.assert_NoError() + print("Test parameter 'log_file_format': PASS") + + # Test parameter: log_file_path, log_file_type, log_file_rotating_size, log_file_rotating_num + # => Cannot be written programmatically + + # Test parameter: license_type in metering + assert drm_manager.get('license_type') == 'Floating/Metering' + async_cb.assert_NoError() + print("Test parameter 'license_type' in Metered: PASS") + + # Test parameter: drm_license_type, license_duration + drm_manager.activate() + assert drm_manager.get('drm_license_type') == 'Floating/Metering' + assert drm_manager.get('license_duration') != 0 + drm_manager.deactivate() + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(license_duration=10) + assert "Parameter 'license_duration' cannot be overwritten" in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadArg.error_code + async_cb.assert_NoError() + print("Test parameter 'drm_license_type', 'license_duration': PASS") + + # Test parameter: num_activators + nb_activator = drm_manager.get('num_activators') + assert nb_activator == activators.length, 'Unexpected number of activators' + print("Test parameter 'num_activators': PASS") + + # Test parameter: session_id + drm_manager.activate() + sessionId = drm_manager.get('session_id') + assert len(sessionId) == 16, 'Unexpected length of session ID' + drm_manager.deactivate() + async_cb.assert_NoError() + print("Test parameter 'session_id': PASS") + + # Test parameter: session_status + session_state = drm_manager.get('session_status') + assert not session_state + drm_manager.activate() + session_state = drm_manager.get('session_status') + assert session_state + drm_manager.deactivate() + session_state = drm_manager.get('session_status') + assert not session_state + async_cb.assert_NoError() + print("Test parameter 'session_status': PASS") + + # Test parameter: license_status + assert not drm_manager.get('license_status') + drm_manager.activate() + assert drm_manager.get('license_status') + drm_manager.deactivate() + assert not drm_manager.get('license_status') + async_cb.assert_NoError() + print("Test parameter 'license_status': PASS") + + # Test parameter: metered_data + drm_manager.activate() + activators[0].generate_coin(10) + activators[0].check_coin(drm_manager.get('metered_data')) + async_cb.assert_NoError() + drm_manager.deactivate() + activators[0].reset_coin() + + print("Test parameter 'metered_data': PASS") + + # Test parameter: page_ctrlreg + page = drm_manager.get('page_ctrlreg') + assert search(r'Register\s+@0x00:\s+0x00000000', page), 'Unexpected content of page_ctrlreg' + print("Test parameter 'page_ctrlreg': PASS") + + # Test parameter: page_vlnvfile + page = drm_manager.get('page_vlnvfile') + assert search(r'Register\s+@0x00:\s+0x00000001', page), 'Unexpected content of page_vlnvfile' + print("Test parameter 'page_vlnvfile': PASS") + + # Test parameter: page_licfile + page = drm_manager.get('page_licfile') + assert search(r'Register\s+@0x00:\s+0x00000002', page), 'Unexpected content of page_licfile' + print("Test parameter 'page_licfile': PASS") + + # Test parameter: page_tracefile + page = drm_manager.get('page_tracefile') + assert search(r'Register\s+@0x00:\s+0x00000003', page), 'Unexpected content of page_tracefile' + print("Test parameter 'page_tracefile': PASS") + + # Test parameter: page_meteringfile + page = drm_manager.get('page_meteringfile') + assert search(r'Register\s+@0x00:\s+0x00000004', page), 'Unexpected content of page_meteringfile' + print("Test parameter 'page_meteringfile': PASS") + + # Test parameter: page_mailbox + page = drm_manager.get('page_mailbox') + assert search(r'Register\s+@0x00:\s+0x00000005', page), 'Unexpected content of page_mailbox' + print("Test parameter 'page_mailbox': PASS") + + # Test parameter: hw_report + hw_report = drm_manager.get('hw_report') + nb_lines = len(tuple(finditer(r'\n', hw_report))) + assert nb_lines > 10, 'Unexpected HW report content' + print("Test parameter 'hw_report': PASS") + + # Test parameter: frequency_detection_threshold + orig_freq_threhsold = drm_manager.get('frequency_detection_threshold') # Save original threshold + exp_freq_threhsold = orig_freq_threhsold * 2 + drm_manager.set(frequency_detection_threshold=exp_freq_threhsold) + new_freq_threhsold = drm_manager.get('frequency_detection_threshold') + assert new_freq_threhsold == exp_freq_threhsold, 'Unexpected frequency dectection threshold percentage' + drm_manager.set(frequency_detection_threshold=orig_freq_threhsold) # Restore original threshold + print("Test parameter 'frequency_detection_threshold': PASS") + + # Test parameter: frequency_detection_period + orig_freq_period = drm_manager.get('frequency_detection_period') # Save original period + exp_freq_period = orig_freq_period * 2 + drm_manager.set(frequency_detection_period=exp_freq_period) + new_freq_period = drm_manager.get('frequency_detection_period') + assert new_freq_period == exp_freq_period, 'Unexpected frequency dectection period' + drm_manager.set(frequency_detection_period=orig_freq_period) # Restore original period + print("Test parameter 'frequency_detection_period': PASS") + + # Test parameter: drm_frequency + freq_period = drm_manager.get('frequency_detection_period') # Save original period + drm_manager.activate() + #sleep(2.0*freq_period/1000) + freq_drm = drm_manager.get('drm_frequency') + drm_manager.deactivate() + assert 125 <= freq_drm <= 126, 'Unexpected frequency gap threshold' + print("Test parameter 'drm_frequency': PASS") + + # Test parameter: product_info + from pprint import pformat + product_id = pformat(drm_manager.get('product_info')) + exp_product_id = pformat(activators.product_id) + assert product_id == exp_product_id, 'Unexpected product ID' + print("Test parameter 'product_info': PASS") + + # Test parameter: mailbox_size + mailbox_size = drm_manager.get('mailbox_size') + assert mailbox_size == 14, 'Unexpected Mailbox size' + print("Test parameter 'mailbox_size': PASS") + + # Test parameter: token_string, token_validity and token_time_left + drm_manager.activate() + token_time_left = drm_manager.get('token_time_left') + if token_time_left < 15: + drm_manager.deactivate() + sleep(16) + drm_manager.activate() + token_string = drm_manager.get('token_string') + assert len(token_string) > 0 + token_validity = drm_manager.get('token_validity') + assert token_validity > 15 + token_time_left = drm_manager.get('token_time_left') + sleep(2) + assert 2 <= token_time_left - drm_manager.get('token_time_left') <= 3 + assert drm_manager.get('token_validity') == token_validity + assert token_string == drm_manager.get('token_string') + drm_manager.deactivate() + print("Test parameter 'token_string', 'token_validity' and 'token_time_left': PASS") + + # Test parameter: list_all + list_param = drm_manager.get('list_all') + assert isinstance(list_param , list) + assert len(list_param) == len(_PARAM_LIST) + assert all(key in _PARAM_LIST for key in list_param) + print("Test parameter 'list_all': PASS") + + # Test parameter: dump_all + dump_param = drm_manager.get('dump_all') + assert isinstance(dump_param, dict) + assert len(dump_param) == _PARAM_LIST.index('dump_all') + assert all(key in _PARAM_LIST for key in dump_param.keys()) + print("Test parameter 'dump_all': PASS") + + # Test parameter: custom_field + from random import randint + val_exp = randint(0,0xFFFFFFFF) + val_init = drm_manager.get('custom_field') + assert val_exp != val_init + drm_manager.set(custom_field=val_exp) + assert drm_manager.get('custom_field') == val_exp + print("Test parameter 'custom_field': PASS") + + # Test parameter: mailbox_data + from random import sample + mailbox_size = drm_manager.get('mailbox_size') + wr_msg = sample(range(0xFFFFFFFF), mailbox_size) + drm_manager.set(mailbox_data=wr_msg) + rd_msg = drm_manager.get('mailbox_data') + assert type(rd_msg) == type(wr_msg) == list + assert rd_msg == wr_msg + print("Test parameter 'mailbox_data': PASS") + + # Test parameter: ws_retry_period_long + orig_retry_period_long = drm_manager.get('ws_retry_period_long') # Save original value + orig_retry_period_short = drm_manager.get('ws_retry_period_short') + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(ws_retry_period_long=orig_retry_period_short) + assert search(r'ws_retry_period_long .+ must be greater than ws_retry_period_short .+', + str(excinfo.value)) is not None + err_code = async_handler.get_error_code(str(excinfo.value)) + assert err_code == accelize_drm.exceptions.DRMBadArg.error_code + exp_value = orig_retry_period_long + 1 + drm_manager.set(ws_retry_period_long=exp_value) + assert drm_manager.get('ws_retry_period_long') == exp_value + drm_manager.set(ws_retry_period_long=orig_retry_period_long) # Restore original value + async_cb.assert_NoError() + print("Test parameter 'ws_retry_period_long': PASS") + + # Test parameter: ws_retry_period_short + orig_retry_period_short = drm_manager.get('ws_retry_period_short') # Save original value + orig_retry_period_long = drm_manager.get('ws_retry_period_long') + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(ws_retry_period_short=orig_retry_period_long) + assert search(r'ws_retry_period_long .+ must be greater than ws_retry_period_short .+', + str(excinfo.value)) is not None + err_code = async_handler.get_error_code(str(excinfo.value)) + assert err_code == accelize_drm.exceptions.DRMBadArg.error_code + exp_value = orig_retry_period_short + 1 + drm_manager.set(ws_retry_period_short=exp_value) + assert drm_manager.get('ws_retry_period_short') == exp_value + drm_manager.set(ws_retry_period_short=orig_retry_period_short) # Restore original value + async_cb.assert_NoError() + print("Test parameter 'ws_retry_period_short': PASS") + + # Test parameter: ws_api_retry_duration + orig_api_retry_duration = drm_manager.get('ws_api_retry_duration') # Save original value + exp_value = 0 + drm_manager.set(ws_api_retry_duration=exp_value) + assert drm_manager.get('ws_api_retry_duration') == exp_value + exp_value = orig_api_retry_duration + 100 + drm_manager.set(ws_api_retry_duration=exp_value) + assert drm_manager.get('ws_api_retry_duration') == exp_value + drm_manager.set(ws_api_retry_duration=orig_api_retry_duration) # Restore original value + async_cb.assert_NoError() + print("Test parameter 'ws_api_retry_duration': PASS") + + # Test parameter: ws_request_timeout + orig_request_timeout = drm_manager.get('ws_request_timeout') + 100 + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(ws_request_timeout=0) + assert "Parameter 'ws_request_timeout' cannot be overwritten" in str(excinfo.value) + async_cb.assert_NoError() + print("Test parameter 'ws_request_timeout': PASS") + + # Test parameter: log_message_level + level = drm_manager.get('log_message_level') + exp_level = 5 if level!=5 else 4 + drm_manager.set(log_message_level=exp_level) + assert drm_manager.get('log_message_level') == exp_level + async_cb.assert_NoError() + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(log_message_level=100) + assert 'log_message_level (100) is out of range [0:6]' in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadArg.error_code + async_cb.assert_NoError() + print("Test parameter 'log_message_level': PASS") + + # Test parameter: trigger_async_callback + drm_manager.activate() + test_message = 'Test message' + drm_manager.set(trigger_async_callback=test_message) + assert async_cb.was_called, 'Asynchronous callback has not been called.' + assert async_cb.message is not None, 'Asynchronous callback did not report any message' + assert test_message in async_cb.message, 'Asynchronous callback has not received the correct message' + assert async_cb.errcode == accelize_drm.exceptions.DRMDebug.error_code, \ + 'Asynchronous callback has not received the correct error code' + drm_manager.deactivate() + async_cb.reset() + async_cb.assert_NoError() + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.get('trigger_async_callback') + assert "Parameter 'trigger_async_callback' cannot be read" in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadArg.error_code + async_cb.assert_NoError() + print("Test parameter 'trigger_async_callback': PASS") + + # Test parameter: ParameterKeyCount + assert drm_manager.get('ParameterKeyCount') == len(_PARAM_LIST) + async_cb.assert_NoError() + print("Test parameter 'ParameterKeyCount': PASS") + + # Test parameter: log_message + async_cb.reset() + conf_json.reset() + logpath = accelize_drm.create_log_path(whoami()) + verbosity = 5 + conf_json['settings']['log_file_verbosity'] = verbosity + conf_json['settings']['log_file_type'] = 1 + conf_json['settings']['log_file_path'] = logpath + conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + drm_manager.set(log_message_level=verbosity) + msg = 'This line should appear in log file' + drm_manager.set(log_message=msg) + del drm_manager + wait_func_true(lambda: isfile(logpath), 10) + with open(logpath, 'rt') as f: + log_content = f.read() + assert "critical" in log_content + assert msg in log_content + async_cb.assert_NoError() + remove(logpath) + print("Test parameter 'log_message': PASS") + + # Test parameter: hdk_compatibility + async_cb.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + hdk_limit = drm_manager.get('hdk_compatibility') + assert match(r'\d+\.\d', hdk_limit) + async_cb.assert_NoError() + print("Test parameter 'hdk_compatibility': PASS") + + # Test parameter: health_period + async_cb.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('health_period') == 0 + async_cb.assert_NoError() + print("Test parameter 'health_period': PASS") + + # Test parameter: health_retry + async_cb.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('health_retry') == drm_manager.get('ws_api_retry_duration') + async_cb.assert_NoError() + print("Test parameter 'health_retry': PASS") + + # Test parameter: health_retry_sleep + async_cb.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('health_retry_sleep') == drm_manager.get('ws_retry_period_short') + async_cb.assert_NoError() + print("Test parameter 'health_retry_sleep': PASS") + + # Test parameter: host_data_verbosity + async_cb.reset() + conf_json.reset() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('host_data_verbosity') == 1 + expectVal = 0 + conf_json['settings']['host_data_verbosity'] = expectVal + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('host_data_verbosity') == expectVal + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(host_data_verbosity=2) # Test it cannot be written from code + assert "Parameter 'host_data_verbosity' cannot be overwritten" in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadArg.error_code + async_cb.assert_NoError() + print("Test parameter 'host_data_verbosity': PASS") + + # Test parameter: host_data + async_cb.reset() + conf_json.reset() + conf_json['settings'] = {'host_data': 0} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + if 'XRT_PATH' in environ: + assert type(drm_manager.get('host_data')) == dict + assert len(drm_manager.get('host_data')) + else: + assert drm_manager.get('host_data') is None + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(host_data={'test':'test'}) + async_cb.assert_NoError() + print("Test parameter 'host_data': PASS") + + # Test parameter: log_file_append + async_cb.reset() + conf_json.reset() + conf_json['settings'] = {'log_file_append': False} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('log_file_append') == False + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(log_file_append=True) + async_cb.assert_NoError() + print("Test parameter 'log_file_append': PASS") + + # Test parameter: ws_verbosity + async_cb.reset() + conf_json.reset() + expvalue = 0 + conf_json['settings'] = {'ws_verbosity': expvalue} + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert drm_manager.get('ws_verbosity') == expvalue + with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: + drm_manager.set(ws_verbosity=1) + async_cb.assert_NoError() + print("Test parameter 'ws_verbosity': PASS") + + +def test_configuration_file_with_bad_authentication(accelize_drm, conf_json, cred_json, + async_handler): + """Test errors when bad authentication parameters are provided to + DRM Manager Constructor or Web Service.""" + + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + + drm_manager = None + print() + try: + # Test when authentication url in configuration file is wrong + async_cb.reset() + cred_json.set_user('accelize_accelerator_test_02') + conf_json.reset() + conf_json['licensing']['url'] = "http://acme.com" + conf_json['settings']['ws_api_retry_duration'] = 5 + conf_json['settings']['ws_retry_period_short'] = 1 + conf_json.save() + assert conf_json['licensing']['url'] == "http://acme.com" + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: + drm_manager.activate() + assert "OAuth2 Web Service error 404" in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code + async_cb.assert_NoError() + print('Test when authentication url in configuration file is wrong: PASS') + + # Test when client_id is wrong + async_cb.reset() + conf_json.reset() + cred_json.set_user('accelize_accelerator_test_02') + orig_client_id = cred_json.client_id + replaced_char = 'A' if orig_client_id[0]!='A' else 'B' + cred_json.client_id = orig_client_id.replace(orig_client_id[0], replaced_char) + assert orig_client_id != cred_json.client_id + cred_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: + drm_manager.activate() + assert "OAuth2 Web Service error 401" in str(excinfo.value) + assert "invalid_client" in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code + async_cb.assert_NoError() + print('Test when client_id is wrong: PASS') + + # Test when client_secret is wrong + async_cb.reset() + conf_json.reset() + cred_json.set_user('accelize_accelerator_test_02') + orig_client_secret = cred_json.client_secret + replaced_char = 'A' if orig_client_secret[0]!='A' else 'B' + cred_json.client_secret = orig_client_secret.replace(orig_client_secret[0], replaced_char) + cred_json.save() + assert orig_client_secret != cred_json.client_secret + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: + drm_manager.activate() + assert "OAuth2 Web Service error 401" in str(excinfo.value) + assert "invalid_client" in str(excinfo.value) + assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code + async_cb.assert_NoError() + print('Test when client_secret is wrong: PASS') + + finally: + if drm_manager: + drm_manager.deactivate() diff --git a/tests/test_python_library.py b/tests/test_python_library.py index c1f0139c..18b8a2d1 100644 --- a/tests/test_python_library.py +++ b/tests/test_python_library.py @@ -116,15 +116,15 @@ def test_python_lint(): Static code lint to detect errors and reach code quality standard. """ from subprocess import run, PIPE, STDOUT - from glob import glob - run_kwargs = dict(universal_newlines=True, stderr=STDOUT, stdout=PIPE) - commands = [('flake8', 'python_src', '--ignore', 'E501')] - for f in glob('python_src/src/*.pyx'): - commands.append(('flake8', f, - # Cython specific - '--ignore', 'E211,E225,E226,E227,E999')) + flake8 = ['flake8', 'python_src', '--ignore', 'E501'] + commands = ( + # Standard Python files + flake8, + # Cython files (Ignore incompatible rules) + flake8 + ['--filename', '*.pyx', '--ignore', 'E211,E225,E226,E227,E999'] + ) stdouts = [] for command in commands: diff --git a/tests/test_retry_mechanism.py b/tests/test_retry_mechanism.py new file mode 100644 index 00000000..201cd54c --- /dev/null +++ b/tests/test_retry_mechanism.py @@ -0,0 +1,234 @@ +# -*- coding: utf-8 -*- +""" +Test node-locked behavior of DRM Library. +""" +import pytest +import gc +from glob import glob +from os import remove, getpid +from os.path import getsize, isfile, dirname, join, realpath +from re import match, search, finditer, findall, MULTILINE, IGNORECASE +from time import sleep, time +from json import loads +from datetime import datetime, timedelta +from flask import request +from dateutil import parser +from math import ceil + +from tests.conftest import wait_func_true, whoami +from tests.proxy import get_context, set_context + + +@pytest.mark.no_parallel +def test_api_retry_disabled(accelize_drm, conf_json, cred_json, async_handler, live_server): + """ + Test retry mechanism is disabled on API function (not including the retry in background thread) + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_api_retry' + conf_json['settings']['ws_api_retry_duration'] = 0 # Disable retry on function call + logpath = accelize_drm.create_log_path(whoami()) + conf_json['settings']['log_file_verbosity'] = accelize_drm.create_log_level(2) + conf_json['settings']['log_file_path'] = logpath + conf_json['settings']['log_file_type'] = 1 + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert not drm_manager.get('license_status') + start = datetime.now() + with pytest.raises(accelize_drm.exceptions.DRMWSMayRetry) as excinfo: + drm_manager.activate() + end = datetime.now() + del drm_manager + assert (end - start).total_seconds() < 1 + wait_func_true(lambda: isfile(logpath), 10) + with open(logpath, 'rt') as f: + log_content = f.read() + assert search(r'\[\s*critical\s*\]\s*\d+\s*,\s*\[errCode=\d+\]\s*Metering Web Service error 408', + log_content, IGNORECASE) + assert not search(r'attempt', log_content, IGNORECASE) + async_cb.assert_NoError() + remove(logpath) + + +@pytest.mark.no_parallel +def test_api_retry_enabled(accelize_drm, conf_json, cred_json, async_handler, live_server): + """ + Test retry mechanism is working on API function (not including the retry in background thread) + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + retry_duration = 10 + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_api_retry' + conf_json['settings']['ws_api_retry_duration'] = retry_duration # Set retry duration to 10s + logpath = accelize_drm.create_log_path(whoami()) + conf_json['settings']['log_file_verbosity'] = accelize_drm.create_log_level(2) + conf_json['settings']['log_file_path'] = logpath + conf_json['settings']['log_file_type'] = 1 + conf_json.save() + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + assert not drm_manager.get('license_status') + retry_sleep = drm_manager.get('ws_retry_period_short') + start = datetime.now() + with pytest.raises(accelize_drm.exceptions.DRMWSError) as excinfo: + drm_manager.activate() + end = datetime.now() + del drm_manager + total_seconds = int((end - start).total_seconds()) + assert retry_duration <= total_seconds <= retry_duration + 1 + wait_func_true(lambda: isfile(logpath), 10) + with open(logpath, 'rt') as f: + log_content = f.read() + m = search(r'\[\s*critical\s*\]\s*\d+\s*,\s*\[errCode=\d+\]\s*Timeout on License request after (\d+) attempts', + log_content, IGNORECASE) + assert m is not None + nb_attempts = int(m.group(1)) + nb_attempts_expected = retry_duration / retry_sleep + assert nb_attempts_expected - 1 <= nb_attempts <= nb_attempts_expected + 1 + async_cb.assert_NoError() + remove(logpath) + + +@pytest.mark.no_parallel +def test_long_to_short_retry_switch(accelize_drm, conf_json, cred_json, async_handler, live_server): + """ + Test the number of expected retris and the gap between 2 retries are correct when a retryable error is returned + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + + retryShortPeriod = 3 + retryLongPeriod = 10 + timeoutSecondFirst2 = 3 + timeoutSecond = 20 + + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_long_to_short_retry_switch' + conf_json['settings']['ws_retry_period_short'] = retryShortPeriod + conf_json['settings']['ws_retry_period_long'] = retryLongPeriod + conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + + context = {'data':list(), + 'cnt':0, + 'timeoutSecondFirst2':timeoutSecondFirst2, + 'timeoutSecond':timeoutSecond + } + set_context(context) + assert get_context() == context + + drm_manager.activate() + try: + wait_func_true(lambda: async_cb.was_called, + timeout=timeoutSecondFirst2 + 2*timeoutSecond + 2) + finally: + drm_manager.deactivate() + assert async_cb.was_called + assert 'Timeout on License' in async_cb.message + assert async_cb.errcode == accelize_drm.exceptions.DRMWSError.error_code + context = get_context() + data_list = context['data'] + nb_long_retry = int(timeoutSecond / retryLongPeriod) + nb_short_retry = int(retryLongPeriod / retryShortPeriod) + assert (nb_long_retry+nb_short_retry) <= len(data_list) <= (1+nb_long_retry+nb_short_retry) + data = data_list.pop(0) + assert data[0] == 'running' + prev_lic = parser.parse(data[2]) + for i, (type, start, end) in enumerate(data_list): + lic_delta = int((parser.parse(start) - prev_lic).total_seconds()) + prev_lic = parser.parse(end) + if i < nb_long_retry-1: + assert (retryLongPeriod-1) <= lic_delta <= (retryLongPeriod+1) + else: + assert (retryShortPeriod-1) <= lic_delta <= (retryShortPeriod+1) + + +@pytest.mark.no_parallel +def test_retry_on_no_connection(accelize_drm, conf_json, cred_json, async_handler, live_server): + """ + Test the number of expected retries and the gap between 2 retries are correct when the requests are lost + """ + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + + retryShortPeriod = 2 + retryLongPeriod = 20 + licDuration = 60 + requestTimeout = 5 + nb_long_retry = ceil((licDuration - retryLongPeriod)/(retryLongPeriod + requestTimeout)) + print('nb_long_retry=', nb_long_retry, type(nb_long_retry)) + nb_short_retry = ceil((licDuration - nb_long_retry*(retryLongPeriod + requestTimeout)) / (retryShortPeriod + requestTimeout)) + print('nb_short_retry=', nb_short_retry, type(nb_short_retry)) + nb_retry = nb_long_retry + nb_short_retry + + conf_json.reset() + conf_json['licensing']['url'] = request.url + 'test_retry_on_no_connection' + conf_json['settings']['ws_retry_period_short'] = retryShortPeriod + conf_json['settings']['ws_retry_period_long'] = retryLongPeriod + conf_json['settings']['ws_request_timeout'] = requestTimeout + logpath = accelize_drm.create_log_path(whoami()) + conf_json['settings']['log_file_verbosity'] = accelize_drm.create_log_level(1) + conf_json['settings']['log_file_type'] = 1 + conf_json['settings']['log_file_path'] = logpath + conf_json.save() + + drm_manager = accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) + + context = {'cnt':0, + 'timeoutSecond':licDuration + } + set_context(context) + assert get_context() == context + + drm_manager.activate() + try: + wait_func_true(lambda: async_cb.was_called, + timeout=licDuration*2) + finally: + drm_manager.deactivate() + del drm_manager + assert async_cb.was_called + assert async_cb.errcode == accelize_drm.exceptions.DRMWSError.error_code + m = search(r'Timeout on License request after (\d+) attempts', async_cb.message) + assert m is not None + nb_attempts = int(m.group(1)) + assert nb_retry == nb_attempts + wait_func_true(lambda: isfile(logpath), 10) + with open(logpath, 'rt') as f: + log_content = f.read() + attempts_list = [int(e) for e in findall(r'Attempt #(\d+) to obtain a new License failed with message', log_content)] + assert len(attempts_list) == nb_retry + assert sorted(list(attempts_list)) == list(range(1,nb_retry+1)) + remove(logpath) + diff --git a/tests/test_trng_quality.py b/tests/test_trng_quality.py index 5761a15d..3fa6c4e4 100644 --- a/tests/test_trng_quality.py +++ b/tests/test_trng_quality.py @@ -4,7 +4,6 @@ """ import pytest import sys -import gc import re from glob import glob from os import remove @@ -14,6 +13,7 @@ from json import loads, dumps from datetime import datetime, timedelta from random import randrange +from tests.conftest import wait_func_true SAMPLES_DUPLICATE_THRESHOLD = 2 @@ -194,7 +194,7 @@ def test_dna_and_challenge_duplication(accelize_drm, conf_json, cred_json, async async_cb.reset() cred_json.set_user(access_key) conf_json.reset() - logpath = realpath("./drmlib.%d.%d.log" % (time(), randrange(0xFFFFFFFF))) + logpath = accelize_drm.create_log_path(whoami()) conf_json['settings']['log_file_verbosity'] = 1 conf_json['settings']['log_file_type'] = 1 conf_json['settings']['log_file_path'] = logpath @@ -246,7 +246,7 @@ def test_dna_and_challenge_duplication(accelize_drm, conf_json, cred_json, async sleep(1) activators.autotest(is_activated=False) del drm_manager - gc.collect() + wait_func_true(lambda: isfile(logpath), 10) if no_err: session_cnt += 1 async_cb.assert_NoError() diff --git a/tests/test_unittest_on_hw.py b/tests/test_unittest_on_hw.py index 2c1df0c7..5441c81f 100644 --- a/tests/test_unittest_on_hw.py +++ b/tests/test_unittest_on_hw.py @@ -3,1677 +3,17 @@ Test node-locked behavior of DRM Library. """ import pytest -import gc -from glob import glob -from os import remove, getpid -from os.path import getsize, isfile, dirname, join, realpath -from re import match, search, finditer, MULTILINE, IGNORECASE -from time import sleep, time -from json import loads +from re import search, IGNORECASE +from time import sleep from datetime import datetime, timedelta -from time import time - - -LOG_FORMAT_SHORT = "[%^%=8l%$] %-6t, %v" -LOG_FORMAT_LONG = "%Y-%m-%d %H:%M:%S.%e - %18s:%-4# [%=8l] %=6t, %v" - -REGEX_FORMAT_SHORT = r'\[\s*(\w+)\s*\] \s*\d+\s*, %s' -REGEX_FORMAT_LONG = r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3} - \s*\S+:\d+\s* \[\s*(\w+)\s*\] \s*\d+\s*, %s' - - -_PARAM_LIST = ['license_type', - 'license_duration', - 'num_activators', - 'session_id', - 'session_status', - 'license_status', - 'metered_data', - 'nodelocked_request_file', - 'drm_frequency', - 'drm_license_type', - 'product_info', - 'mailbox_size', - 'token_string', - 'token_validity', - 'token_time_left', - 'log_verbosity', - 'log_format', - 'log_file_verbosity', - 'log_file_format', - 'log_file_path', - 'log_file_type', - 'log_file_rotating_size', - 'log_file_rotating_num', - 'bypass_frequency_detection', - 'frequency_detection_method', - 'frequency_detection_threshold', - 'frequency_detection_period', - 'custom_field', - 'mailbox_data', - 'ws_retry_period_long', - 'ws_retry_period_short', - 'ws_request_timeout', - 'log_message_level', - 'list_all', - 'dump_all', - 'page_ctrlreg', - 'page_vlnvfile', - 'page_licfile', - 'page_tracefile', - 'page_meteringfile', - 'page_mailbox', - 'hw_report', - 'trigger_async_callback', - 'bad_product_id', - 'bad_oauth2_token', - 'log_message'] - - -def ordered_json(obj): - if isinstance(obj, dict): - return sorted((k, ordered_json(v)) for k, v in obj.items()) - if isinstance(obj, list): - return sorted(ordered_json(x) for x in obj) - else: - return obj +from flask import request @pytest.mark.minimum -def test_backward_compatibility(accelize_drm, conf_json, cred_json, async_handler): - from itertools import groupby - """Test API is not compatible with DRM HDK < 3.0""" - refdesign = accelize_drm.pytest_ref_designs - hdk_version = accelize_drm.pytest_hdk_version - if hdk_version is None: - pytest.skip("FPGA image is not corresponding to a known HDK version") - - current_major = float(match(r'^(\d+\.\d+)\.', hdk_version).group(1)) - driver = accelize_drm.pytest_fpga_driver[0] - fpga_image_bkp = driver.fpga_image - async_cb = async_handler.create() - drm_manager = None - - try: - refdesignByMajor = ((float(match(r'^(\d+\.\d+)\.', x).group(1)), x) for x in refdesign.hdk_versions) - HDK_Limit = 3.1 - - for major, versions in groupby(refdesignByMajor, lambda x: x[0]): - if major >= current_major: - continue - - hdk = sorted((e[1] for e in versions))[0] - # Program FPGA with older HDK - image_id = refdesign.get_image_id(hdk) - driver.program_fpga(image_id) - # Test compatibility issue - async_cb.reset() - try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - if major < HDK_Limit: - raise AssertionError('HDK %s is not compatible but DRMLib did not raise an exception.' % hdk) - except accelize_drm.exceptions.DRMCtlrError as excinfo: - if major < HDK_Limit: - hit = False - if 'Unable to find DRM Controller registers' in str(excinfo): - hit =True - if search(r'This DRM Library version \S+ is not compatible with the DRM HDK version', str(excinfo)): - hit =True - assert hit - assert async_handler.get_error_code(str(excinfo)) == accelize_drm.exceptions.DRMCtlrError.error_code - else: - raise AssertionError('HDK %s is compatible but DRMLib raised an exception.' % hdk) - async_cb.assert_NoError() - print('Test compatibility with %s: PASS' % hdk) - - finally: - if drm_manager: - del drm_manager - gc.collect() - # Reprogram FPGA with original image - driver.program_fpga(fpga_image_bkp) - - -@pytest.mark.minimum -def test_get_version(accelize_drm): - """Test the versions of the DRM Lib and its dependencies are well displayed""" - versions = accelize_drm.get_api_version() - assert search(r'\d+\.\d+\.\d+', versions.version) is not None - - -@pytest.mark.minimum -def test_wrong_drm_controller_address(accelize_drm, conf_json, cred_json, async_handler): - """Test when a wrong DRM Controller offset is given""" - async_cb = async_handler.create() - async_cb.reset() - driver = accelize_drm.pytest_fpga_driver[0] - ctrl_base_addr_backup = driver._drm_ctrl_base_addr - driver._drm_ctrl_base_addr += 0x10000 - try: - with pytest.raises(accelize_drm.exceptions.DRMCtlrError) as excinfo: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert 'Unable to find DRM Controller registers.' in str(excinfo.value) - assert 'Please verify' in str(excinfo.value) - finally: - driver._drm_ctrl_base_addr = ctrl_base_addr_backup - - -@pytest.mark.minimum -@pytest.mark.hwtst -@pytest.mark.no_parallel -def test_users_entitlements(accelize_drm, conf_json, cred_json, async_handler, ws_admin): - """ - Test the entitlements for all accounts used in regression - """ - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - - print() - - # Test user-01 entitlements - # Request metering license - async_cb.reset() - cred_json.set_user('accelize_accelerator_test_01') - conf_json.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('license_type') == 'Floating/Metering' - drmLicType = drm_manager.get('drm_license_type') - with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: - drm_manager.activate() - assert "License Web Service error 400" in str(excinfo.value) - assert "DRM WS request failed" in str(excinfo.value) - assert search(r'\\"No Entitlement\\" with .+ for \S+_test_01@accelize.com', str(excinfo.value)) - assert "User account has no entitlement. Purchase additional licenses via your portal" in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code - async_cb.assert_NoError() - # Request nodelock license - try: - async_cb.reset() - cred_json.set_user('accelize_accelerator_test_01') - conf_json.reset() - conf_json.addNodelock() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('license_type') == 'Node-Locked' - assert drm_manager.get('drm_license_type') == drmLicType - with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: - drm_manager.activate() - assert "License Web Service error 400" in str(excinfo.value) - assert "DRM WS request failed" in str(excinfo.value) - assert search(r'\\"No Entitlement\\" with .+ for \S+_test_01@accelize.com', str(excinfo.value)) - assert "User account has no entitlement. Purchase additional licenses via your portal" in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code - async_cb.assert_NoError() - finally: - accelize_drm.clean_nodelock_env(conf_json=conf_json) - print('Test user-01 entitlements: PASS') - - # Test user-02 entitlements - # Request metering license - async_cb.reset() - cred_json.set_user('accelize_accelerator_test_02') - conf_json.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('license_type') == 'Floating/Metering' - assert drm_manager.get('drm_license_type') == drmLicType - drm_manager.activate() - assert drm_manager.get('drm_license_type') == 'Floating/Metering' - drm_manager.deactivate() - async_cb.assert_NoError() - # Request nodelock license - try: - async_cb.reset() - conf_json.reset() - conf_json.addNodelock() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('license_type') == 'Node-Locked' - assert drm_manager.get('drm_license_type') == 'Floating/Metering' - with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: - drm_manager.activate() - assert "License Web Service error 400" in str(excinfo.value) - assert "DRM WS request failed" in str(excinfo.value) - assert search(r'\\"No Entitlement\\" with .+ for \S+_test_02@accelize.com', str(excinfo.value)) - assert 'No valid NodeLocked entitlement found for your account' in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code - async_cb.assert_NoError() - finally: - accelize_drm.clean_nodelock_env(conf_json=conf_json) - print('Test user-02 entitlements: PASS') - - # Test user-03 entitlements - # Request metering license - cred_json.set_user('accelize_accelerator_test_03') - async_cb.reset() - conf_json.reset() - accelize_drm.clean_metering_env(cred_json, ws_admin) - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('license_type') == 'Floating/Metering' - assert drm_manager.get('drm_license_type') == 'Floating/Metering' - drm_manager.activate() - assert drm_manager.get('drm_license_type') == 'Floating/Metering' - drm_manager.deactivate() - async_cb.assert_NoError() - # Request nodelock license - try: - async_cb.reset() - conf_json.reset() - conf_json.addNodelock() - accelize_drm.clean_nodelock_env(None, driver, conf_json, cred_json, ws_admin) - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('license_type') == 'Node-Locked' - # Start application - assert drm_manager.get('drm_license_type') == 'Idle' - drm_manager.activate() - assert drm_manager.get('drm_license_type') == 'Node-Locked' - drm_manager.deactivate() - async_cb.assert_NoError() - finally: - accelize_drm.clean_nodelock_env(drm_manager, driver, conf_json, cred_json, ws_admin) - print('Test user-03 entitlements: PASS') - - # Test user-04 entitlements - # Request metering license - cred_json.set_user('accelize_accelerator_test_04') - async_cb.reset() - conf_json.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - drm_manager.set(log_verbosity=1) - assert drm_manager.get('license_type') == 'Floating/Metering' - assert drm_manager.get('drm_license_type') == 'Idle' - drm_manager.activate() - assert drm_manager.get('drm_license_type') == 'Floating/Metering' - drm_manager.deactivate() - async_cb.assert_NoError() - # Request nodelock license - try: - async_cb.reset() - conf_json.reset() - conf_json.addNodelock() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('license_type') == 'Node-Locked' - assert drm_manager.get('drm_license_type') == 'Floating/Metering' - with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: - drm_manager.activate() - assert "License Web Service error 400" in str(excinfo.value) - assert "DRM WS request failed" in str(excinfo.value) - assert search(r'\\"No Entitlement\\" with .+ for \S+_test_04@accelize.com', str(excinfo.value)) - assert 'No valid NodeLocked entitlement found for your account' in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code - async_cb.assert_NoError() - finally: - accelize_drm.clean_nodelock_env(conf_json=conf_json) - print('Test user-04 entitlements: PASS') - - -@pytest.mark.minimum -def test_parameter_key_modification_with_config_file(accelize_drm, conf_json, cred_json, - async_handler): - """Test accesses to parameters""" - - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - - # First get all default value for all tested parameters - async_cb.reset() - conf_json.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - orig_log_verbosity = drm_manager.get('log_verbosity') - orig_log_format = drm_manager.get('log_format') - orig_frequency_mhz = drm_manager.get('drm_frequency') - orig_frequency_detect_period = drm_manager.get('frequency_detection_period') - orig_frequency_detect_threshold = drm_manager.get('frequency_detection_threshold') - orig_retry_period_long = drm_manager.get('ws_retry_period_long') - orig_retry_period_short = drm_manager.get('ws_retry_period_short') - orig_response_timeout = drm_manager.get('ws_request_timeout') - - # Test parameter: log_verbosity - from random import choice - async_cb.reset() - conf_json.reset() - log_level_choice = list(range(0,6)) - log_level_choice.remove(orig_log_verbosity) - exp_value = choice(log_level_choice) - assert exp_value != orig_log_verbosity - conf_json['settings']['log_verbosity'] = exp_value - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('log_verbosity') == exp_value - drm_manager.set(log_verbosity=orig_log_verbosity) - print("Test parameter 'log_verbosity': PASS") - - # Test parameter: log_format - async_cb.reset() - conf_json.reset() - exp_value = LOG_FORMAT_LONG - conf_json['settings']['log_format'] = exp_value - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('log_format') == exp_value - async_cb.assert_NoError() - print("Test parameter 'log_format': PASS") - - # Test parameter: log_file_verbosity - async_cb.reset() - conf_json.reset() - exp_value = 0 - conf_json['settings']['log_file_verbosity'] = exp_value - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('log_file_verbosity') == exp_value - async_cb.assert_NoError() - print("Test parameter 'log_file_verbosity': PASS") - - # Test parameter: log_file_format - async_cb.reset() - conf_json.reset() - exp_value = LOG_FORMAT_SHORT - conf_json['settings']['log_file_format'] = exp_value - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('log_file_format') == exp_value - async_cb.assert_NoError() - print("Test parameter 'log_file_format': PASS") - - # Test parameter: log_file_path - async_cb.reset() - conf_json.reset() - exp_value = realpath("./drmlib.%d.%s.log" % (getpid(), time())) - conf_json['settings']['log_file_path'] = exp_value - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('log_file_path') == exp_value - async_cb.assert_NoError() - print("Test parameter 'log_file_path': PASS") - - # Test parameter: log_file_type - async_cb.reset() - conf_json.reset() - exp_value = 1 - conf_json['settings']['log_file_type'] = exp_value - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('log_file_type') == exp_value - async_cb.assert_NoError() - print("Test parameter 'log_file_type': PASS") - - # Test parameter: log_file_rotating_size - async_cb.reset() - conf_json.reset() - exp_value = 1024 - conf_json['settings']['log_file_rotating_size'] = exp_value - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('log_file_rotating_size') == exp_value - async_cb.assert_NoError() - print("Test parameter 'log_file_rotating_size': PASS") - - # Test parameter: log_file_rotating_num - async_cb.reset() - conf_json.reset() - exp_value = 10 - conf_json['settings']['log_file_rotating_num'] = exp_value - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('log_file_rotating_num') == exp_value - async_cb.assert_NoError() - print("Test parameter 'log_file_rotating_num': PASS") - - # Test parameter: frequency_detection_method - if accelize_drm.pytest_new_freq_method_supported: - async_cb.reset() - conf_json.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('frequency_detection_method') == 1 - print("Test parameter 'frequency_detection_method': PASS") - - # Test parameter: bypass_frequency_detection - if accelize_drm.pytest_new_freq_method_supported: - async_cb.reset() - conf_json.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert not drm_manager.get('bypass_frequency_detection') - conf_json.reset() - conf_json['drm']['bypass_frequency_detection'] = True - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('bypass_frequency_detection') - print("Test parameter 'bypass_frequency_detection': PASS") - - # Test parameter: drm_frequency - async_cb.reset() - conf_json.reset() - exp_value = 2*orig_frequency_mhz - conf_json['drm']['bypass_frequency_detection'] = True - conf_json['drm']['frequency_mhz'] = exp_value - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('drm_frequency') == exp_value - async_cb.assert_NoError() - print("Test parameter 'drm_frequency': PASS") - - # Test parameter: frequency_detection_period - async_cb.reset() - conf_json.reset() - exp_value = 2*orig_frequency_detect_period - conf_json['settings'] = {'frequency_detection_period': exp_value} - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - value = drm_manager.get('frequency_detection_period') - assert value == exp_value - async_cb.assert_NoError() - print("Test parameter 'frequency_detection_period': PASS") - - # Test parameter: frequency_detection_threshold - async_cb.reset() - conf_json.reset() - exp_value = 2*orig_frequency_detect_threshold - conf_json['settings'] = {'frequency_detection_threshold': exp_value} - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - value = drm_manager.get('frequency_detection_threshold') - assert value == exp_value - async_cb.assert_NoError() - print("Test parameter 'frequency_detection_threshold': PASS") - - # Test parameter: ws_retry_period_long - async_cb.reset() - conf_json.reset() - # Check error: ws_retry_period_long must be != ws_retry_period_short - conf_json['settings'] = {'ws_retry_period_long': orig_retry_period_short} - conf_json.save() - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert search(r'ws_retry_period_long .+ must be greater than ws_retry_period_short .+', - str(excinfo.value)) is not None - err_code = async_handler.get_error_code(str(excinfo.value)) - assert err_code == accelize_drm.exceptions.DRMBadArg.error_code - async_cb.assert_NoError() - - async_cb.reset() - conf_json.reset() - exp_value = orig_retry_period_long + 1 - conf_json['settings'] = {'ws_retry_period_long': exp_value} - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - value = drm_manager.get('ws_retry_period_long') - assert value == exp_value - async_cb.assert_NoError() - print("Test parameter 'ws_retry_period_long': PASS") - - # Test parameter: ws_retry_period_short - async_cb.reset() - conf_json.reset() - # Check error: ws_retry_period_long must be != ws_retry_period_short - conf_json['settings'] = {'ws_retry_period_short': orig_retry_period_long} - conf_json.save() - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert search(r'ws_retry_period_long .+ must be greater than ws_retry_period_short .+', - str(excinfo.value)) is not None - err_code = async_handler.get_error_code(str(excinfo.value)) - assert err_code == accelize_drm.exceptions.DRMBadArg.error_code - async_cb.assert_NoError() - - async_cb.reset() - conf_json.reset() - exp_value = orig_retry_period_short + 1 - conf_json['settings'] = {'ws_retry_period_short': exp_value} - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - value = drm_manager.get('ws_retry_period_short') - assert value == exp_value - async_cb.assert_NoError() - print("Test parameter 'ws_retry_period_short': PASS") - - # Test parameter: ws_request_timeout - async_cb.reset() - conf_json.reset() - conf_json['settings'] = {'ws_request_timeout': 0} - conf_json.save() - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert "ws_request_timeout must not be 0" in str(excinfo.value) - err_code = async_handler.get_error_code(str(excinfo.value)) - assert err_code == accelize_drm.exceptions.DRMBadArg.error_code - - async_cb.reset() - conf_json.reset() - exp_value = 2*orig_response_timeout - conf_json['settings'] = {'ws_request_timeout': exp_value} - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - value = drm_manager.get('ws_request_timeout') - assert value == exp_value - async_cb.assert_NoError() - print("Test parameter 'ws_request_timeout': PASS") - - # Test unsupported parameter - async_cb.reset() - conf_json.reset() - conf_json['settings'] = {'unsupported_param': 10.2} - conf_json.save() - accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - async_cb.assert_NoError() - print("Test unsupported parameter: PASS") - - # Test empty parameter - async_cb.reset() - conf_json.reset() - conf_json['settings'] = {'': 10.2} - conf_json.save() - accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - async_cb.assert_NoError() - print("Test empty parameter: PASS") - - -@pytest.mark.aws -def test_c_unittests(accelize_drm, exec_func): - """Test errors when missing arguments are given to DRM Controller Constructor""" - driver = accelize_drm.pytest_fpga_driver[0] - if driver._name != 'aws': - pytest.skip("C unit-tests are only supported with AWS driver.") - - exec_lib = exec_func.load('unittests', driver._fpga_slot_id) - - # Test when read register callback is null - exec_lib.run('test_null_read_callback') - assert exec_lib.returncode == accelize_drm.exceptions.DRMBadArg.error_code - assert 'Read register callback function must not be NULL' in exec_lib.stdout - assert exec_lib.asyncmsg is None - - # Test when write register callback is null - exec_lib.run('test_null_write_callback') - assert exec_lib.returncode == accelize_drm.exceptions.DRMBadArg.error_code - assert 'Write register callback function must not be NULL' in exec_lib.stdout - assert exec_lib.asyncmsg is None - - # Test when asynchronous error callback is null - exec_lib.run('test_null_error_callback') - assert exec_lib.returncode == accelize_drm.exceptions.DRMBadArg.error_code - assert 'Asynchronous error callback function must not be NULL' in exec_lib.stdout - assert exec_lib.asyncmsg is None - - # Test various types of get and set functions - exec_lib.run('test_types_of_get_and_set_functions') - assert exec_lib.returncode == 0 - assert exec_lib.asyncmsg is None - - # Test out of range of get function - exec_lib.run('test_get_function_out_of_range') - assert exec_lib.returncode == accelize_drm.exceptions.DRMBadArg.error_code - assert 'Cannot find parameter with ID: ' in exec_lib.stdout - assert exec_lib.asyncmsg is None - - # Test get_json_string with bad format - exec_lib.run('test_get_json_string_with_bad_format') - assert exec_lib.returncode == accelize_drm.exceptions.DRMBadFormat.error_code - assert 'Cannot parse JSON string because' in exec_lib.stdout - assert exec_lib.asyncmsg is None - - # Test get_json_string with empty string - exec_lib.run('test_get_json_string_with_empty_string') - assert exec_lib.returncode == accelize_drm.exceptions.DRMBadFormat.error_code - assert 'Cannot parse an empty JSON string' in exec_lib.stdout - assert exec_lib.asyncmsg is None - - -def test_parameter_key_modification_with_get_set(accelize_drm, conf_json, cred_json, async_handler, - ws_admin): - """Test accesses to parameter""" - - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - activators = accelize_drm.pytest_fpga_activators[0] - activators.reset_coin() - - print() - - # Test with a nodelocked user - - # Test parameter: license_type and drm_license_type in nodelocked and nodelocked_request_file - # => Done in test_nodelock_mode_on_hw - - # Test with a floating/metered user - - async_cb.reset() - cred_json.set_user('accelize_accelerator_test_02') - conf_json.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - - # Test when parameter is a list - value = drm_manager.get('num_activators','license_type') - assert isinstance(value, dict) - assert value['num_activators'] == activators.length - assert value['license_type'] == 'Floating/Metering' - async_cb.assert_NoError() - print("Test when parameter is a list: PASS") - - - # Test parameter: log_verbosity - orig_val = drm_manager.get('log_verbosity') - exp_val = 1 if orig_val == 0 else 0 - drm_manager.set(log_verbosity=exp_val) - assert drm_manager.get('log_verbosity') == exp_val - drm_manager.set(log_verbosity=orig_val) - async_cb.assert_NoError() - print("Test parameter 'log_verbosity': PASS") - - # Test parameter: log_format - orig_val = drm_manager.get('log_format') - exp_val = LOG_FORMAT_LONG - drm_manager.set(log_format=exp_val) - assert drm_manager.get('log_format') == exp_val - drm_manager.set(log_format=orig_val) - async_cb.assert_NoError() - print("Test parameter 'log_format': PASS") - - # Test parameter: log_file_verbosity - orig_val = drm_manager.get('log_file_verbosity') - exp_val = 1 if orig_val == 0 else 0 - drm_manager.set(log_file_verbosity=exp_val) - assert drm_manager.get('log_file_verbosity') == exp_val - drm_manager.set(log_file_verbosity=orig_val) - async_cb.assert_NoError() - print("Test parameter 'log_file_verbosity': PASS") - - # Test parameter: log_file_format - orig_val = drm_manager.get('log_file_format') - assert orig_val == LOG_FORMAT_LONG - exp_val = LOG_FORMAT_SHORT - drm_manager.set(log_file_format=exp_val) - assert drm_manager.get('log_file_format') == exp_val - drm_manager.set(log_file_format=orig_val) - async_cb.assert_NoError() - print("Test parameter 'log_file_format': PASS") - - # Test parameter: log_file_path, log_file_type, log_file_rotating_size, log_file_rotating_num - # => Cannot be written programmatically - - # Test parameter: license_type in metering - assert drm_manager.get('license_type') == 'Floating/Metering' - async_cb.assert_NoError() - print("Test parameter 'license_type' in Metered: PASS") - - # Test parameter: drm_license_type, license_duration - drm_manager.activate() - assert drm_manager.get('drm_license_type') == 'Floating/Metering' - assert drm_manager.get('license_duration') != 0 - drm_manager.deactivate() - async_cb.assert_NoError() - print("Test parameter 'drm_license_type', 'license_duration': PASS") - - # Test parameter: num_activators - nb_activator = drm_manager.get('num_activators') - assert nb_activator == activators.length, 'Unexpected number of activators' - print("Test parameter 'num_activators': PASS") - - # Test parameter: session_id - drm_manager.activate() - sessionId = drm_manager.get('session_id') - assert len(sessionId) == 16, 'Unexpected length of session ID' - drm_manager.deactivate() - async_cb.assert_NoError() - print("Test parameter 'session_id': PASS") - - # Test parameter: session_status - session_state = drm_manager.get('session_status') - assert not session_state - drm_manager.activate() - session_state = drm_manager.get('session_status') - assert session_state - drm_manager.deactivate() - session_state = drm_manager.get('session_status') - assert not session_state - async_cb.assert_NoError() - print("Test parameter 'session_status': PASS") - - # Test parameter: license_status - assert not drm_manager.get('license_status') - drm_manager.activate() - assert drm_manager.get('license_status') - drm_manager.deactivate() - assert not drm_manager.get('license_status') - async_cb.assert_NoError() - print("Test parameter 'license_status': PASS") - - # Test parameter: metered_data - drm_manager.activate() - activators[0].generate_coin(10) - activators[0].check_coin(drm_manager.get('metered_data')) - async_cb.assert_NoError() - drm_manager.deactivate() - activators[0].reset_coin() - - print("Test parameter 'metered_data': PASS") - - # Test parameter: page_ctrlreg - page = drm_manager.get('page_ctrlreg') - assert search(r'Register\s+@0x00:\s+0x00000000', page), 'Unexpected content of page_ctrlreg' - print("Test parameter 'page_ctrlreg': PASS") - - # Test parameter: page_vlnvfile - page = drm_manager.get('page_vlnvfile') - assert search(r'Register\s+@0x00:\s+0x00000001', page), 'Unexpected content of page_vlnvfile' - print("Test parameter 'page_vlnvfile': PASS") - - # Test parameter: page_licfile - page = drm_manager.get('page_licfile') - assert search(r'Register\s+@0x00:\s+0x00000002', page), 'Unexpected content of page_licfile' - print("Test parameter 'page_licfile': PASS") - - # Test parameter: page_tracefile - page = drm_manager.get('page_tracefile') - assert search(r'Register\s+@0x00:\s+0x00000003', page), 'Unexpected content of page_tracefile' - print("Test parameter 'page_tracefile': PASS") - - # Test parameter: page_meteringfile - page = drm_manager.get('page_meteringfile') - assert search(r'Register\s+@0x00:\s+0x00000004', page), 'Unexpected content of page_meteringfile' - print("Test parameter 'page_meteringfile': PASS") - - # Test parameter: page_mailbox - page = drm_manager.get('page_mailbox') - assert search(r'Register\s+@0x00:\s+0x00000005', page), 'Unexpected content of page_mailbox' - print("Test parameter 'page_mailbox': PASS") - - # Test parameter: hw_report - hw_report = drm_manager.get('hw_report') - nb_lines = len(tuple(finditer(r'\n', hw_report))) - assert nb_lines > 10, 'Unexpected HW report content' - print("Test parameter 'hw_report': PASS") - - # Test parameter: frequency_detection_threshold - orig_freq_threhsold = drm_manager.get('frequency_detection_threshold') # Save original threshold - exp_freq_threhsold = orig_freq_threhsold * 2 - drm_manager.set(frequency_detection_threshold=exp_freq_threhsold) - new_freq_threhsold = drm_manager.get('frequency_detection_threshold') - assert new_freq_threhsold == exp_freq_threhsold, 'Unexpected frequency dectection threshold percentage' - drm_manager.set(frequency_detection_threshold=orig_freq_threhsold) # Restore original threshold - print("Test parameter 'frequency_detection_threshold': PASS") - - # Test parameter: frequency_detection_period - orig_freq_period = drm_manager.get('frequency_detection_period') # Save original period - exp_freq_period = orig_freq_period * 2 - drm_manager.set(frequency_detection_period=exp_freq_period) - new_freq_period = drm_manager.get('frequency_detection_period') - assert new_freq_period == exp_freq_period, 'Unexpected frequency dectection period' - drm_manager.set(frequency_detection_period=orig_freq_period) # Restore original period - print("Test parameter 'frequency_detection_period': PASS") - - # Test parameter: drm_frequency - freq_period = drm_manager.get('frequency_detection_period') # Save original period - drm_manager.activate() - #sleep(2.0*freq_period/1000) - freq_drm = drm_manager.get('drm_frequency') - drm_manager.deactivate() - assert 125 <= freq_drm <= 126, 'Unexpected frequency gap threshold' - print("Test parameter 'drm_frequency': PASS") - - # Test parameter: product_info - from pprint import pformat - product_id = pformat(drm_manager.get('product_info')) - exp_product_id = pformat(activators.product_id) - assert product_id == exp_product_id, 'Unexpected product ID' - print("Test parameter 'product_info': PASS") - - # Test parameter: mailbox_size - mailbox_size = drm_manager.get('mailbox_size') - assert mailbox_size == 14, 'Unexpected Mailbox size' - print("Test parameter 'mailbox_size': PASS") - - # Test parameter: token_string, token_validity and token_time_left - drm_manager.activate() - token_time_left = drm_manager.get('token_time_left') - if token_time_left < 15: - drm_manager.deactivate() - sleep(16) - drm_manager.activate() - token_string = drm_manager.get('token_string') - assert len(token_string) > 0 - token_validity = drm_manager.get('token_validity') - assert token_validity > 15 - token_time_left = drm_manager.get('token_time_left') - sleep(2) - assert 2 <= token_time_left - drm_manager.get('token_time_left') <= 3 - assert drm_manager.get('token_validity') == token_validity - assert token_string == drm_manager.get('token_string') - drm_manager.deactivate() - print("Test parameter 'token_string', 'token_validity' and 'token_time_left': PASS") - - # Test parameter: list_all - list_param = drm_manager.get('list_all') - assert isinstance(list_param , list) - assert len(list_param) == len(_PARAM_LIST) - assert all(key in _PARAM_LIST for key in list_param) - print("Test parameter 'list_all': PASS") - - # Test parameter: dump_all - dump_param = drm_manager.get('dump_all') - assert isinstance(dump_param, dict) - assert len(dump_param) == _PARAM_LIST.index('dump_all') - assert all(key in _PARAM_LIST for key in dump_param.keys()) - print("Test parameter 'dump_all': PASS") - - # Test parameter: custom_field - from random import randint - val_exp = randint(0,0xFFFFFFFF) - val_init = drm_manager.get('custom_field') - assert val_exp != val_init - drm_manager.set(custom_field=val_exp) - assert drm_manager.get('custom_field') == val_exp - print("Test parameter 'custom_field': PASS") - - # Test parameter: mailbox_data - from random import sample - mailbox_size = drm_manager.get('mailbox_size') - wr_msg = sample(range(0xFFFFFFFF), mailbox_size) - drm_manager.set(mailbox_data=wr_msg) - rd_msg = drm_manager.get('mailbox_data') - assert type(rd_msg) == type(wr_msg) == list - assert rd_msg == wr_msg - print("Test parameter 'mailbox_data': PASS") - - # Test parameter: ws_retry_period_long - orig_retry_period_long = drm_manager.get('ws_retry_period_long') # Save original value - orig_retry_period_short = drm_manager.get('ws_retry_period_short') - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager.set(ws_retry_period_long=orig_retry_period_short) - assert search(r'ws_retry_period_long .+ must be greater than ws_retry_period_short .+', - str(excinfo.value)) is not None - err_code = async_handler.get_error_code(str(excinfo.value)) - assert err_code == accelize_drm.exceptions.DRMBadArg.error_code - exp_value = orig_retry_period_long + 1 - drm_manager.set(ws_retry_period_long=exp_value) - assert drm_manager.get('ws_retry_period_long') == exp_value - drm_manager.set(ws_retry_period_long=orig_retry_period_long) # Restore original value - async_cb.assert_NoError(async_cb.assert_NoError) - print("Test parameter 'ws_retry_period_long': PASS") - - # Test parameter: ws_retry_period_short - orig_retry_period_short = drm_manager.get('ws_retry_period_short') # Save original value - orig_retry_period_long = drm_manager.get('ws_retry_period_long') - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager.set(ws_retry_period_short=orig_retry_period_long) - assert search(r'ws_retry_period_long .+ must be greater than ws_retry_period_short .+', - str(excinfo.value)) is not None - err_code = async_handler.get_error_code(str(excinfo.value)) - assert err_code == accelize_drm.exceptions.DRMBadArg.error_code - exp_value = orig_retry_period_short + 1 - drm_manager.set(ws_retry_period_short=exp_value) - assert drm_manager.get('ws_retry_period_short') == exp_value - drm_manager.set(ws_retry_period_short=orig_retry_period_short) # Restore original value - async_cb.assert_NoError(async_cb.assert_NoError) - print("Test parameter 'ws_retry_period_short': PASS") - - # Test parameter: ws_request_timeout - orig_response_timeout = drm_manager.get('ws_request_timeout') # Save original value - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager.set(ws_request_timeout=0) - assert "ws_request_timeout must not be 0" in str(excinfo.value) - err_code = async_handler.get_error_code(str(excinfo.value)) - assert err_code == accelize_drm.exceptions.DRMBadArg.error_code - exp_value = orig_response_timeout + 100 - drm_manager.set(ws_request_timeout=exp_value) - assert drm_manager.get('ws_request_timeout') == exp_value - drm_manager.set(ws_request_timeout=orig_response_timeout) # Restore original value - async_cb.assert_NoError(async_cb.assert_NoError) - print("Test parameter 'ws_request_timeout': PASS") - - # Test parameter: log_message_level - level = drm_manager.get('log_message_level') - exp_level = 5 if level!=5 else 4 - drm_manager.set(log_message_level=exp_level) - assert drm_manager.get('log_message_level') == exp_level - async_cb.assert_NoError() - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager.set(log_message_level=100) - assert 'log_message_level (100) is out of range [0:6]' in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadArg.error_code - async_cb.assert_NoError() - print("Test parameter 'log_message_level': PASS") - - # Test parameter: trigger_async_callback - drm_manager.activate() - test_message = 'Test message' - drm_manager.set(trigger_async_callback=test_message) - assert async_cb.was_called, 'Asynchronous callback has not been called.' - assert async_cb.message is not None, 'Asynchronous callback did not report any message' - assert test_message in async_cb.message, 'Asynchronous callback has not received the correct message' - assert async_cb.errcode == accelize_drm.exceptions.DRMDebug.error_code, \ - 'Asynchronous callback has not received the correct error code' - drm_manager.deactivate() - async_cb.reset() - print("Test parameter 'trigger_async_callback': PASS") - - # Test parameter: bad_product_id - # => Skipped: Tested in test_configuration_file_bad_product_id - - # Test parameter: bad_oauth2_token - # => Skipped: Tested in test_configuration_file_with_bad_authentication - - # Test parameter: ParameterKeyCount - assert drm_manager.get('ParameterKeyCount') == len(_PARAM_LIST) - async_cb.assert_NoError() - print("Test parameter 'ParameterKeyCount': PASS") - - # Test parameter: log_message - from os.path import isfile - async_cb.reset() - conf_json.reset() - logpath = realpath("./drmlib.%d.%s.log" % (getpid(), time())) - verbosity = 5 - conf_json['settings']['log_file_verbosity'] = verbosity - conf_json['settings']['log_file_type'] = 1 - conf_json['settings']['log_file_path'] = logpath - conf_json.save() - try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - drm_manager.set(log_message_level=verbosity) - msg = 'This line should appear in log file' - drm_manager.set(log_message=msg) - del drm_manager - gc.collect() - assert isfile(logpath) - with open(logpath, 'rt') as f: - log_content = f.read() - assert "critical" in log_content - assert msg in log_content - finally: - if isfile(logpath): - remove(logpath) - async_cb.assert_NoError() - print("Test parameter 'log_message': PASS") - - -def test_configuration_file_with_bad_authentication(accelize_drm, conf_json, cred_json, - async_handler): - """Test errors when bad authentication parameters are provided to - DRM Manager Constructor or Web Service.""" - - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - - drm_manager = None - print() - try: - # Test when authentication url in configuration file is wrong - async_cb.reset() - cred_json.set_user('accelize_accelerator_test_02') - conf_json.reset() - conf_json['licensing']['url'] = "http://accelize.com" - conf_json['settings']['ws_request_timeout'] = 5 - conf_json['settings']['ws_retry_period_short'] = 1 - conf_json.save() - assert conf_json['licensing']['url'] == "http://accelize.com" - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: - drm_manager.activate() - assert "OAuth2 Web Service error 404" in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code - async_cb.assert_NoError() - print('Test when authentication url in configuration file is wrong: PASS') - - # Test when client_id is wrong - async_cb.reset() - conf_json.reset() - cred_json.set_user('accelize_accelerator_test_02') - orig_client_id = cred_json.client_id - replaced_char = 'A' if orig_client_id[0]!='A' else 'B' - cred_json.client_id = orig_client_id.replace(orig_client_id[0], replaced_char) - assert orig_client_id != cred_json.client_id - cred_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: - drm_manager.activate() - assert "OAuth2 Web Service error 401" in str(excinfo.value) - assert "invalid_client" in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code - async_cb.assert_NoError() - print('Test when client_id is wrong: PASS') - - # Test when client_secret is wrong - async_cb.reset() - conf_json.reset() - cred_json.set_user('accelize_accelerator_test_02') - orig_client_secret = cred_json.client_secret - replaced_char = 'A' if orig_client_secret[0]!='A' else 'B' - cred_json.client_secret = orig_client_secret.replace(orig_client_secret[0], replaced_char) - cred_json.save() - assert orig_client_secret != cred_json.client_secret - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: - drm_manager.activate() - assert "OAuth2 Web Service error 401" in str(excinfo.value) - assert "invalid_client" in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code - async_cb.assert_NoError() - print('Test when client_secret is wrong: PASS') - - # Test when token is wrong - async_cb.reset() - conf_json.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - drm_manager.set(bad_oauth2_token=1) - with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: - drm_manager.activate() - assert "invalid_client" in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code - async_cb.assert_NoError() - print('Test when token is wrong: PASS') - - # Test token validity after deactivate - async_cb.reset() - conf_json.reset() - cred_json.set_user('accelize_accelerator_test_02') - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - drm_manager.activate() - token_time_left = drm_manager.get('token_time_left') - if token_time_left < 15: - drm_manager.deactivate() - # Wait expiration of current oauth2 token before starting test - sleep(16) - drm_manager.activate() - token_validity = drm_manager.get('token_validity') - assert token_validity > 15 - exp_token_string = drm_manager.get('token_string') - drm_manager.deactivate() - token_string = drm_manager.get('token_string') - assert token_string == exp_token_string - drm_manager.activate() - token_string = drm_manager.get('token_string') - assert token_string == exp_token_string - drm_manager.deactivate() - token_string = drm_manager.get('token_string') - assert token_string == exp_token_string - async_cb.assert_NoError() - print('Test token validity after deactivate: PASS') - -# # Test when token has expired -# async_cb.reset() -# conf_json.reset() -# drm_manager = accelize_drm.DrmManager( -# conf_json.path, -# cred_json.path, -# driver.read_register_callback, -# driver.write_register_callback, -# async_cb.callback -# ) -# drm_manager.activate() -# start = datetime.now() -# drm_manager.deactivate() -# exp_token_string = drm_manager.get('token_string') -# token_validity = drm_manager.get('token_validity') -# token_expired_in = drm_manager.get('token_expired_in') -# exp_token_validity = 10 -# drm_manager.set(token_validity=exp_token_validity) -# token_validity = drm_manager.get('token_validity') -# assert token_validity == exp_token_validity -# token_expired_in = drm_manager.get('token_expired_in') -# ts = drm_manager.get('token_string') -# assert token_expired_in > token_validity/3 -# assert token_expired_in > 3 -# # Wait right before the token expires and verifiy it is the same -# wait_period = start + timedelta(seconds=token_expired_in-3) - datetime.now() -# sleep(wait_period.total_seconds()) -# drm_manager.activate() -# drm_manager.deactivate() -# token_string = drm_manager.get('token_string') -# assert token_string == exp_token_string -# sleep(4) -# drm_manager.activate() -# drm_manager.deactivate() -# token_string = drm_manager.get('token_string') -# assert token_string != exp_token_string -# async_cb.assert_NoError() -# print('Test when token has expired: PASS') - - finally: - if drm_manager: - drm_manager.deactivate() - - -def test_configuration_file_with_bad_frequency(accelize_drm, conf_json, cred_json, async_handler): - """Test errors when wrong frequency is given to DRM Controller Constructor""" - - from math import ceil, floor - - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - cred_json.set_user('accelize_accelerator_test_02') - - # Before any test, get the real DRM frequency and the gap threshold - async_cb.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - freq_threshold = drm_manager.get('frequency_detection_threshold') - freq_period = drm_manager.get('frequency_detection_period') - drm_manager.activate() - sleep(2.0*freq_period/1000) - frequency = drm_manager.get('drm_frequency') - drm_manager.deactivate() - - # Test no error is returned by asynchronous error callback when the frequency - # in configuration file differs from the DRM frequency by less than the threshold - async_cb.reset() - conf_json.reset() - conf_json['drm']['frequency_mhz'] = int(floor(frequency * (100.0 + freq_threshold/2) / 100.0)) - assert abs(conf_json['drm']['frequency_mhz'] - frequency) * 100.0 / frequency < freq_threshold - conf_json.save() - - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - drm_manager.activate() - sleep(2.0*freq_period/1000) - drm_manager.deactivate() - async_cb.assert_NoError('freq_period=%d ms, freq_threshold=%d%%, frequency=%d MHz' - % (freq_period, freq_threshold, frequency)) - print('Test frequency mismatch < threshold: PASS') - - # Test a BADFrequency error is returned by asynchronous error callback when the frequency - # in configuration file differs from the DRM frequency by more than the threshold - async_cb.reset() - conf_json.reset() - conf_json['drm']['frequency_mhz'] = int(ceil(frequency * (100.0 + 2*freq_threshold) / 100.0)) - assert abs(conf_json['drm']['frequency_mhz'] - frequency) * 100.0 / frequency > freq_threshold - conf_json.save() - - if accelize_drm.pytest_new_freq_method_supported: - with pytest.raises(accelize_drm.exceptions.DRMBadFrequency) as excinfo: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert search(r'DRM frequency .* differs from .* configuration file', - str(excinfo.value)) is not None - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadFrequency.error_code - else: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - drm_manager.activate() - sleep(1) - drm_manager.deactivate() - assert async_cb.was_called, 'Asynchronous callback NOT called' - assert async_cb.message is not None, 'Asynchronous callback did not report any message' - assert search(r'DRM frequency .* differs from .* configuration file', - async_cb.message) is not None, 'Unexpected message reported by asynchronous callback' - assert async_cb.errcode == accelize_drm.exceptions.DRMBadFrequency.error_code, \ - 'Unexpected error code reported by asynchronous callback' - print('Test frequency mismatch > threshold: PASS') - - # Test web service detects a frequency underflow - async_cb.reset() - conf_json.reset() - conf_json['drm']['bypass_frequency_detection'] = True - conf_json['drm']['frequency_mhz'] = 40 - conf_json.save() - assert conf_json['drm']['frequency_mhz'] == 40 - - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback - ) - with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: - drm_manager.activate() - assert 'License Web Service error 400' in str(excinfo.value) - assert 'Ensure this value is greater than or equal to 50' in str(excinfo.value) - err_code = async_handler.get_error_code(str(excinfo.value)) - assert err_code == accelize_drm.exceptions.DRMWSReqError.error_code - print('Test frequency underflow: PASS') - - # Test web service detects a frequency overflow - async_cb.reset() - conf_json.reset() - conf_json['drm']['bypass_frequency_detection'] = True - conf_json['drm']['frequency_mhz'] = 400 - conf_json.save() - assert conf_json['drm']['frequency_mhz'] == 400 - - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback - ) - with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: - drm_manager.activate() - assert 'License Web Service error 400' in str(excinfo.value) - assert 'Ensure this value is less than or equal to 320' in str(excinfo.value) - err_code = async_handler.get_error_code(str(excinfo.value)) - assert err_code == accelize_drm.exceptions.DRMWSReqError.error_code - print('Test frequency overflow: PASS') - - -def test_mailbox_write_overflow(accelize_drm, conf_json, cred_json, async_handler): - from random import sample - - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - - # Test with a null crendential file - async_cb.reset() - cred_json.reset() - conf_json.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - mb_size = drm_manager.get('mailbox_size') - assert mb_size > 0 - - mb_data = sample(range(0xFFFFFFFF), mb_size + 1) - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager.set(mailbox_data=mb_data) - assert 'Trying to write out of Mailbox memory space' in str(excinfo.value) - err_code = async_handler.get_error_code(str(excinfo.value)) - assert err_code == accelize_drm.exceptions.DRMBadArg.error_code - async_cb.assert_NoError() - - -def test_mailbox_type_error(accelize_drm, conf_json, cred_json, async_handler): - from random import sample - - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - - # Test with a null crendential file - async_cb.reset() - cred_json.reset() - conf_json.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager.set(mailbox_data='this is bad type') - assert 'Value must be an array of integers' in str(excinfo.value) - err_code = async_handler.get_error_code(str(excinfo.value)) - assert err_code == accelize_drm.exceptions.DRMBadArg.error_code - async_cb.assert_NoError() - - -def test_configuration_file_wrong_product_id(accelize_drm, conf_json, cred_json, async_handler): - """Test errors when an incorrect product ID is requested to License Web Server""" - - refdesign = accelize_drm.pytest_ref_designs - driver = accelize_drm.pytest_fpga_driver[0] - fpga_image_bkp = driver.fpga_image - async_cb = async_handler.create() - cred_json.set_user('accelize_accelerator_test_02') - - # Test Web Service when an unexisting product ID is provided - async_cb.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - drm_manager.set(bad_product_id=1) - product_id = drm_manager.get('product_info') - pid_string = '{vendor}/{library}/{name}'.format(**product_id) - assert pid_string == 'accelize.com/refdesign/BAD_NAME_JUST_FOR_TEST' - with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: - drm_manager.activate() - assert 'License Web Service error 400' in str(excinfo.value) - assert 'DRM WS request failed' in str(excinfo.value) - assert search(r'\\"Unknown Product ID\\" \s*%s for' % pid_string, str(excinfo.value)) is not None - assert search(r'Product ID \s*%s from license request is unknown' % pid_string, str(excinfo.value)) is not None - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code - async_cb.assert_NoError() - - -def test_configuration_file_empty_and_corrupted_product_id(accelize_drm, conf_json, cred_json, async_handler): - """Test errors when an incorrect product ID is requested to License Web Server""" - - refdesign = accelize_drm.pytest_ref_designs - driver = accelize_drm.pytest_fpga_driver[0] - fpga_image_bkp = driver.fpga_image - async_cb = async_handler.create() - cred_json.set_user('accelize_accelerator_test_02') - - try: - # Test Web Service when an empty product ID is provided - empty_fpga_image = refdesign.get_image_id('empty_product_id') - if empty_fpga_image is None: - pytest.skip("No FPGA image found for 'empty_product_id'") - driver.program_fpga(empty_fpga_image) - async_cb.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('product_info') is None - with pytest.raises(accelize_drm.exceptions.DRMWSReqError) as excinfo: - drm_manager.activate() - assert 'License Web Service error 400' in str(excinfo.value) - assert 'DRM WS request failed' in str(excinfo.value) - assert search(r'\\"Unknown Product ID\\" for ', str(excinfo.value)) is not None - assert 'Product ID from license request is not set' in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSReqError.error_code - async_cb.assert_NoError() - print('Test Web Service when an empty product ID is provided: PASS') - - # Test when a misformatted product ID is provided - bad_fpga_image = refdesign.get_image_id('bad_product_id') - if bad_fpga_image is None: - pytest.skip("No FPGA image found for 'bad_product_id'") - driver.program_fpga(bad_fpga_image) - async_cb.reset() - with pytest.raises(accelize_drm.exceptions.DRMBadFormat) as excinfo: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert 'Failed to parse Read-Only Mailbox in DRM Controller:' in str(excinfo.value) - assert search(r'Cannot parse JSON string .* because ', str(excinfo.value)) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadFormat.error_code - async_cb.assert_NoError() - print('Test Web Service when a misformatted product ID is provided: PASS') - - finally: - # Reprogram FPGA with original image - driver.program_fpga(fpga_image_bkp) - - -@pytest.mark.skip(reason='Not supported') -def test_2_drm_manager_concurrently(accelize_drm, conf_json, cred_json, async_handler): - """Test errors when 2 DrmManager instances are used.""" - - driver = accelize_drm.pytest_fpga_driver[0] - - async_cb1 = async_handler.create() - async_cb2 = async_handler.create() - - cred_json.set_user('accelize_accelerator_test_02') - - drm_manager1 = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb1.callback - ) - - with pytest.raises(accelize_drm.exceptions.DRMBadUsage) as excinfo: - drm_manager2 = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb2.callback - ) - assert 'Another instance of the DRM Manager is currently owning the HW' in str(excinfo.value) +def test_get_version(accelize_drm): + """Test the versions of the DRM Lib and its dependencies are well displayed""" + versions = accelize_drm.get_api_version() + assert search(r'\d+\.\d+\.\d+', versions.version) is not None @pytest.mark.long_run @@ -1845,47 +185,37 @@ def test_session_status(accelize_drm, conf_json, cred_json, async_handler): # Test session status on start/stop # Check no session is running and no ID is available - status = drm_manager.get('session_status') - session_id = drm_manager.get('session_id') - assert not status, 'A session is running' - assert len(session_id) == 0, 'A session ID exists' + assert not drm_manager.get('session_status') + assert len(drm_manager.get('session_id')) == 0 # Activate new session drm_manager.activate() # Check a session is running with a valid ID - status = drm_manager.get('session_status') - session_id = drm_manager.get('session_id') - assert status, 'No session is running' - assert len(session_id) == 16, 'No session ID is returned' + assert drm_manager.get('session_status') + assert len(drm_manager.get('session_id')) == 16 # Deactivate current session drm_manager.deactivate() # Check session is closed - status = drm_manager.get('session_status') - session_id = drm_manager.get('session_id') - assert not status, 'A session is running' - assert len(session_id) == 0, 'A session ID exists' + assert not drm_manager.get('session_status') + assert len(drm_manager.get('session_id')) == 0 print('Test session status on start/stop: PASS') # Test session status on start/pause # Check no session is running and no ID is available - status = drm_manager.get('session_status') - session_id = drm_manager.get('session_id') - assert not status, 'A session is running' - assert len(session_id) == 0, 'A session ID exists' + assert not drm_manager.get('session_status') + assert len(drm_manager.get('session_id')) == 0 # Activate new session drm_manager.activate() start = datetime.now() # Check a session is running with a valid ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') id_ref = drm_manager.get('session_id') - assert status, 'No session is running' assert len(id_ref) == 16, 'No session ID is returned' # Pause current session drm_manager.deactivate(True) # Check a session is still alive with the same ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id == id_ref, 'Return different session ID' async_cb.assert_NoError() @@ -1894,25 +224,22 @@ def test_session_status(accelize_drm, conf_json, cred_json, async_handler): # Test session status on resume from valid license/pause # Check a session is still alive with the same ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id == id_ref, 'Return different session ID' # Resume current session drm_manager.activate(True) # Check a session is still alive with the same ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id == id_ref, 'Return different session ID' # Pause current session drm_manager.deactivate(True) # Check a session is still alive with the same ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id == id_ref, 'Return different session ID' # Wait until license expires @@ -1920,9 +247,8 @@ def test_session_status(accelize_drm, conf_json, cred_json, async_handler): wait_period = start + timedelta(seconds=2 * lic_duration + 1) - datetime.now() sleep(wait_period.total_seconds()) # Check a session is still alive with the same ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id == id_ref, 'Return different session ID' async_cb.assert_NoError() @@ -1931,25 +257,22 @@ def test_session_status(accelize_drm, conf_json, cred_json, async_handler): # Test session status on resume from expired license/pause # Check a session is still alive with the same ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id == id_ref, 'Return different session ID' # Resume current session drm_manager.activate(True) # Check a session is still alive with the same ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id == id_ref, 'Return different session ID' # Pause current session drm_manager.deactivate(True) # Check a session is still alive with the same ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id == id_ref, 'Return different session ID' async_cb.assert_NoError() @@ -1958,68 +281,57 @@ def test_session_status(accelize_drm, conf_json, cred_json, async_handler): # Test session status on resume/stop # Check a session is still alive with the same ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id == id_ref, 'Return different session ID' # Resume current session drm_manager.activate(True) # Check a session is still alive with the same ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id == id_ref, 'Return different session ID' # Close session drm_manager.deactivate() # Check session is closed - status = drm_manager.get('session_status') - session_id = drm_manager.get('session_id') - assert not status, 'A session is running' - assert len(session_id) == 0, 'A session ID exists' + assert not drm_manager.get('session_status') + assert len(drm_manager.get('session_id')) == 0 async_cb.assert_NoError() print('Test session status on resume/stop: PASS') # Test session status on start from paused session/stop # Check no session is running - status = drm_manager.get('session_status') - session_id = drm_manager.get('session_id') - assert not status, 'A session is running' - assert len(session_id) == 0, 'A session ID exists' + assert not drm_manager.get('session_status') + assert len(drm_manager.get('session_id')) == 0 # Start a new session drm_manager.activate() # Check a session is alive with a new ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id != id_ref, 'Return different session ID' id_ref = session_id # Pause session drm_manager.deactivate(True) # Check a session is still alive with the same ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id == id_ref, 'Return different session ID' # Start a new session drm_manager.activate() # Check a new session has been created with a new ID - status = drm_manager.get('session_status') + assert drm_manager.get('session_status') session_id = drm_manager.get('session_id') - assert status, 'No session is running' assert len(session_id) == 16, 'No session ID is returned' assert session_id != id_ref, 'Return different session ID' # Close session drm_manager.deactivate() # Check session is closed - status = drm_manager.get('session_status') - session_id = drm_manager.get('session_id') - assert not status, 'A session is running' - assert len(session_id) == 0, 'A session ID exists' + assert not drm_manager.get('session_status') + assert len(drm_manager.get('session_id')) == 0 async_cb.assert_NoError() print('Test session status on restart: PASS') @@ -2248,112 +560,6 @@ def test_multiple_call(accelize_drm, conf_json, cred_json, async_handler): drm_manager.deactivate() -@pytest.mark.on_2_fpga -def test_retry_function(accelize_drm, conf_json, cred_json, async_handler): - """ - Test retry mechanism on API function (not including the retry in background thread) - The retry is tested with one FPGA actiavted with a floating license and a 2nd FGPA - that's requesting the same floating license but with a limit to 1 node. - """ - driver0 = accelize_drm.pytest_fpga_driver[0] - driver1 = accelize_drm.pytest_fpga_driver[1] - - async_cb0 = async_handler.create() - async_cb1 = async_handler.create() - - cred_json.set_user('accelize_accelerator_test_04') - - # Test no retry - conf_json.reset() - retry_period = 0 - conf_json['settings']['ws_retry_period_short'] = retry_period - conf_json.save() - async_cb0.reset() - drm_manager0 = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver0.read_register_callback, - driver0.write_register_callback, - async_cb0.callback - ) - async_cb1.reset() - drm_manager1 = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver1.read_register_callback, - driver1.write_register_callback, - async_cb1.callback - ) - assert not drm_manager0.get('license_status') - assert not drm_manager1.get('license_status') - try: - drm_manager0.activate() - assert drm_manager0.get('license_status') - start = datetime.now() - with pytest.raises(accelize_drm.exceptions.DRMWSMayRetry) as excinfo: - drm_manager1.activate() - end = datetime.now() - assert (end - start).total_seconds() < 1 - assert 'License Web Service error 470' in str(excinfo.value) - assert 'DRM WS request failed' in str(excinfo.value) - assert search(r'\\"Entitlement Limit Reached\\" with .+ for \S+_test_04@accelize.com', str(excinfo.value)) is not None - assert 'You have reached the maximum quantity of 1 seat(s) for floating entitlement' in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSMayRetry.error_code - finally: - drm_manager0.deactivate() - assert not drm_manager0.get('license_status') - assert not drm_manager1.get('license_status') - async_cb0.assert_NoError() - async_cb1.assert_NoError() - print('Test no retry: PASS') - - # Test 10s retry - conf_json.reset() - timeout = 10 - retry = 1 - conf_json['settings']['ws_request_timeout'] = timeout - conf_json['settings']['ws_retry_period_short'] = retry - conf_json.save() - async_cb0.reset() - drm_manager0 = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver0.read_register_callback, - driver0.write_register_callback, - async_cb0.callback - ) - async_cb1.reset() - drm_manager1 = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver1.read_register_callback, - driver1.write_register_callback, - async_cb1.callback - ) - assert not drm_manager0.get('license_status') - assert not drm_manager1.get('license_status') - try: - drm_manager0.activate() - assert drm_manager0.get('license_status') - start = datetime.now() - with pytest.raises(accelize_drm.exceptions.DRMWSError) as excinfo: - drm_manager1.activate() - end = datetime.now() - m = search(r'Timeout on License request after (\d+) attempts', str(excinfo.value)) - assert m is not None - assert int(m.group(1)) > 1 - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMWSError.error_code - assert (end - start).total_seconds() >= timeout - assert (end - start).total_seconds() <= timeout + 1 - finally: - drm_manager0.deactivate() - assert not drm_manager0.get('license_status') - assert not drm_manager1.get('license_status') - async_cb0.assert_NoError() - async_cb1.assert_NoError() - print('Test 10s retry: PASS') - - def test_security_stop(accelize_drm, conf_json, cred_json, async_handler): """ Test the session is stopped in case of abnormal termination @@ -2383,192 +589,10 @@ def test_security_stop(accelize_drm, conf_json, cred_json, async_handler): async_cb.callback ) assert not drm_manager1.get('session_status') - session_id = drm_manager1.get('session_id') - assert len(session_id) == 0 - async_cb.assert_NoError() - - -def test_readonly_and_writeonly_parameters(accelize_drm, conf_json, cred_json, async_handler): - """ - Test readonly parameter cannot be written and writeonly parameter cannot be read - """ - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - # Test write-only parameter cannot be read - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager.get('trigger_async_callback') - assert "Parameter 'trigger_async_callback' cannot be read" in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadArg.error_code - async_cb.assert_NoError() - - # Test read-only parameter cannot be written - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager.set(license_duration=10) - assert "Parameter 'license_duration' cannot be overwritten" in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadArg.error_code + assert len(drm_manager1.get('session_id')) == 0 async_cb.assert_NoError() -@pytest.mark.endurance -def test_authentication_expiration(accelize_drm, conf_json, cred_json, async_handler): - from random import sample - driver = accelize_drm.pytest_fpga_driver[0] - activators = accelize_drm.pytest_fpga_activators[0] - async_cb = async_handler.create() - cred_json.set_user('accelize_accelerator_test_02') - - # Get test duration - try: - test_duration = accelize_drm.pytest_params['duration'] - except: - test_duration = 14000 - print('Warning: Missing argument "duration". Using default value %d' % test_duration) - - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - activators[0].generate_coin(1000) - assert not drm_manager.get('license_status') - activators[0].autotest(is_activated=False) - drm_manager.activate() - try: - lic_duration = drm_manager.get('license_duration') - assert drm_manager.get('license_status') - activators[0].autotest(is_activated=True) - activators[0].check_coin(drm_manager.get('metered_data')) - start = datetime.now() - while True: - assert drm_manager.get('license_status') - activators[0].generate_coin(1) - activators[0].check_coin(drm_manager.get('metered_data')) - seconds_left = test_duration - (datetime.now() - start).total_seconds() - print('Remaining time: %0.1fs / current coins=%d' % (seconds_left, activators[0].metering_data)) - if seconds_left < 0: - break - sleep(60) - finally: - drm_manager.deactivate() - assert not drm_manager.get('license_status') - activators[0].autotest(is_activated=False) - print('Endurance test has completed') - - -def test_directory_creation(accelize_drm, conf_json, cred_json, async_handler): - from shutil import rmtree - from subprocess import check_call - from os import makedirs, access, R_OK, W_OK - from os.path import isdir, expanduser - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - - log_type = 1 - log_dir = realpath(expanduser('~/tmp_log_dir.%s' % str(time()))) - if not isdir(log_dir): - makedirs(log_dir) - - try: - # Test error when creating directory - - # Create immutable folder - check_call('sudo chattr +i %s' % log_dir, shell=True) - assert not access(log_dir, W_OK) - try: - log_path = join(log_dir, "tmp", "drmlib.%d.%s.log" % (getpid(), str(time()))) - assert not isdir(dirname(log_path)) - async_cb.reset() - conf_json.reset() - conf_json['settings']['log_file_path'] = log_path - conf_json['settings']['log_file_type'] = log_type - conf_json.save() - with pytest.raises(accelize_drm.exceptions.DRMExternFail) as excinfo: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert "Failed to create log file %s" % log_path in str(excinfo.value) - finally: - check_call('sudo chattr -i %s' % log_dir, shell=True) - assert access(log_dir, W_OK) - if isfile(log_path): - remove(log_path) - print('Test folder creation error: PASS') - - # Test directory already exists - - assert isdir(log_dir) - assert access(log_dir, W_OK) - log_path = join(log_dir, "drmlib.%d.%s.log" % (getpid(), time())) - assert not isfile(log_path) - async_cb.reset() - conf_json.reset() - conf_json['settings']['log_file_path'] = log_path - conf_json['settings']['log_file_type'] = log_type - conf_json.save() - try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - del drm_manager - gc.collect() - assert isfile(log_path) - finally: - if isfile(log_path): - remove(log_path) - print('Test already existing folder: PASS') - - # Test directory creation - - assert isdir(log_dir) - assert access(log_dir, W_OK) - intermediate_dir = join(log_dir, 'tmp') - assert not isdir(intermediate_dir) - log_path = join(intermediate_dir, "drmlib.%d.%s.log" % (getpid(), time())) - async_cb.reset() - conf_json.reset() - conf_json['settings']['log_file_path'] = log_path - conf_json['settings']['log_file_type'] = log_type - conf_json.save() - try: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - del drm_manager - gc.collect() - assert isfile(log_path) - finally: - if isdir(intermediate_dir): - rmtree(intermediate_dir) - print('Test creation of new folder: PASS') - - finally: - if isdir(log_dir): - rmtree(log_dir) - - -#@pytest.mark.skip(reason='TODO: fix a Python Segmentation Fault generated by latest versions of OS') @pytest.mark.minimum def test_curl_host_resolve(accelize_drm, conf_json, cred_json, async_handler): """Test host resolve information is taken into account by DRM Library""" @@ -2589,138 +613,24 @@ def test_curl_host_resolve(accelize_drm, conf_json, cred_json, async_handler): ) with pytest.raises(accelize_drm.exceptions.DRMExternFail) as excinfo: drm_manager.activate() + assert 'libcurl failed to perform HTTP request to Accelize webservice' in str(excinfo.value) assert search(r'peer certificate', str(excinfo.value), IGNORECASE) assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMExternFail.error_code async_cb.assert_NoError() - del drm_manager +@pytest.mark.no_parallel @pytest.mark.minimum -def test_drm_manager_frequency_detection_method1(accelize_drm, conf_json, cred_json, async_handler): - """Test method1 (based on dedicated counter in AXI wrapper) to estimate drm frequency is working""" - - if not accelize_drm.pytest_new_freq_method_supported: - pytest.skip("New frequency detection method is not supported: test skipped") - - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - - conf_json.reset() - logpath = realpath("./drmlib.%d.%s.log" % (getpid(), time())) - conf_json['settings']['log_file_verbosity'] = 1 - conf_json['settings']['log_file_type'] = 1 - conf_json['settings']['log_file_path'] = logpath - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('frequency_detection_method') == 1 - del drm_manager - gc.collect() - assert isfile(logpath) - with open(logpath, 'rt') as f: - log_content = f.read() - assert "Use dedicated counter to compute DRM frequency (method 1)" in log_content - - -def test_drm_manager_frequency_detection_method1_exception(accelize_drm, conf_json, cred_json, async_handler): - """Test method1 (based on dedicated counter in AXI wrapper) to estimate drm frequency is working""" - - if not accelize_drm.pytest_new_freq_method_supported: - pytest.skip("New frequency detection method is not supported: test skipped") - +def test_http_header_api_version(accelize_drm, conf_json, cred_json, async_handler, live_server): + """Test the http header contains the expected API version""" driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() + async_cb.reset() conf_json.reset() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - conf_json.reset() - logpath = realpath("./drmlib.%d.%s.log" % (getpid(), time())) - conf_json['settings']['frequency_detection_period'] = (int)(2**32 / 125000000 * 1000) + 2 + conf_json['licensing']['url'] = request.url + 'test_http_header_api_version' conf_json.save() - with pytest.raises(accelize_drm.exceptions.DRMBadFrequency) as excinfo: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert search(r'Frequency auto-detection failed: frequency_detection_period parameter \([^)]+\) is too long', - str(excinfo.value)) is not None - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadFrequency.error_code - async_cb.assert_NoError() - - -@pytest.mark.minimum -def test_drm_manager_frequency_detection_method2(accelize_drm, conf_json, cred_json, async_handler): - """Test method2 (based on license timer) to estimate drm frequency is still working""" - - refdesign = accelize_drm.pytest_ref_designs - driver = accelize_drm.pytest_fpga_driver[0] - fpga_image_bkp = driver.fpga_image - async_cb = async_handler.create() - - # Program FPGA with HDK 3.x.x (with frequency detection method 2) - hdk = list(filter(lambda x: x.startswith('3.'), refdesign.hdk_versions))[-1] - assert hdk.startswith('3.') - image_id = refdesign.get_image_id(hdk) - try: - driver.program_fpga(image_id) - conf_json.reset() - logpath = realpath("./drmlib.%d.%s.log" % (getpid(), time())) - conf_json['settings']['log_file_verbosity'] = 1 - conf_json['settings']['log_file_type'] = 1 - conf_json['settings']['log_file_path'] = logpath - conf_json.save() - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager.get('frequency_detection_method') == 2 - drm_manager.activate() - assert drm_manager.get('frequency_detection_method') == 2 - drm_manager.deactivate() - del drm_manager - gc.collect() - assert isfile(logpath) - with open(logpath, 'rt') as f: - log_content = f.read() - assert "Use license timer counter to compute DRM frequency (method 2)" in log_content - finally: - if isfile(logpath): - remove(logpath) - # Reprogram FPGA with original image - driver.program_fpga(fpga_image_bkp) - - -def test_drm_manager_frequency_detection_bypass(accelize_drm, conf_json, cred_json, async_handler): - """Test bypass of frequency detection""" - - if not accelize_drm.pytest_new_freq_method_supported: - pytest.skip("New frequency detection method is not supported: test skipped") - - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - # Test when bypass = True - conf_json.reset() - conf_json['drm']['bypass_frequency_detection'] = True - conf_json['drm']['frequency_mhz'] = 80 - conf_json.save() drm_manager = accelize_drm.DrmManager( conf_json.path, cred_json.path, @@ -2728,70 +638,7 @@ def test_drm_manager_frequency_detection_bypass(accelize_drm, conf_json, cred_js driver.write_register_callback, async_cb.callback ) - assert drm_manager.get('drm_frequency') == 80 drm_manager.activate() - sleep(1) - assert drm_manager.get('drm_frequency') == 80 - async_cb.assert_NoError() - print('Test bypass_frequency_detection=true: PASS') - - # Test when bypass = False - conf_json.reset() - conf_json['drm']['frequency_mhz'] = 80 - conf_json.save() - with pytest.raises(accelize_drm.exceptions.DRMBadFrequency) as excinfo: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert search(r'DRM frequency .* differs from .* configuration file', - str(excinfo.value)) is not None - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadFrequency.error_code - async_cb.assert_NoError() - print('Test bypass_frequency_detection=false: PASS') - - -@pytest.mark.hwtst -def test_drm_manager_bist(accelize_drm, conf_json, cred_json, async_handler): - """Test register access BIST""" - - driver = accelize_drm.pytest_fpga_driver[0] - async_cb = async_handler.create() - - # Test read callback error - def my_wrong_read_callback(register_offset, returned_data): - addr = register_offset - if register_offset > 0 and register_offset <= 0x40: - addr += 0x4 - return driver.read_register_callback(addr, returned_data, driver) - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - my_wrong_read_callback, - driver.write_register_callback, - async_cb.callback - ) - assert 'DRM Communication Self-Test 2 failed' in str(excinfo.value) - assert 'Please verify' in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadArg.error_code + drm_manager.deactivate() async_cb.assert_NoError() - # Test write callback error - def my_wrong_write_callback(register_offset, data_to_write): - return driver.write_register_callback(register_offset*2, data_to_write, driver) - with pytest.raises(accelize_drm.exceptions.DRMBadArg) as excinfo: - drm_manager = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - my_wrong_write_callback, - async_cb.callback - ) - assert 'DRM Communication Self-Test 2 failed' in str(excinfo.value) - assert 'Please verify' in str(excinfo.value) - assert async_handler.get_error_code(str(excinfo.value)) == accelize_drm.exceptions.DRMBadArg.error_code - async_cb.assert_NoError() diff --git a/tests/utils/alveo_u50/vitis/cpp/Makefile b/tests/utils/alveo_u50/vitis/cpp/Makefile new file mode 100755 index 00000000..40ceef20 --- /dev/null +++ b/tests/utils/alveo_u50/vitis/cpp/Makefile @@ -0,0 +1,62 @@ +VPP := $(XILINX_VITIS)/bin/v++ +EMCONFIGUTIL := $(XILINX_VITIS)/bin/emconfigutil +MODE := hw +#DSA := xilinx_u200_qdma_201910_1 +DSA := xilinx_u50_gen3x16_xdma_201920_3 + +# sources +HOST_SRC := src/host_cpp.cpp +KRNL_SRC := kernel.cpp + +# kernel targets +KRNL_XO := kernel.$(MODE).xo +XCLBIN := kernel.$(MODE).xclbin + +# host target +HOST_EXE := host.exe + +# config files target +EMCONFIG_FILE := emconfig.json + +VPP_OPTS := -s -t $(MODE) --platform $(DSA) +VPP_OPTS += --temp_dir ./all_builds/$(TARGET) +VPP_OPTS += --report_dir ./all_logs/$(TARGET) +VPP_OPTS += --log_dir ./all_logs/$(TARGET) + +CFLAGS := -g -std=c++11 -I$(XILINX_XRT)/include -I/usr/include +LFLAGS := -L$(XILINX_XRT)/lib -lxilinxopencl -lxrt_core -lrt -luuid -L/usr/lib -laccelize_drmc + +# run time args +SUM := 5 +EXE_OPT := kernel.${MODE}.xclbin ${SUM} + +# primary build targets +.PHONY: xclbin app all + +xclbin: $(XCLBIN) +app: $(HOST_EXE) + +all: xclbin app + +clean: + -$(RM) $(EMCONFIG_FILE) $(HOST_EXE) $(XCLBIN) + +# kernel rules +$(KRNL_XO): $(KRNL_SRC) + $(RM) $@ + $(VPP) $(VPP_OPTS) -c -k increment -o $@ $+ + + +$(XCLBIN): $(KRNL_XO) + $(VPP) $(VPP_OPTS) -l -o $@ $(KRNL_XO) + +# host rules +$(HOST_EXE): $(HOST_SRC) + g++ $(CFLAGS) -o $@ $+ $(LFLAGS) + @echo 'Compiled Host Executable: $(HOST_EXE)' + +$(EMCONFIG_FILE): + $(EMCONFIGUTIL) --nd 1 --od . --platform $(DSA) + +check: $(XCLBIN) $(HOST_EXE) $(EMCONFIG_FILE) + XCL_EMULATION_MODE=${MODE} ./$(HOST_EXE) $(EXE_OPT) diff --git a/tests/utils/alveo_u50/vitis/cpp/README.md b/tests/utils/alveo_u50/vitis/cpp/README.md new file mode 100644 index 00000000..9318430f --- /dev/null +++ b/tests/utils/alveo_u50/vitis/cpp/README.md @@ -0,0 +1,17 @@ +bitstream: +---------- +xclbin folder contain a bitstream for u50 with DSA xilinx_u50_gen3x16_xdma_201920_3 and XRT v2.5 + + +To compile: +----------- +source /opt/xilinx/xrt/setup.sh +make app + +To run: +------- +sudo su +source /opt/xilinx/xrt/setup.sh +./host.exe xclbin/adder.xclbin + +TEST PASSED is displayed if the application runs successfully. \ No newline at end of file diff --git a/tests/utils/alveo_u50/vitis/cpp/adder.ini b/tests/utils/alveo_u50/vitis/cpp/adder.ini new file mode 100644 index 00000000..68d06e40 --- /dev/null +++ b/tests/utils/alveo_u50/vitis/cpp/adder.ini @@ -0,0 +1,5 @@ +[connectivity] +stream_connect=krnl_input_stage_rtl_1.p0:krnl_adder_stage_rtl_1.p0 +stream_connect=krnl_adder_stage_rtl_1.p1:krnl_output_stage_rtl_1.p1 +stream_connect=kernel_drm_controller_1.drm_to_uip0:krnl_adder_stage_rtl_1.drm_to_uip +stream_connect=krnl_adder_stage_rtl_1.uip_to_drm:kernel_drm_controller_1.uip0_to_drm diff --git a/tests/utils/vitis/conf.json b/tests/utils/alveo_u50/vitis/cpp/conf.json similarity index 90% rename from tests/utils/vitis/conf.json rename to tests/utils/alveo_u50/vitis/cpp/conf.json index 8782e7e7..9833ea7a 100644 --- a/tests/utils/vitis/conf.json +++ b/tests/utils/alveo_u50/vitis/cpp/conf.json @@ -7,7 +7,7 @@ "url": "https://master.devmetering.accelize.com" }, "drm": { - "frequency_mhz": 250 + "frequency_mhz": 125 }, "settings": { "log_verbosity": 2 diff --git a/tests/utils/alveo_u50/vitis/cpp/cred.json b/tests/utils/alveo_u50/vitis/cpp/cred.json new file mode 100644 index 00000000..7941ac88 --- /dev/null +++ b/tests/utils/alveo_u50/vitis/cpp/cred.json @@ -0,0 +1,8 @@ +{ + "client_id": "mUWLscXBjfpmnU1VOnuGO18GhKL1NiWJC9yQrnl1", "client_secret": "4eaXBt215YGlh7N02Sjc0Do7FeCxocONLafny71FP9jJtCq2Sc6aRHB191xX8rjQMHzUESsY7Bf9qT95nZMm4k6roOLB2IFhQOS9XajvQmDD2i8emyujBRpjQTKPMJva", + "name__admin__":"Admin_JBL_Regression", "client_id__admin__":"30QxJR7b9ozhD7xmkfVPJa6SSGeOVBze4C5tpLGD", "client_secret__admin__":"r601NrMwIwcRt5xEV9iOsefY6clSyRyPMWFwZY8lCTIX2Ub0W9A6bdR9fdc45FsOLenTzsFeAl6fJRDuTYk1qSJO3ub0dN6alvpKjwSYIVW26DDcpJCmQHL57Jo4MZvR", + "client_id__accelize_accelerator_test_01__":"gxYAS0JklllaMj5oC5rgVuooEniVvGvyy9IC7nDr", "client_secret__accelize_accelerator_test_01__":"xnqXQB5W0uaA0KVtKiMzpCuoUroBUMQHjP8o6onK9JI6iLddGj2Vi3pSSHA3uS41D0Xjc27DaKxipwrMPQxPe80xzqyoKhfmZI1vKJH6vafHliInY9yWBNr0tcSgDKtT", + "client_id__accelize_accelerator_test_02__":"mUWLscXBjfpmnU1VOnuGO18GhKL1NiWJC9yQrnl1", "client_secret__accelize_accelerator_test_02__":"4eaXBt215YGlh7N02Sjc0Do7FeCxocONLafny71FP9jJtCq2Sc6aRHB191xX8rjQMHzUESsY7Bf9qT95nZMm4k6roOLB2IFhQOS9XajvQmDD2i8emyujBRpjQTKPMJva", + "client_id__accelize_accelerator_test_03__":"f3UeDnib7Pyyu6SPvnApLnVFwHnx3haxTaHEC47D", "client_secret__accelize_accelerator_test_03__":"Qv49INGB3WAnazPiTKUQ5Htif89EJBY69FKYUXvZpCGTQG3dJOa7veoqciuzBPjqbwfI244VLecj4sDQxWSZGyOTa5yeIblZB2swVGuhx2HcqGYZu5yoWhuRXF9kbT2U", + "client_id__accelize_accelerator_test_04__":"x0y7bkcm0nUYUTctprxyR2rNNVUHw9FajHZCLPCw", "client_secret__accelize_accelerator_test_04__":"zJ4ZJoXt1JXQNpvMI98bQnMDlFXrMDtfi9PzrT4rzJaT0TBcnjzNf0CZyXmmKSIzIvS7CXerCwOhKBpxGrxOKgzmH42u1sauIPGUqXpQNtrbMxP50LL5TDwcRTacpYxz" +} diff --git a/tests/utils/alveo_u50/vitis/cpp/src/host_cpp.cpp b/tests/utils/alveo_u50/vitis/cpp/src/host_cpp.cpp new file mode 100644 index 00000000..6ff0794a --- /dev/null +++ b/tests/utils/alveo_u50/vitis/cpp/src/host_cpp.cpp @@ -0,0 +1,535 @@ +/******************************************************************************* +Description: Vitis DRM Controller Register access +*******************************************************************************/ + +/* +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include + + +#include +#include +#include + +#include "xclhal2.h" +#include "experimental/xclbin-util.h" +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xclhal2.h" +#include "experimental/xclbin-util.h" + +#define CL_HPP_CL_1_2_DEFAULT_BUILD +#define CL_HPP_TARGET_OPENCL_VERSION 120 +#define CL_HPP_MINIMUM_OPENCL_VERSION 120 +#define CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY 1 +#define CL_USE_DEPRECATED_OPENCL_1_2_APIS + +#include +#include + +#include "accelize/drmc.h" + + +#define TARGET_DEVICE "xilinx_u50_gen3x16_xdma_201920_3" + +#define INCR_VALUE 10 +#define DATA_SIZE 4096 +#define MAX_LENGTH 8192 +#define MEM_ALIGNMENT 4096 + +#if defined(SDX_PLATFORM) && !defined(TARGET_DEVICE) +#define STR_VALUE(arg) #arg +#define GET_STRING(name) STR_VALUE(name) +#define TARGET_DEVICE GET_STRING(SDX_PLATFORM) +#endif + +#define OCL_CHECK(error,call) \ + call; \ + if (error != CL_SUCCESS) { \ + printf("%s:%d Error calling " #call ", error code is: %d\n", \ + __FILE__,__LINE__, error); \ + exit(EXIT_FAILURE); \ + } + + +using namespace std; + + +xclDeviceHandle handle; +uuid_t xclbinId; + + +std::vector readBinary(const std::string &fileName) { + std::ifstream file(fileName, std::ios::binary | std::ios::ate); + if (file) { + file.seekg(0, std::ios::end); + streamsize size = file.tellg(); + file.seekg(0, std::ios::beg); + std::vector buffer(size); + file.read((char *)buffer.data(), size); + return buffer; + } else { + return std::vector(0); + } +} + + +template +struct aligned_allocator +{ + using value_type = T; + T* allocate(std::size_t num) + { + void* ptr = nullptr; + if (posix_memalign(&ptr,4096,num*sizeof(T))) + throw std::bad_alloc(); + return reinterpret_cast(ptr); + } + void deallocate(T* p, std::size_t num) + { + free(p); + } +}; + +std::vector read_binary_file(const std::string &xclbin_file_name) { + cout << "INFO: Reading " << xclbin_file_name << endl; + + if (access(xclbin_file_name.c_str(), R_OK) != 0) { + printf("ERROR: %s xclbin not available please build\n", + xclbin_file_name.c_str()); + exit(EXIT_FAILURE); + } + //Loading XCL Bin into char buffer + cout << "Loading: '" << xclbin_file_name.c_str() << "'\n"; + std::ifstream bin_file(xclbin_file_name.c_str(), std::ifstream::binary); + bin_file.seekg(0, bin_file.end); + auto nb = bin_file.tellg(); + bin_file.seekg(0, bin_file.beg); + std::vector buf; + buf.resize(nb); + bin_file.read(reinterpret_cast(buf.data()), nb); + return buf; +} + +std::vector get_devices() { + size_t i; + cl_int err; + std::vector platforms; + cl::Platform::get(&platforms); + cl::Platform platform; + for (i = 0; i < platforms.size(); i++) { + platform = platforms[i]; + std::string platformName = platform.getInfo(&err); + if (platformName == "Xilinx") { + cout << "Found Platform" << endl; + cout << "Platform Name: " << platformName.c_str() << endl; + break; + } + } + if (i == platforms.size()) { + cout << "Error: Failed to find Xilinx platform" << endl; + exit(EXIT_FAILURE); + } + //Getting ACCELERATOR Devices and selecting 1st such device + std::vector devices; + err = platform.getDevices(CL_DEVICE_TYPE_ACCELERATOR, &devices); + return devices; +} + +/* + * Read Register Function + */ +int32_t read_register(uint32_t cuidx, uint32_t addr, uint32_t* value) +{ + xclOpenContext(handle, xclbinId, cuidx, false); + int ret = xclRegRead(handle, cuidx, addr, value); + if (ret) { + cout << "[ERROR] " << __FUNCTION__ << ": Failed to read CU ID" << cuidx << " @0x" << hex << addr << dec << endl; + } + xclCloseContext(handle, xclbinId, cuidx); + return ret; +} + +/* + * Write Register Function + */ +int32_t write_register(uint32_t cuidx, uint32_t addr, uint32_t value) +{ + xclOpenContext(handle, xclbinId, cuidx, false); + int ret = xclRegWrite(handle, cuidx, addr, value); + if (ret) { + cout << "[ERROR] " << __FUNCTION__ << ": Failed to write CU ID" << cuidx << " @0x" << hex << addr << dec << endl; + } + xclCloseContext(handle, xclbinId, cuidx); + return ret; +} + +/* + * DRMLib Read Callback Function + */ +int32_t drm_read_callback(uint32_t addr, uint32_t* value, void* context) +{ + return read_register(*(int*)context, addr, value); +} + +/* + * DRMLib Write Callback Function + */ +int32_t drm_write_callback(uint32_t addr, uint32_t value, void* context) +{ + return write_register(*(int*)context, addr, value); +} + +/* + * DRMLib Error Callback Function + */ +void drm_error_callback( const char* errmsg, void* context ){ + printf("ERROR [DRM]: %s", errmsg); +} + + +/** + * Entry point + */ +int main(int argc, char **argv) { + + if (argc != 2) { + cout << "Usage: " << argv[0] << " " << endl; + return EXIT_FAILURE; + } + + // OpenCL Setup + // OpenCL objects + cl::Device device; + cl::Context context; + cl::Program program; + + // Error Status variable + cl_int err; + + // Create Program Objects + // Load binary from disk + string xclbin = string(argv[1]); + cout << "INFO: loading xclbin " << xclbin << endl; + + // read_binary_file() is a utility API which will load the xclbin + // and will return the pointer to file buffer. + auto binary = read_binary_file(xclbin); + cl::Program::Binaries bins{{binary.data(), binary.size()}}; + + // get_devices() is a utility API which will find the xilinx + // platforms and will return a list of devices connected to Xilinx platform + auto devices = get_devices(); + int valid_device = 0; + for (unsigned int i = 0; i < devices.size(); i++) { + device = devices[i]; + // Creating Context and Command Queue for selected Device + context = cl::Context(device, NULL, NULL, NULL, &err); + cout << "Trying to program device[" << i + << "]: " << device.getInfo() << endl; + program = cl::Program(context, {device}, bins, NULL, &err); + if (err) { + cout << "Failed to program device[" << i + << "] with xclbin file!\n"; + } else { + cout << "Device[" << i << "]: program successful!\n"; + valid_device++; + break; // we break because we found a valid device + } + } + if (valid_device == 0) { + cout << "Failed to program any device found, exit!\n"; + exit(EXIT_FAILURE); + } + + auto platform_id = device.getInfo(&err); + if (err) { + printf("Error: Failed to get device info!\n"); + printf("Test failed\n"); + return EXIT_FAILURE; + } + + xclbin_uuid(binary.data(), xclbinId); + + xclProbe(); + + clGetDeviceInfo(device.get(),CL_DEVICE_HANDLE,sizeof(handle),&handle,nullptr); + + // Creating Kernels + cl::Kernel drm_ctrl_kernel = cl::Kernel(program, "kernel_drm_controller", &err); + if (err) { + printf("Error: Failed to create compute kernel_drm_controller!\n"); + printf("Test failed\n"); + return EXIT_FAILURE; + } + + cl::Kernel input_kernel = cl::Kernel(program, "krnl_input_stage_rtl", &err); + if (err) { + printf("Error: Failed to create compute krnl_input_stage_rtl!\n"); + printf("Test failed\n"); + return EXIT_FAILURE; + } + + cl::Kernel adder_kernel = cl::Kernel(program, "krnl_adder_stage_rtl", &err); + if (err) { + printf("Error: Failed to create compute krnl_adder_stage_rtl!\n"); + printf("Test failed\n"); + return EXIT_FAILURE; + } + + cl::Kernel output_kernel = cl::Kernel(program, "krnl_output_stage_rtl", &err); + if (err) { + printf("Error: Failed to create compute krnl_output_stage_rtl!\n"); + printf("Test failed\n"); + return EXIT_FAILURE; + } + + // Get kernel_drm_controller info + + // checking cu based address for testing purpose: not needed + size_t drm_cuaddr; + xclGetComputeUnitInfo(drm_ctrl_kernel.get(),0,XCL_COMPUTE_UNIT_BASE_ADDRESS,sizeof(drm_cuaddr),&drm_cuaddr,nullptr); + cout << endl << "DRM Ctrl CU addr = " << hex << drm_cuaddr << dec << endl; + // checked + cl_uint drm_cuidx; + xclGetComputeUnitInfo(drm_ctrl_kernel.get(),0,XCL_COMPUTE_UNIT_INDEX,sizeof(drm_cuidx),&drm_cuidx,nullptr); + cout << "DRM Ctrl CU index = " << drm_cuidx << endl; + + // Get krnl_input_stage_rtl info + + // checking cu based address for testing purpose: not needed + size_t in_cuaddr; + xclGetComputeUnitInfo(input_kernel.get(),0,XCL_COMPUTE_UNIT_BASE_ADDRESS,sizeof(in_cuaddr),&in_cuaddr,nullptr); + cout << endl << "Input CU addr = " << hex << in_cuaddr << dec << endl; + // checked + cl_uint in_cuidx = 0; + xclGetComputeUnitInfo(input_kernel.get(),0,XCL_COMPUTE_UNIT_INDEX,sizeof(in_cuidx),&in_cuidx,nullptr); + cout << endl << "Input CU index = " << in_cuidx << endl; + + // Get krnl_adder_stage_rtl info + + // checking cu based address for testing purpose: not needed + size_t add_cuaddr; + xclGetComputeUnitInfo(adder_kernel.get(),0,XCL_COMPUTE_UNIT_BASE_ADDRESS,sizeof(add_cuaddr),&add_cuaddr,nullptr); + cout << endl << "Adder CU addr = " << hex << add_cuaddr << dec << endl; + // checked + cl_uint add_cuidx = 0; + xclGetComputeUnitInfo(adder_kernel.get(),0,XCL_COMPUTE_UNIT_INDEX,sizeof(add_cuidx),&add_cuidx,nullptr); + cout << endl << "Adder CU index = " << add_cuidx << endl; + + // Get krnl_output_stage_rtl info + + // checking cu based address for testing purpose: not needed + size_t out_cuaddr; + xclGetComputeUnitInfo(output_kernel.get(),0,XCL_COMPUTE_UNIT_BASE_ADDRESS,sizeof(out_cuaddr),&out_cuaddr,nullptr); + cout << endl << "Output CU addr = " << hex << out_cuaddr << dec << endl; + // checked + cl_uint out_cuidx = 0; + xclGetComputeUnitInfo(output_kernel.get(),0,XCL_COMPUTE_UNIT_INDEX,sizeof(out_cuidx),&out_cuidx,nullptr); + cout << endl << "Output CU index = " << out_cuidx << endl << endl; + + uint32_t reg; + + // Get DRM Ctrl version + read_register(drm_cuidx, 0x70, ®); + cout << "DRM Controller version: " << hex << reg << dec << endl; + + // Check DRM Activator existance + read_register(add_cuidx, 0x40, ®); + cout << "DRM Activator existance: " << hex << reg << dec << endl; + if (reg != 0x600DC0DE) { + cout << "Error: DRM Activator existance should be 0x600DC0DE" << endl; + return -1; + } + + // Check DRM Activator status + read_register(add_cuidx, 0x38, ®); + if (reg != 0) { + cout << "Error: DRM Activator status should be 0, not " << reg << endl; + return -1; + } + cout << "DRM Activator is locked" << endl; + + //ACCELIZE DRMLIB CODE AREA START + DrmManager *pDrmManager = NULL; + + if (DRM_OK != DrmManager_alloc(&pDrmManager, + "conf.json", + "cred.json", + drm_read_callback, drm_write_callback, drm_error_callback, + &drm_cuidx)) { + printf("Error allocating DRM Manager object: %s", pDrmManager->error_message); + return -1; + } + cout << "[DRMLIB] Allocated" << endl; + + if (DRM_OK != DrmManager_activate(pDrmManager, false)) { + printf("Error activating DRM Manager object: %s", pDrmManager->error_message); + DrmManager_free(&pDrmManager); + return -1; + } + cout << "[DRMLIB] Design unlocked" << endl; + + // Check a DRM Activator is detected + read_register(add_cuidx, 0x40, ®); + if (reg != 0x600DC0DE) { + cout << "Error: No DRM Activator is detected" << endl; + DrmManager_free(&pDrmManager); + return -1; + } + cout << "[DRMLIB] a DRM Activator is detected" << endl; + + // Check DRM Activator status + read_register(add_cuidx, 0x38, ®); + if (reg != 3) { + cout << "Error: DRM Activator status should be 3, not " << reg << endl; + DrmManager_free(&pDrmManager); + return -1; + } + cout << "[DRMLIB] Design unlocked" << endl; + //ACCELIZE DRMLIB CODE AREA STOP + + // Perform some processing with the kernels + + // Allocate Memory in Host Memory + std::vector> source_input(DATA_SIZE); + std::vector> source_hw_results(DATA_SIZE); + std::vector> source_sw_results(DATA_SIZE); + + // Create the test data and Software Result + for (int i = 0; i < DATA_SIZE; i++) { + source_input[i] = i; + source_sw_results[i] = i + INCR_VALUE; + source_hw_results[i] = 0; + } + + auto vector_size_bytes = sizeof(int) * DATA_SIZE; + + // Allocate Buffer in Global Memory + OCL_CHECK(err, + cl::Buffer buffer_input(context, + CL_MEM_USE_HOST_PTR | CL_MEM_READ_ONLY, + vector_size_bytes, + source_input.data(), + &err)); + OCL_CHECK(err, + cl::Buffer buffer_output(context, + CL_MEM_USE_HOST_PTR | CL_MEM_WRITE_ONLY, + vector_size_bytes, + source_hw_results.data(), + &err)); + + // Set the Kernel Arguments + auto inc = INCR_VALUE; + auto size = DATA_SIZE; + OCL_CHECK(err, err = input_kernel.setArg(0, buffer_input)); + OCL_CHECK(err, err = input_kernel.setArg(1, size)); + OCL_CHECK(err, err = adder_kernel.setArg(0, inc)); + OCL_CHECK(err, err = adder_kernel.setArg(1, size)); + OCL_CHECK(err, err = output_kernel.setArg(0, buffer_output)); + OCL_CHECK(err, err = output_kernel.setArg(1, size)); + + // Create a command queue + cl::CommandQueue commands = cl::CommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err); + if (err) { + printf("Error: Failed to create a command commands!\n"); + printf("Error: code %i\n",err); + printf("Test failed\n"); + return EXIT_FAILURE; + } + + // Copy input data to device global memory + cl::Event write_event; + OCL_CHECK(err, err = commands.enqueueMigrateMemObjects( + {buffer_input}, 0, NULL, &write_event)); // 0 means from host + + // Launch the Kernel + std::vector eventVec; + eventVec.push_back(write_event); + OCL_CHECK(err, err = commands.enqueueTask(input_kernel, &eventVec)); + OCL_CHECK(err, err = commands.enqueueTask(adder_kernel, &eventVec)); + OCL_CHECK(err, err = commands.enqueueTask(output_kernel, &eventVec)); + + // Wait for all kernels to finish their operations + OCL_CHECK(err, err = commands.finish()); + + // Copy Result from Device Global Memory to Host Local Memory + OCL_CHECK(err, + err = commands.enqueueMigrateMemObjects({buffer_output}, + CL_MIGRATE_MEM_OBJECT_HOST)); + OCL_CHECK(err, err = commands.finish()); + + // OPENCL HOST CODE AREA END + + + // Compare the results of the Device to the simulation + int mismatch = 0; + for (int i = 0; i < DATA_SIZE; i++) { + if (source_hw_results[i] != source_sw_results[i]) { + cout << "Error: Result mismatch" << endl; + cout << "i = " << i << " CPU result = " << source_sw_results[i] + << " Device result = " << source_hw_results[i] + << endl; + mismatch ++; + if (mismatch > 5) break; + } + } + + if (DRM_OK != DrmManager_deactivate(pDrmManager, false)) + cout << "Error deactivating DRM Manager object: " << pDrmManager->error_message << endl; + else + cout << "[DRMLIB] Design locked" << endl; + + if (DRM_OK != DrmManager_free(&pDrmManager)) + cout << "Error deallocating DRM Manager object: " << pDrmManager->error_message << endl; + //ACCELIZE DRMLIB CODE AREA STOP + +/* + // DOES NOT WORK BECAUSE THE ADDER KERNEL CANNOT BE ACCESSED ANYMORE BUT I DON'T KNOW WHY + + // Check DRM Activator status + read_register(add_cuidx, 0x38, ®); + if (reg != 0) { + cout << "Error: DRM Activator status should be 0, not " << reg << endl; + DrmManager_free(&pDrmManager); + return -1; + } +*/ +/* + free(source_sw_results); + clReleaseMemObject(buffer_input); + clReleaseMemObject(buffer_output); + + clReleaseKernel(drm_ctrl_kernel); + clReleaseKernel(input_kernel); + clReleaseKernel(adder_kernel); + clReleaseKernel(output_kernel); + clReleaseCommandQueue(commands); + clReleaseContext(context); + clReleaseProgram(program); +*/ + cout << "TEST " << (mismatch ? "FAILED" : "PASSED") << endl; + return (mismatch ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/tests/utils/alveo_u50/vitis/cpp/src/kernel_adder_stage.xml b/tests/utils/alveo_u50/vitis/cpp/src/kernel_adder_stage.xml new file mode 100644 index 00000000..669cf6f0 --- /dev/null +++ b/tests/utils/alveo_u50/vitis/cpp/src/kernel_adder_stage.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/utils/alveo_u50/vitis/cpp/src/kernel_input_stage.xml b/tests/utils/alveo_u50/vitis/cpp/src/kernel_input_stage.xml new file mode 100644 index 00000000..ccceda74 --- /dev/null +++ b/tests/utils/alveo_u50/vitis/cpp/src/kernel_input_stage.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/tests/utils/alveo_u50/vitis/cpp/src/kernel_output_stage.xml b/tests/utils/alveo_u50/vitis/cpp/src/kernel_output_stage.xml new file mode 100644 index 00000000..b6d73b7d --- /dev/null +++ b/tests/utils/alveo_u50/vitis/cpp/src/kernel_output_stage.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/tests/utils/alveo_u50/vitis/cpp/xclbin b/tests/utils/alveo_u50/vitis/cpp/xclbin new file mode 120000 index 00000000..54e4a5ba --- /dev/null +++ b/tests/utils/alveo_u50/vitis/cpp/xclbin @@ -0,0 +1 @@ +../xclbin/ \ No newline at end of file diff --git a/tests/utils/alveo_u50/vitis/opencl/Makefile b/tests/utils/alveo_u50/vitis/opencl/Makefile new file mode 100755 index 00000000..e3d66559 --- /dev/null +++ b/tests/utils/alveo_u50/vitis/opencl/Makefile @@ -0,0 +1,62 @@ +VPP := $(XILINX_VITIS)/bin/v++ +EMCONFIGUTIL := $(XILINX_VITIS)/bin/emconfigutil +MODE := hw +#DSA := xilinx_u200_qdma_201910_1 +DSA := xilinx_u50_gen3x16_xdma_201920_3 + +# sources +HOST_SRC := src/host_ocl.cpp +KRNL_SRC := kernel.cpp + +# kernel targets +KRNL_XO := kernel.$(MODE).xo +XCLBIN := kernel.$(MODE).xclbin + +# host target +HOST_EXE := host.exe + +# config files target +EMCONFIG_FILE := emconfig.json + +VPP_OPTS := -s -t $(MODE) --platform $(DSA) +VPP_OPTS += --temp_dir ./all_builds/$(TARGET) +VPP_OPTS += --report_dir ./all_logs/$(TARGET) +VPP_OPTS += --log_dir ./all_logs/$(TARGET) + +CFLAGS := -g -std=c++11 -I$(XILINX_XRT)/include -I/usr/include +LFLAGS := -L$(XILINX_XRT)/lib -lxilinxopencl -lxrt_core -lrt -luuid -L/usr/lib -laccelize_drmc + +# run time args +SUM := 5 +EXE_OPT := kernel.${MODE}.xclbin ${SUM} + +# primary build targets +.PHONY: xclbin app all + +xclbin: $(XCLBIN) +app: $(HOST_EXE) + +all: xclbin app + +clean: + -$(RM) $(EMCONFIG_FILE) $(HOST_EXE) $(XCLBIN) + +# kernel rules +$(KRNL_XO): $(KRNL_SRC) + $(RM) $@ + $(VPP) $(VPP_OPTS) -c -k increment -o $@ $+ + + +$(XCLBIN): $(KRNL_XO) + $(VPP) $(VPP_OPTS) -l -o $@ $(KRNL_XO) + +# host rules +$(HOST_EXE): $(HOST_SRC) + g++ $(CFLAGS) -o $@ $+ $(LFLAGS) + @echo 'Compiled Host Executable: $(HOST_EXE)' + +$(EMCONFIG_FILE): + $(EMCONFIGUTIL) --nd 1 --od . --platform $(DSA) + +check: $(XCLBIN) $(HOST_EXE) $(EMCONFIG_FILE) + XCL_EMULATION_MODE=${MODE} ./$(HOST_EXE) $(EXE_OPT) diff --git a/tests/utils/alveo_u50/vitis/opencl/README.md b/tests/utils/alveo_u50/vitis/opencl/README.md new file mode 100644 index 00000000..9318430f --- /dev/null +++ b/tests/utils/alveo_u50/vitis/opencl/README.md @@ -0,0 +1,17 @@ +bitstream: +---------- +xclbin folder contain a bitstream for u50 with DSA xilinx_u50_gen3x16_xdma_201920_3 and XRT v2.5 + + +To compile: +----------- +source /opt/xilinx/xrt/setup.sh +make app + +To run: +------- +sudo su +source /opt/xilinx/xrt/setup.sh +./host.exe xclbin/adder.xclbin + +TEST PASSED is displayed if the application runs successfully. \ No newline at end of file diff --git a/tests/utils/alveo_u50/vitis/opencl/adder.ini b/tests/utils/alveo_u50/vitis/opencl/adder.ini new file mode 100644 index 00000000..68d06e40 --- /dev/null +++ b/tests/utils/alveo_u50/vitis/opencl/adder.ini @@ -0,0 +1,5 @@ +[connectivity] +stream_connect=krnl_input_stage_rtl_1.p0:krnl_adder_stage_rtl_1.p0 +stream_connect=krnl_adder_stage_rtl_1.p1:krnl_output_stage_rtl_1.p1 +stream_connect=kernel_drm_controller_1.drm_to_uip0:krnl_adder_stage_rtl_1.drm_to_uip +stream_connect=krnl_adder_stage_rtl_1.uip_to_drm:kernel_drm_controller_1.uip0_to_drm diff --git a/tests/utils/alveo_u50/vitis/opencl/conf.json b/tests/utils/alveo_u50/vitis/opencl/conf.json new file mode 100644 index 00000000..9833ea7a --- /dev/null +++ b/tests/utils/alveo_u50/vitis/opencl/conf.json @@ -0,0 +1,16 @@ +{ + "design": { + "udid": "6AE1A700-0000-0000-0000-000000000001", + "boardType": "DRM_125" + }, + "licensing": { + "url": "https://master.devmetering.accelize.com" + }, + "drm": { + "frequency_mhz": 125 + }, + "settings": { + "log_verbosity": 2 + } +} + diff --git a/tests/utils/alveo_u50/vitis/opencl/src/host_ocl.cpp b/tests/utils/alveo_u50/vitis/opencl/src/host_ocl.cpp new file mode 100644 index 00000000..26b069c5 --- /dev/null +++ b/tests/utils/alveo_u50/vitis/opencl/src/host_ocl.cpp @@ -0,0 +1,506 @@ +/******************************************************************************* +Description: Vitis DRM Controller Register access +*******************************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +#include "xclhal2.h" +#include "experimental/xclbin-util.h" + +#include "accelize/drmc.h" + + +#define TARGET_DEVICE "xilinx_u50_gen3x16_xdma_201920_3" + +#define INCR_VALUE 10 +#define DATA_SIZE 4096 +#define MAX_LENGTH 8192 +#define MEM_ALIGNMENT 4096 + +#if defined(SDX_PLATFORM) && !defined(TARGET_DEVICE) +#define STR_VALUE(arg) #arg +#define GET_STRING(name) STR_VALUE(name) +#define TARGET_DEVICE GET_STRING(SDX_PLATFORM) +#endif + + +using namespace std; + +xclDeviceHandle handle; +uuid_t xclbinId; + + +/* + * Read Register Function + */ +int32_t read_register(uint32_t cuidx, uint32_t addr, uint32_t* value) +{ + xclOpenContext(handle, xclbinId, cuidx, false); + int ret = xclRegRead(handle, cuidx, addr, value); + if (ret) { + cout << "[ERROR] " << __FUNCTION__ << ": Failed to read CU ID" << cuidx << " @0x" << hex << addr << dec << endl; + } + xclCloseContext(handle, xclbinId, cuidx); + return ret; +} + +/* + * Write Register Function + */ +int32_t write_register(uint32_t cuidx, uint32_t addr, uint32_t value) +{ + xclOpenContext(handle, xclbinId, cuidx, false); + int ret = xclRegWrite(handle, cuidx, addr, value); + if (ret) { + cout << "[ERROR] " << __FUNCTION__ << ": Failed to write CU ID" << cuidx << " @0x" << hex << addr << dec << endl; + } + xclCloseContext(handle, xclbinId, cuidx); + return ret; +} + +/* + * DRMLib Read Callback Function + */ +int32_t drm_read_callback(uint32_t addr, uint32_t* value, void* context) +{ + return read_register(*(int*)context, addr, value); +} + +/* + * DRMLib Write Callback Function + */ +int32_t drm_write_callback(uint32_t addr, uint32_t value, void* context) +{ + return write_register(*(int*)context, addr, value); +} + +/* + * DRMLib Error Callback Function + */ +void drm_error_callback( const char* errmsg, void* context ){ + printf("ERROR [DRM]: %s", errmsg); +} + +std::vector readBinary(const std::string &fileName) { + std::ifstream file(fileName, std::ios::binary | std::ios::ate); + if (file) { + file.seekg(0, std::ios::end); + streamsize size = file.tellg(); + file.seekg(0, std::ios::beg); + std::vector buffer(size); + file.read((char *)buffer.data(), size); + return buffer; + } else { + return std::vector(0); + } +} + + +/** + * Entry point + */ +int main(int argc, char **argv) { + + if (argc != 2) { + cout << "Usage: " << argv[0] << " " << endl; + return EXIT_FAILURE; + } + + cl_int err; // error code returned from api calls + cl_uint check_status = 0; + const cl_uint number_of_words = 4096; // 16KB of data + + cl_platform_id platform_id; // platform id + cl_device_id device_id; // compute device id + cl_context context; // compute context + + char cl_platform_vendor[1001]; + char target_device_name[1001] = TARGET_DEVICE; + + // Get all platforms and then select Xilinx platform + cl_platform_id platforms[16]; // platform id + cl_uint platform_count; + cl_uint platform_found = 0; + err = clGetPlatformIDs(16, platforms, &platform_count); + if (err != CL_SUCCESS) { + printf("Error: Failed to find an OpenCL platform!\n"); + printf("Test failed\n"); + return EXIT_FAILURE; + } + printf("INFO: Found %d platforms\n", platform_count); + + // Find Xilinx Plaftorm + for (cl_uint iplat=0; iplat binary = readBinary(xclbin); + size_t binary_size = binary.size(); + const unsigned char *kernelbinary = binary.data(); + + // Create the compute program from offline + cl_program program = clCreateProgramWithBinary(context, 1, &device_id, &binary_size, + &kernelbinary, &status, &err); + + if ((!program) || (err!=CL_SUCCESS)) { + printf("Error: Failed to create compute program from binary %d!\n", err); + printf("Test failed\n"); + return EXIT_FAILURE; + } + + cl_kernel drm_ctrl_kernel = clCreateKernel(program, "kernel_drm_controller", &err); + if (!drm_ctrl_kernel || err != CL_SUCCESS) { + printf("Error: Failed to create compute kernel_drm_controller!\n"); + printf("Test failed\n"); + return EXIT_FAILURE; + } + + cl_kernel input_kernel = clCreateKernel(program, "krnl_input_stage_rtl", &err); + if (!input_kernel || err != CL_SUCCESS) { + printf("Error: Failed to create compute krnl_input_stage_rtl!\n"); + printf("Test failed\n"); + return EXIT_FAILURE; + } + + cl_kernel adder_kernel = clCreateKernel(program, "krnl_adder_stage_rtl", &err); + if (!adder_kernel || err != CL_SUCCESS) { + printf("Error: Failed to create compute krnl_adder_stage_rtl!\n"); + printf("Test failed\n"); + return EXIT_FAILURE; + } + + cl_kernel output_kernel = clCreateKernel(program, "krnl_output_stage_rtl", &err); + if (!output_kernel || err != CL_SUCCESS) { + printf("Error: Failed to create compute krnl_output_stage_rtl!\n"); + printf("Test failed\n"); + return EXIT_FAILURE; + } + + xclbin_uuid(kernelbinary, xclbinId); + + handle = xclOpen(0, nullptr, XCL_INFO); + + // Get kernel_drm_controller info + + // checking cu based address for testing purpose: not needed + size_t drm_cuaddr; + xclGetComputeUnitInfo(drm_ctrl_kernel,0,XCL_COMPUTE_UNIT_BASE_ADDRESS,sizeof(drm_cuaddr),&drm_cuaddr,nullptr); + printf("\n DRM Ctrl CU addr = %zx",drm_cuaddr); + + cl_uint drm_cuidx = 0; + xclGetComputeUnitInfo(drm_ctrl_kernel,0,XCL_COMPUTE_UNIT_INDEX,sizeof(drm_cuidx),&drm_cuidx,nullptr); + printf("\n DRM Ctrl CU index = %d\n\n",drm_cuidx); + + // Get krnl_input_stage_rtl info + + // checking cu based address for testing purpose: not needed + size_t in_cuaddr; + xclGetComputeUnitInfo(input_kernel,0,XCL_COMPUTE_UNIT_BASE_ADDRESS,sizeof(in_cuaddr),&in_cuaddr,nullptr); + printf("\n Input CU addr = %zx",in_cuaddr); + // checked + + cl_uint in_cuidx = 0; + xclGetComputeUnitInfo(input_kernel,0,XCL_COMPUTE_UNIT_INDEX,sizeof(in_cuidx),&in_cuidx,nullptr); + printf("\n Input CU index = %d\n\n",in_cuidx); + + // Get krnl_adder_stage_rtl info + + // checking cu based address for testing purpose: not needed + size_t add_cuaddr; + xclGetComputeUnitInfo(adder_kernel,0,XCL_COMPUTE_UNIT_BASE_ADDRESS,sizeof(add_cuaddr),&add_cuaddr,nullptr); + printf("\n Adder CU addr = %zx",add_cuaddr); + // checked + + cl_uint add_cuidx = 0; + xclGetComputeUnitInfo(adder_kernel,0,XCL_COMPUTE_UNIT_INDEX,sizeof(add_cuidx),&add_cuidx,nullptr); + printf("\n Adder CU index = %d\n\n",add_cuidx); + + // Get krnl_output_stage_rtl info + + // checking cu based address for testing purpose: not needed + size_t out_cuaddr; + xclGetComputeUnitInfo(output_kernel,0,XCL_COMPUTE_UNIT_BASE_ADDRESS,sizeof(out_cuaddr),&out_cuaddr,nullptr); + printf("\n Output CU addr = %zx",out_cuaddr); + // checked + + cl_uint out_cuidx = 0; + xclGetComputeUnitInfo(output_kernel,0,XCL_COMPUTE_UNIT_INDEX,sizeof(out_cuidx),&out_cuidx,nullptr); + printf("\n Output CU index = %d\n\n",out_cuidx); + + uint32_t reg; + + // Get DRM Ctrl version + read_register(drm_cuidx, 0x70, ®); + cout << "DRM Controller version: " << hex << reg << dec << endl; + + // Check DRM Activator existance + read_register(add_cuidx, 0x40, ®); + cout << "DRM Activator existance: " << hex << reg << dec << endl; + if (reg != 0x600DC0DE) { + cout << "Error: DRM Activator existance should be 0x600DC0DE" << endl; + return -1; + } + + // Check DRM Activator status + read_register(add_cuidx, 0x38, ®); + if (reg != 0) { + cout << "Error: DRM Activator status should be 0, not " << reg << endl; + return -1; + } + cout << "DRM Activator is locked" << endl; + + //ACCELIZE DRMLIB CODE AREA START + DrmManager *pDrmManager = NULL; + + if (DRM_OK != DrmManager_alloc(&pDrmManager, + "conf.json", + "cred.json", + drm_read_callback, drm_write_callback, drm_error_callback, + &drm_cuidx)) { + printf("Error allocating DRM Manager object: %s", pDrmManager->error_message); + return -1; + } + cout << "[DRMLIB] Allocated" << endl; + + if (DRM_OK != DrmManager_activate(pDrmManager, false)) { + printf("Error activating DRM Manager object: %s", pDrmManager->error_message); + DrmManager_free(&pDrmManager); + return -1; + } + cout << "[DRMLIB] Design unlocked" << endl; + + // Check a DRM Activator is detected + read_register(add_cuidx, 0x40, ®); + if (reg != 0x600DC0DE) { + cout << "Error: No DRM Activator is detected" << endl; + DrmManager_free(&pDrmManager); + return -1; + } + cout << "[DRMLIB] a DRM Activator is detected" << endl; + + // Check DRM Activator status + read_register(add_cuidx, 0x38, ®); + if (reg != 3) { + cout << "Error: DRM Activator status should be 3, not " << reg << endl; + DrmManager_free(&pDrmManager); + return -1; + } + cout << "[DRMLIB] Design unlocked" << endl; + //ACCELIZE DRMLIB CODE AREA STOP + + // Perform some processing with the kernels + + // Allocate buffers + int* source_input; + int* source_hw_results; + int* source_sw_results; + + // Aligning memory in 4K boundary + err = posix_memalign((void**)&source_input,4096,MAX_LENGTH*sizeof(int)); + err |= posix_memalign((void**)&source_hw_results,4096,MAX_LENGTH*sizeof(int)); + err |= posix_memalign((void**)&source_sw_results,4096,MAX_LENGTH*sizeof(int)); + if (err) { + cout << "Fatal Error calling posix_memalign" << endl; + exit(EXIT_FAILURE); + } + + // Fill the buffers + for (int i = 0; i < DATA_SIZE; i++) { + source_input[i] = i; + source_sw_results[i] = i + INCR_VALUE; + source_hw_results[i] = 0; + } + + auto vector_size_bytes = sizeof(int) * DATA_SIZE; + + cl_mem buffer_input = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, + vector_size_bytes, source_input, NULL); + + cl_mem buffer_output = clCreateBuffer(context, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, + vector_size_bytes, source_hw_results, NULL); + + // Set kernel arguments + int size = DATA_SIZE; + int inc = INCR_VALUE; + clSetKernelArg(input_kernel, 0, sizeof(cl_mem), &buffer_input); + clSetKernelArg(input_kernel, 1, sizeof(int), &size); + clSetKernelArg(adder_kernel, 0, sizeof(int), &inc); + clSetKernelArg(adder_kernel, 1, sizeof(int), &size); + clSetKernelArg(output_kernel, 0, sizeof(cl_mem), &buffer_output); + clSetKernelArg(output_kernel, 1, sizeof(int), &size); + + // Create a command queue + cl_command_queue commands = clCreateCommandQueue(context, device_id, CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &err); + if (err || !commands) { + printf("Error: Failed to create a command commands!\n"); + printf("Error: code %i\n",err); + printf("Test failed\n"); + return EXIT_FAILURE; + } + + // Copy input data to device global memory + cl_event write_event; + if (clEnqueueMigrateMemObjects(commands, 1, &buffer_input, 0, 0, nullptr, &write_event)) { + cout << "Fatal Error calling clEnqueueMigrateMemObjects" << endl; + exit(EXIT_FAILURE); + } + + // Launch the kernels + cl_event evts[1] = {write_event}; + err = clEnqueueTask(commands, input_kernel, 1, evts, nullptr); + err |= clEnqueueTask(commands, adder_kernel, 1, evts, nullptr); + err |= clEnqueueTask(commands, output_kernel, 1, evts, nullptr); + if (err) { + cout << "Fatal Error calling clEnqueueTask" << endl; + exit(EXIT_FAILURE); + } + + // Wait for all kernels to finish their operations + if (clFinish(commands)) { + cout << "Fatal Error calling clFinish" << endl; + exit(EXIT_FAILURE); + } + + // Copy Result from Device Global Memory to Host Local Memory + if (clEnqueueMigrateMemObjects(commands, 1, &buffer_output, CL_MIGRATE_MEM_OBJECT_HOST, 0, nullptr, nullptr)) { + cout << "Fatal Error calling clEnqueueMigrateMemObjects" << endl; + exit(EXIT_FAILURE); + } + // Wait for all kernels to finish their operations + if (clFinish(commands)) { + cout << "Fatal Error calling clFinish" << endl; + exit(EXIT_FAILURE); + } + + // Compare the results of the Device to the simulation + int mismatch = 0; + for (int i = 0; i < DATA_SIZE; i++) { + if (source_hw_results[i] != source_sw_results[i]) { + std::cout << "Error: Result mismatch" << std::endl; + std::cout << "i = " << i << " CPU result = " << source_sw_results[i] + << " Device result = " << source_hw_results[i] + << std::endl; + mismatch ++; + if (mismatch > 5) break; + } + } + + if (DRM_OK != DrmManager_deactivate(pDrmManager, false)) + cout << "Error deactivating DRM Manager object: " << pDrmManager->error_message << endl; + else + cout << "[DRMLIB] Design locked" << endl; + + if (DRM_OK != DrmManager_free(&pDrmManager)) + cout << "Error deallocating DRM Manager object: " << pDrmManager->error_message << endl; + //ACCELIZE DRMLIB CODE AREA STOP + +/* + // DOES NOT WORK BECAUSE THE ADDER KERNEL CANNOT BE ACCESSED ANYMORE BUT I DON'T KNOW WHY + + // Check DRM Activator status + read_register(add_cuidx, 0x38, ®); + if (reg != 0) { + cout << "Error: DRM Activator status should be 0, not " << reg << endl; + DrmManager_free(&pDrmManager); + return -1; + } + */ + + clReleaseMemObject(buffer_input); + clReleaseMemObject(buffer_output); + free(source_sw_results); + + clReleaseKernel(drm_ctrl_kernel); + clReleaseKernel(input_kernel); + clReleaseKernel(adder_kernel); + clReleaseKernel(output_kernel); + clReleaseCommandQueue(commands); + clReleaseContext(context); + clReleaseProgram(program); + + cout << "TEST " << (mismatch ? "FAILED" : "PASSED") << endl; + return (mismatch ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/tests/utils/alveo_u50/vitis/opencl/src/kernel_adder_stage.xml b/tests/utils/alveo_u50/vitis/opencl/src/kernel_adder_stage.xml new file mode 100644 index 00000000..669cf6f0 --- /dev/null +++ b/tests/utils/alveo_u50/vitis/opencl/src/kernel_adder_stage.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/utils/alveo_u50/vitis/opencl/src/kernel_input_stage.xml b/tests/utils/alveo_u50/vitis/opencl/src/kernel_input_stage.xml new file mode 100644 index 00000000..ccceda74 --- /dev/null +++ b/tests/utils/alveo_u50/vitis/opencl/src/kernel_input_stage.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/tests/utils/alveo_u50/vitis/opencl/src/kernel_output_stage.xml b/tests/utils/alveo_u50/vitis/opencl/src/kernel_output_stage.xml new file mode 100644 index 00000000..b6d73b7d --- /dev/null +++ b/tests/utils/alveo_u50/vitis/opencl/src/kernel_output_stage.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/tests/utils/alveo_u50/vitis/opencl/xclbin b/tests/utils/alveo_u50/vitis/opencl/xclbin new file mode 120000 index 00000000..54e4a5ba --- /dev/null +++ b/tests/utils/alveo_u50/vitis/opencl/xclbin @@ -0,0 +1 @@ +../xclbin/ \ No newline at end of file diff --git a/tests/utils/alveo_u50/vitis/py/host.py b/tests/utils/alveo_u50/vitis/py/host.py new file mode 100644 index 00000000..dd91bd38 --- /dev/null +++ b/tests/utils/alveo_u50/vitis/py/host.py @@ -0,0 +1,202 @@ +import sys +from ctypes import c_uint, c_int, byref, sizeof, memset, cast, POINTER + +# Following found in PYTHONPATH setup by XRT +from xrt_binding import * + +#sys.path.append('/opt/xilinx/xrt/test/') +from utils_binding import * + +# Get DRM library +sys.path.insert(0, '/opt/accelize/drmlib_jbl/build/python3_bdist') +import accelize_drm + +INCR_VALUE = 10 +DATA_SIZE = 4096 + + +# Global Read Register Function +def read_register(cuidx, addr, value, shared): + xclOpenContext(shared.handle, shared.xuuid, cuidx, False) + try: + return xclRegRead(shared.handle, cuidx, addr, value) + finally: + xclCloseContext(shared.handle, shared.xuuid, cuidx) + +# Global Write Register Function +def write_register(cuidx, addr, value, shared): + xclOpenContext(shared.handle, shared.xuuid, cuidx, False) + try: + return xclRegWrite(shared.handle, cuidx, addr, value) + finally: + xclCloseContext(shared.handle, shared.xuuid, cuidx) + +def py_read_register(cuidx, addr, shared): + reg = c_uint(0) + if read_register(cuidx, addr, byref(reg), shared): + raise RuntimeError("[ERROR] Failed to read CU ID %d @0x%X" % (cuidx, addr)) + return reg.value + +def py_write_register(cuidx, addr, value, shared): + reg = c_uint(value) + if write_register(cuidx, addr, reg, shared): + raise RuntimeError("[ERROR] Failed to write CU ID %d @0x%X" % (cuidx, addr)) + + +def main(args): + mismatch = DATA_SIZE + opt = Options() + Options.getOptions(opt, args) + try: + initXRT(opt) + assert (opt.first_mem >= 0), "Incorrect memory configuration" + + drm_cuidx = 0 + add_cuidx = 1 + + # Load page 0 of DRM Ctrl + py_write_register(drm_cuidx, 0, 0, opt) + + # Get DRM Ctrl version + reg = py_read_register(drm_cuidx, 0x70, opt) + print("DRM Controller version: %X" % reg) + + # Check DRM Activator existance + reg = py_read_register(add_cuidx, 0x40, opt) + print("DRM Activator existance: 0x%X" % reg) + if reg != 0x600DC0DE: + print("Error: DRM Activator existance should be 0x600DC0DE, not %X" % reg); + return -1 + + # Check DRM Activator status + reg = py_read_register(add_cuidx, 0x38, opt); + if reg != 0: + print("Error: DRM Activator status should be 0, not", reg); + return -1 + print("DRM Activator is locked"); + +#ACCELIZE DRMLIB ACTIVATION CODE AREA START + drm_manager = accelize_drm.DrmManager( + 'conf.json', + 'cred.json', + lambda addr, value: read_register(drm_cuidx, addr, value, opt), + lambda addr, value: write_register(drm_cuidx, addr, value, opt) + ) + print('[DRMLIB] Allocated') + + drm_manager.activate() + print("[DRMLIB] Design unlocked") + +#ACCELIZE DRMLIB ACTIVATION CODE AREA STOP + + try: + # Check a DRM Activator is detected + reg = py_read_register(add_cuidx, 0x40, opt); + if reg != 0x600DC0DE: + raise RuntimeError("Error: No DRM Activator is detected") + print("A DRM Activator is detected") + + # Check DRM Activator status + reg = py_read_register(add_cuidx, 0x38, opt) + if reg != 3: + raise RuntimeError("Error: DRM Activator status should be 3, not", reg) + print("Checked Activator is unlocked") + + # Perform some processing with the kernels + try: + c_data_size = sizeof(c_int) * DATA_SIZE + + input_kernel = adder_kernel = output_kernel = None + rInputhandle = rAdderhandle = rOutputhandle = None + input_bo_handle = output_bo_handle = None + input_bo = output_bo = None + + input_kernel = xrtPLKernelOpen(opt.handle, opt.xuuid, 'krnl_input_stage_rtl'.encode('utf-8')) + adder_kernel = xrtPLKernelOpen(opt.handle, opt.xuuid, 'krnl_adder_stage_rtl'.encode('utf-8')) + output_kernel = xrtPLKernelOpen(opt.handle, opt.xuuid, 'krnl_output_stage_rtl'.encode('utf-8')) + + input_bo_handle = xclAllocBO(opt.handle, c_data_size, 0, opt.first_mem) + input_bo = xclMapBO(opt.handle, input_bo_handle, True) + memset(input_bo, 0, DATA_SIZE) + input_bo_int = cast(input_bo, POINTER(c_int)) + for i in range(DATA_SIZE): + input_bo_int[i] = i + + output_bo_handle = xclAllocBO(opt.handle, c_data_size, 0, opt.first_mem) + output_bo = xclMapBO(opt.handle, output_bo_handle, True) + memset(output_bo, 0, DATA_SIZE) + + xclSyncBO(opt.handle, input_bo_handle, xclBOSyncDirection.XCL_BO_SYNC_BO_TO_DEVICE, c_data_size, 0) + xclSyncBO(opt.handle, output_bo_handle, xclBOSyncDirection.XCL_BO_SYNC_BO_TO_DEVICE, c_data_size, 0) + + print("Issue kernel start requests") + rInputhandle = xrtKernelRun(input_kernel, input_bo_handle, DATA_SIZE) + rAdderhandle = xrtKernelRun(adder_kernel, INCR_VALUE, DATA_SIZE) + rOutputhandle = xrtKernelRun(output_kernel, output_bo_handle, DATA_SIZE) + + print("Now wait for the kernels to finish") + xrtRunWait(rInputhandle) + xrtRunWait(rAdderhandle) + xrtRunWait(rOutputhandle) + + print("Get the output data produced by the kernel runs from the device") + xclSyncBO(opt.handle, output_bo_handle, xclBOSyncDirection.XCL_BO_SYNC_BO_FROM_DEVICE, c_data_size, 0) + + # Compare result + hw_result_int = cast(output_bo, POINTER(c_int)) + for i in range(DATA_SIZE): + if hw_result_int[i] == i + INCR_VALUE: + mismatch -= 1 + + except Exception as e: + print('Error:', str(e)) + + finally: + xrtRunClose(rInputhandle) + xrtRunClose(rAdderhandle) + xrtRunClose(rOutputhandle) + + xrtKernelClose(input_kernel) + xrtKernelClose(adder_kernel) + xrtKernelClose(output_kernel) + + xclUnmapBO(opt.handle, input_bo_handle, input_bo) + xclFreeBO(opt.handle, input_bo_handle) + xclUnmapBO(opt.handle, output_bo_handle, output_bo) + xclFreeBO(opt.handle, output_bo_handle) + + finally: +#ACCELIZE DRMLIB DEACTIVATION CODE AREA START + drm_manager.deactivate() + del drm_manager + print("[DRMLIB] Design locked") +#ACCELIZE DRMLIB DEACTIVATION CODE AREA STOP + + # Check DRM Activator status + reg = py_read_register(add_cuidx, 0x38, opt) + if reg != 0: + print("Error: DRM Activator status should be 0, not", reg) + return -1 + print("Checked Activator is locked") + + print("TEST", "FAILED" if mismatch else "PASSED") + return mismatch + + except OSError as o: + print(o) + print("FAILED TEST") + sys.exit(o.errno) + except AssertionError as a: + print(a) + print("FAILED TEST") + sys.exit(1) + except Exception as e: + print(e) + print("FAILED TEST") + sys.exit(1) + finally: + xclClose(opt.handle) + + +if __name__ == "__main__": + main(sys.argv) diff --git a/tests/utils/alveo_u50/vitis/py/utils_binding.py b/tests/utils/alveo_u50/vitis/py/utils_binding.py new file mode 100644 index 00000000..9d3d136f --- /dev/null +++ b/tests/utils/alveo_u50/vitis/py/utils_binding.py @@ -0,0 +1,159 @@ +## + # Copyright (C) 2018-2020 Xilinx, Inc + # Helper routines for Python based XRT tests + # + # Licensed under the Apache License, Version 2.0 (the "License"). You may + # not use this file except in compliance with the License. A copy of the + # License is located at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + # License for the specific language governing permissions and limitations + # under the License. +## +import sys +import getopt +import struct +import ctypes +import uuid +# XRT modules imported from PYTHONPATH +from xclbin_binding import * +from xrt_binding import * +from ert_binding import * + + +class Options(object): + def __init__(self): + self.DATA_SIZE = 1024 + self.sharedLibrary = None + self.bitstreamFile = None + self.halLogFile = None + self.alignment = 4096 + self.option_index = 0 + self.index = 0 + self.cu_index = 0 + self.verbose = False + self.handle = None + self.first_mem = -1 + self.cu_base_addr = -1 + self.xuuid = uuid.uuid4() + self.kernels = [] + + def getOptions(self, argv): + try: + opts, args = getopt.getopt(argv[1:], "k:l:a:c:d:vhe", ["bitstream=", "hal_logfile=", "alignment=", + "cu_index=", "device=", "verbose", "help", "ert"]) + except getopt.GetoptError: + print(self.printHelp()) + sys.exit(2) + + for o, arg in opts: + if o in ("--bitstream", "-k"): + self.bitstreamFile = arg + elif o in ("--hal_logfile", "-l"): + self.halLogFile = arg + elif o in ("--alignment", "-a"): + print("-a/--alignment switch is not supported") + elif o in ("--cu_index", "-c"): + self.cu_index = int(arg) + elif o in ("--device", "-d"): + self.index = int(arg) + elif o in ("--help", "-h"): + print(self.printHelp()) + elif o == "-v": + self.verbose = True + elif o in ("-e", "--ert"): + print("-e/--ert switch is not supported") + else: + assert False, "unhandled option" + + if self.bitstreamFile is None: + raise RuntimeError("No bitstream specified") + + if self.halLogFile: + print("Log files are not supported on command line, Please use xrt.ini to specify logging configuration") + print("Host buffer alignment " + str(self.alignment) + " bytes") + print("Compiled kernel = " + self.bitstreamFile) + + def printHelp(self): + print("usage: %s [options] -k ") + print(" -k ") + print(" -d ") + print(" -c ") + print(" -v") + print(" -h") + print("") + print("* Bitstream is required") + +def initXRT(opt): + deviceInfo = xclDeviceInfo2() + if opt.index >= xclProbe(): + raise RuntimeError("Incorrect device index") + + opt.handle = xclOpen(opt.index, None, xclVerbosityLevel.XCL_INFO) + + xclGetDeviceInfo2(opt.handle, ctypes.byref(deviceInfo)) + + if sys.version_info[0] == 3: + print("Shell = %s" % deviceInfo.mName) + print("Index = %d" % opt.index) + print("PCIe = GEN%d x %d" % (deviceInfo.mPCIeLinkSpeed, deviceInfo.mPCIeLinkWidth)) + print("OCL Frequency = (%d, %d) MHz" % (deviceInfo.mOCLFrequency[0], deviceInfo.mOCLFrequency[1])) + print("DDR Bank = %d" % deviceInfo.mDDRBankCount) + print("Device Temp = %d C" % deviceInfo.mOnChipTemp) + print("MIG Calibration = %s" % deviceInfo.mMigCalib) + else: + print("Shell = %s") % deviceInfo.mName + print("Index = %s") % opt.index + print("PCIe = GEN%s" + " x %s") % (deviceInfo.mPCIeLinkSpeed, deviceInfo.mPCIeLinkWidth) + print("OCL Frequency = %s MHz") % deviceInfo.mOCLFrequency[0] + print("DDR Bank = %d") % deviceInfo.mDDRBankCount + print("Device Temp = %d C") % deviceInfo.mOnChipTemp + print("MIG Calibration = %s") % deviceInfo.mMigCalib + + tempFileName = opt.bitstreamFile + + with open(tempFileName, "rb") as f: + data = bytearray(os.path.getsize(tempFileName)) + f.readinto(data) + f.close() + blob = (ctypes.c_char * len(data)).from_buffer(data) + xbinary = axlf.from_buffer(data) + if xbinary.m_magic.decode("utf-8") != "xclbin2": + raise RuntimeError("Invalid Bitsream") + + xclLoadXclBin(opt.handle, blob) + print("Finished downloading bitstream %s" % opt.bitstreamFile) + + myuuid = memoryview(xbinary.m_header.u2.uuid)[:] + opt.xuuid = uuid.UUID(bytes=myuuid.tobytes()) + head = wrap_get_axlf_section(blob, AXLF_SECTION_KIND.IP_LAYOUT) + layout = ip_layout.from_buffer(data, head.contents.m_sectionOffset) + + if opt.cu_index > layout.m_count: + raise RuntimeError("Can't determine cu base address") + + ip = (ip_data * layout.m_count).from_buffer(data, head.contents.m_sectionOffset + 8) + + for i in range(layout.m_count): + if (ip[i].m_type != 1): + continue + opt.cu_base_addr = ip[i].ip_u1.m_base_address + opt.kernels.append(ctypes.cast(ip[i].m_name, ctypes.c_char_p).value) + print("CU[%d] %s @0x%x" % (i, opt.kernels[-1], opt.cu_base_addr)) + + head = wrap_get_axlf_section(blob, AXLF_SECTION_KIND.MEM_TOPOLOGY) + topo = mem_topology.from_buffer(data, head.contents.m_sectionOffset) + mem = (mem_data * topo.m_count).from_buffer(data, head.contents.m_sectionOffset + 8) + + for i in range(topo.m_count): + print("[%d] %s @0x%x" % (i, ctypes.cast(mem[i].m_tag, ctypes.c_char_p).value, mem[i].mem_u2.m_base_address)) + if (mem[i].m_used == 0): + continue + opt.first_mem = i + break + + return 0 diff --git a/tests/utils/alveo_u50/vitis/py/xclbin b/tests/utils/alveo_u50/vitis/py/xclbin new file mode 120000 index 00000000..900e997c --- /dev/null +++ b/tests/utils/alveo_u50/vitis/py/xclbin @@ -0,0 +1 @@ +../xclbin \ No newline at end of file diff --git a/tests/utils/alveo_u50/vitis/xclbin/adder.xclbin b/tests/utils/alveo_u50/vitis/xclbin/adder.xclbin new file mode 100644 index 00000000..f2d11566 Binary files /dev/null and b/tests/utils/alveo_u50/vitis/xclbin/adder.xclbin differ diff --git a/tests/utils/alveo_u50/vitis/xclbin/adder.xclbin.info b/tests/utils/alveo_u50/vitis/xclbin/adder.xclbin.info new file mode 100644 index 00000000..8356a066 --- /dev/null +++ b/tests/utils/alveo_u50/vitis/xclbin/adder.xclbin.info @@ -0,0 +1,551 @@ + +============================================================================== +XRT Build Version: 2.5.309 (2019.2_PU2) + Build Date: 2020-02-24 02:54:37 + Hash ID: 9a03790c11f066a5597b133db737cf4683ad84c8 +============================================================================== +xclbin Information +------------------ + Generated by: v++ (2019.2.1) on Thu Dec 5 04:48:12 MST 2019 + Version: 2.5.309 + Kernels: kernel_drm_controller, krnl_output_stage_rtl, krnl_input_stage_rtl, krnl_adder_stage_rtl + Signature: + Content: Bitstream + UUID (xclbin): d3ef6007-6355-4884-803b-1fe459023e0c + UUID (IINTF): 862c7020a250293e32036f19956669e5 + Sections: BITSTREAM, MEM_TOPOLOGY, IP_LAYOUT, CONNECTIVITY, + CLOCK_FREQ_TOPOLOGY, BUILD_METADATA, + EMBEDDED_METADATA, SYSTEM_METADATA, PARTITION_METADATA +============================================================================== +Hardware Platform (Shell) Information +------------------------------------- + Vendor: xilinx + Board: u50 + Name: gen3x16_xdma + Version: 201920.3 + Generated Version: Vivado 2019.2 (SW Build: 2708876) + Created: Wed Feb 19 10:53:31 2020 + FPGA Device: xcu50 + Board Vendor: xilinx.com + Board Name: xilinx.com:au50:1.0 + Board Part: xilinx.com:au50:part0:1.0 + Platform VBNV: xilinx_u50_gen3x16_xdma_201920_3 + Static UUID: 00000000-0000-0000-0000-000000000000 + Feature ROM TimeStamp: 0 + +Clocks +------ + Name: hbm_aclk + Index: 0 + Type: SYSTEM + Frequency: 450 MHz + + Name: KERNEL_CLK + Index: 1 + Type: KERNEL + Frequency: 500 MHz + + Name: DATA_CLK + Index: 2 + Type: DATA + Frequency: 125 MHz + +Memory Configuration +-------------------- + Name: HBM[0] + Index: 0 + Type: MEM_HBM + Base Address: 0x0 + Address Size: 0x10000000 + Bank Used: Yes + + Name: HBM[1] + Index: 1 + Type: MEM_DRAM + Base Address: 0x10000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[2] + Index: 2 + Type: MEM_DRAM + Base Address: 0x20000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[3] + Index: 3 + Type: MEM_DRAM + Base Address: 0x30000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[4] + Index: 4 + Type: MEM_DRAM + Base Address: 0x40000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[5] + Index: 5 + Type: MEM_DRAM + Base Address: 0x50000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[6] + Index: 6 + Type: MEM_DRAM + Base Address: 0x60000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[7] + Index: 7 + Type: MEM_DRAM + Base Address: 0x70000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[8] + Index: 8 + Type: MEM_DRAM + Base Address: 0x80000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[9] + Index: 9 + Type: MEM_DRAM + Base Address: 0x90000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[10] + Index: 10 + Type: MEM_DRAM + Base Address: 0xa0000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[11] + Index: 11 + Type: MEM_DRAM + Base Address: 0xb0000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[12] + Index: 12 + Type: MEM_DRAM + Base Address: 0xc0000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[13] + Index: 13 + Type: MEM_DRAM + Base Address: 0xd0000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[14] + Index: 14 + Type: MEM_DRAM + Base Address: 0xe0000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[15] + Index: 15 + Type: MEM_DRAM + Base Address: 0xf0000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[16] + Index: 16 + Type: MEM_DRAM + Base Address: 0x100000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[17] + Index: 17 + Type: MEM_DRAM + Base Address: 0x110000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[18] + Index: 18 + Type: MEM_DRAM + Base Address: 0x120000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[19] + Index: 19 + Type: MEM_DRAM + Base Address: 0x130000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[20] + Index: 20 + Type: MEM_DRAM + Base Address: 0x140000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[21] + Index: 21 + Type: MEM_DRAM + Base Address: 0x150000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[22] + Index: 22 + Type: MEM_DRAM + Base Address: 0x160000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[23] + Index: 23 + Type: MEM_DRAM + Base Address: 0x170000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[24] + Index: 24 + Type: MEM_DRAM + Base Address: 0x180000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[25] + Index: 25 + Type: MEM_DRAM + Base Address: 0x190000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[26] + Index: 26 + Type: MEM_DRAM + Base Address: 0x1a0000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[27] + Index: 27 + Type: MEM_DRAM + Base Address: 0x1b0000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[28] + Index: 28 + Type: MEM_DRAM + Base Address: 0x1c0000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[29] + Index: 29 + Type: MEM_DRAM + Base Address: 0x1d0000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[30] + Index: 30 + Type: MEM_DRAM + Base Address: 0x1e0000000 + Address Size: 0x10000000 + Bank Used: No + + Name: HBM[31] + Index: 31 + Type: MEM_DRAM + Base Address: 0x1f0000000 + Address Size: 0x10000000 + Bank Used: No + + Name: PLRAM[0] + Index: 32 + Type: MEM_DRAM + Base Address: 0x0 + Address Size: 0x0 + Bank Used: No + + Name: PLRAM[1] + Index: 33 + Type: MEM_DRAM + Base Address: 0x0 + Address Size: 0x0 + Bank Used: No + + Name: PLRAM[2] + Index: 34 + Type: MEM_DRAM + Base Address: 0x0 + Address Size: 0x0 + Bank Used: No + + Name: PLRAM[3] + Index: 35 + Type: MEM_DRAM + Base Address: 0x0 + Address Size: 0x0 + Bank Used: No + + Name: dc_0 + Index: 36 + Type: MEM_STREAMING_CONNECTION + Base Address: 0x0 + Address Size: 0x0 + Bank Used: Yes + + Name: dc_1 + Index: 37 + Type: MEM_STREAMING_CONNECTION + Base Address: 0x0 + Address Size: 0x0 + Bank Used: Yes + + Name: dc_2 + Index: 38 + Type: MEM_STREAMING_CONNECTION + Base Address: 0x0 + Address Size: 0x0 + Bank Used: Yes + + Name: dc_3 + Index: 39 + Type: MEM_STREAMING_CONNECTION + Base Address: 0x0 + Address Size: 0x0 + Bank Used: Yes +============================================================================== +Kernel: kernel_drm_controller + +Definition +---------- + Signature: kernel_drm_controller (stream >& drm_to_uip0, stream >& uip0_to_drm) + +Ports +----- + Port: s_axi_control + Mode: slave + Range (bytes): 0x10000 + Data Width: 32 bits + Port Type: addressable + + Port: drm_to_uip0 + Mode: write_only + Range (bytes): + Data Width: 32 bits + Port Type: stream + + Port: uip0_to_drm + Mode: read_only + Range (bytes): + Data Width: 32 bits + Port Type: stream + +-------------------------- +Instance: kernel_drm_controller_1 + Base Address: 0x1400000 + + Argument: drm_to_uip0 + Register Offset: 0x0 + Port: drm_to_uip0 + Memory: dc_0 (MEM_STREAMING_CONNECTION) + + Argument: uip0_to_drm + Register Offset: 0x0 + Port: uip0_to_drm + Memory: dc_2 (MEM_STREAMING_CONNECTION) +Kernel: krnl_output_stage_rtl + +Definition +---------- + Signature: krnl_output_stage_rtl (int* output_r, int size, stream >& p1) + +Ports +----- + Port: m_axi_gmem + Mode: master + Range (bytes): 0xFFFFFFFF + Data Width: 32 bits + Port Type: addressable + + Port: s_axi_control + Mode: slave + Range (bytes): 0x1000 + Data Width: 32 bits + Port Type: addressable + + Port: p1 + Mode: read_only + Range (bytes): + Data Width: 32 bits + Port Type: stream + +-------------------------- +Instance: krnl_output_stage_rtl_1 + Base Address: 0x1430000 + + Argument: output_r + Register Offset: 0x10 + Port: m_axi_gmem + Memory: HBM[0] (MEM_HBM) + + Argument: size + Register Offset: 0x1C + Port: s_axi_control + Memory: + + Argument: p1 + Register Offset: 0x0 + Port: p1 + Memory: dc_1 (MEM_STREAMING_CONNECTION) +Kernel: krnl_input_stage_rtl + +Definition +---------- + Signature: krnl_input_stage_rtl (int* input_r, int size, stream >& p0) + +Ports +----- + Port: m_axi_gmem + Mode: master + Range (bytes): 0xFFFFFFFF + Data Width: 32 bits + Port Type: addressable + + Port: s_axi_control + Mode: slave + Range (bytes): 0x1000 + Data Width: 32 bits + Port Type: addressable + + Port: p0 + Mode: write_only + Range (bytes): + Data Width: 32 bits + Port Type: stream + +-------------------------- +Instance: krnl_input_stage_rtl_1 + Base Address: 0x1420000 + + Argument: input_r + Register Offset: 0x10 + Port: m_axi_gmem + Memory: HBM[0] (MEM_HBM) + + Argument: size + Register Offset: 0x1C + Port: s_axi_control + Memory: + + Argument: p0 + Register Offset: 0x0 + Port: p0 + Memory: dc_3 (MEM_STREAMING_CONNECTION) +Kernel: krnl_adder_stage_rtl + +Definition +---------- + Signature: krnl_adder_stage_rtl (int inc, int size, stream>& p0, stream>& p1, stream>& drm_to_uip, stream>& uip_to_drm) + +Ports +----- + Port: s_axi_control + Mode: slave + Range (bytes): 0x1000 + Data Width: 32 bits + Port Type: addressable + + Port: p0 + Mode: read_only + Range (bytes): + Data Width: 32 bits + Port Type: stream + + Port: p1 + Mode: write_only + Range (bytes): + Data Width: 32 bits + Port Type: stream + + Port: drm_to_uip + Mode: read_only + Range (bytes): + Data Width: 32 bits + Port Type: stream + + Port: uip_to_drm + Mode: write_only + Range (bytes): + Data Width: 32 bits + Port Type: stream + +-------------------------- +Instance: krnl_adder_stage_rtl_1 + Base Address: 0x1410000 + + Argument: inc + Register Offset: 0x10 + Port: s_axi_control + Memory: + + Argument: size + Register Offset: 0x18 + Port: s_axi_control + Memory: + + Argument: p0 + Register Offset: 0x0 + Port: p0 + Memory: dc_3 (MEM_STREAMING_CONNECTION) + + Argument: p1 + Register Offset: 0x0 + Port: p1 + Memory: dc_1 (MEM_STREAMING_CONNECTION) + + Argument: drm_to_uip + Register Offset: 0x0 + Port: drm_to_uip + Memory: dc_0 (MEM_STREAMING_CONNECTION) + + Argument: uip_to_drm + Register Offset: 0x0 + Port: uip_to_drm + Memory: dc_2 (MEM_STREAMING_CONNECTION) +============================================================================== +Generated By +------------ + Command: v++ + Version: 2019.2.1 - Thu Dec 5 04:48:12 MST 2019 (SW BUILD: 2729669) + Command Line: v++ -t hw --platform /opt/xilinx/platforms/xilinx_u50_gen3x16_xdma_201920_3/xilinx_u50_gen3x16_xdma_201920_3.xpfm --save-temps --temp_dir ./build_dir.hw.xilinx_u50_gen3x16_xdma_201920_3 -l --config ./adder.ini --kernel_frequency 0:125 -obuild_dir.hw.xilinx_u50_gen3x16_xdma_201920_3/adder.xclbin _x.hw.xilinx_u50_gen3x16_xdma_201920_3/input.xo _x.hw.xilinx_u50_gen3x16_xdma_201920_3/adder.xo _x.hw.xilinx_u50_gen3x16_xdma_201920_3/output.xo _x.hw.xilinx_u50_gen3x16_xdma_201920_3/drmctrl.xo + Options: -t hw + --platform /opt/xilinx/platforms/xilinx_u50_gen3x16_xdma_201920_3/xilinx_u50_gen3x16_xdma_201920_3.xpfm + --save-temps + --temp_dir ./build_dir.hw.xilinx_u50_gen3x16_xdma_201920_3 + -l + --config ./adder.ini + --kernel_frequency 0:125 + -obuild_dir.hw.xilinx_u50_gen3x16_xdma_201920_3/adder.xclbin _x.hw.xilinx_u50_gen3x16_xdma_201920_3/input.xo _x.hw.xilinx_u50_gen3x16_xdma_201920_3/adder.xo _x.hw.xilinx_u50_gen3x16_xdma_201920_3/output.xo _x.hw.xilinx_u50_gen3x16_xdma_201920_3/drmctrl.xo +============================================================================== +User Added Key Value Pairs +-------------------------- + +============================================================================== diff --git a/tests/utils/CMakeLists.txt b/tests/utils/aws/hdk/CMakeLists.txt similarity index 73% rename from tests/utils/CMakeLists.txt rename to tests/utils/aws/hdk/CMakeLists.txt index a102a775..8bbed03c 100644 --- a/tests/utils/CMakeLists.txt +++ b/tests/utils/aws/hdk/CMakeLists.txt @@ -19,7 +19,7 @@ pkg_check_modules(JSONCPP jsoncpp) include_directories(${JSONCPP_INCLUDEDIR}) # demo C -add_executable(drmutil_c aws/drmutil.c) +add_executable(drmutil_c drmutil.c) target_include_directories(drmutil_c PUBLIC ${FPGAMGMTLIB_INCLUDE_DIRS}) target_include_directories(drmutil_c PRIVATE ${DRMLIB_INCLUDE_DIRS}) target_link_libraries(drmutil_c ${DRMLIB_C_LIBRARIES}) @@ -27,15 +27,7 @@ target_link_libraries(drmutil_c pthread) target_link_libraries(drmutil_c ${FPGAMGMTLIB_LIBRARIES}) # demo CPP -add_executable(drmutil_cpp aws/drmutil.cpp) -target_include_directories(drmutil_cpp PUBLIC ${FPGAMGMTLIB_INCLUDE_DIRS}) -target_include_directories(drmutil_cpp PRIVATE ${DRMLIB_INCLUDE_DIRS}) -target_link_libraries(drmutil_cpp ${DRMLIB_LIBRARIES}) -target_link_libraries(drmutil_cpp pthread) -target_link_libraries(drmutil_cpp ${FPGAMGMTLIB_LIBRARIES}) - -# demo SDAccel -add_executable(drmutil_sdx sdaccel/src/host.cpp) +add_executable(drmutil_cpp drmutil.cpp) target_include_directories(drmutil_cpp PUBLIC ${FPGAMGMTLIB_INCLUDE_DIRS}) target_include_directories(drmutil_cpp PRIVATE ${DRMLIB_INCLUDE_DIRS}) target_link_libraries(drmutil_cpp ${DRMLIB_LIBRARIES}) diff --git a/tests/utils/cmake/FindDRMLIB.cmake b/tests/utils/aws/hdk/cmake/FindDRMLIB.cmake similarity index 100% rename from tests/utils/cmake/FindDRMLIB.cmake rename to tests/utils/aws/hdk/cmake/FindDRMLIB.cmake diff --git a/tests/utils/cmake/FindFPGAMGMTLIB.cmake b/tests/utils/aws/hdk/cmake/FindFPGAMGMTLIB.cmake similarity index 100% rename from tests/utils/cmake/FindFPGAMGMTLIB.cmake rename to tests/utils/aws/hdk/cmake/FindFPGAMGMTLIB.cmake diff --git a/tests/utils/conf.json b/tests/utils/aws/hdk/conf.json similarity index 100% rename from tests/utils/conf.json rename to tests/utils/aws/hdk/conf.json diff --git a/tests/utils/drmutil.c b/tests/utils/aws/hdk/drmutil.c similarity index 96% rename from tests/utils/drmutil.c rename to tests/utils/aws/hdk/drmutil.c index 7dd87def..8f5b06c8 100644 --- a/tests/utils/drmutil.c +++ b/tests/utils/aws/hdk/drmutil.c @@ -50,15 +50,17 @@ #define DRM_NB_PAGES 6 #define MAX_BATCH_CMD 32 -#define INC_EVENT_REG_OFFSET 0x8 - #define PCI_VENDOR_ID 0x1D0F /* Amazon PCI Vendor ID */ #define PCI_DEVICE_ID 0xF000 /* PCI Device ID preassigned by Amazon for F1 applications */ /* Here we add the DRM controller base address */ -#define DRM_CTRL_BASE_ADDR 0x00000 -#define ACTIVATOR_0_BASE_ADDR 0x10000 -#define ACTIVATOR_RANGE_ADDR 0x10000 +#define DRM_CTRL_ADDR 0x0000000 +#define DRM_ACTR_ADDR 0x0010000 +#define DRM_ACTR_ADDR_RANGE 0x10000 + +#define ACT_STATUS_REG_OFFSET 0x38 +#define MAILBOX_REG_OFFSET 0x3C +#define INC_EVENT_REG_OFFSET 0x40 typedef enum {LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG} t_LogLevel; @@ -208,8 +210,8 @@ int tokenize(char str[], t_BatchCmd tokens[], uint32_t* tokens_len) /** Define Three callback for the DRM Lib **/ /* Callback function for DRM library to perform a thread safe register read */ -int read_drm_reg32( uint32_t offset, uint32_t* p_value, void* user_p ) { - if (fpga_pci_peek(*(pci_bar_handle_t*)user_p, DRM_CTRL_BASE_ADDR+offset, p_value)) { +int read_register( uint32_t offset, uint32_t* p_value, void* user_p ) { + if (fpga_pci_peek(*(pci_bar_handle_t*)user_p, DRM_CTRL_ADDR+offset, p_value)) { ERROR("Unable to read from the fpga!"); return 1; } @@ -217,8 +219,8 @@ int read_drm_reg32( uint32_t offset, uint32_t* p_value, void* user_p ) { } /* Callback function for DRM library to perform a thread safe register write */ -int write_drm_reg32( uint32_t offset, uint32_t value, void* user_p ) { - if (fpga_pci_poke(*(pci_bar_handle_t*)user_p, DRM_CTRL_BASE_ADDR+offset, value)) { +int write_register( uint32_t offset, uint32_t value, void* user_p ) { + if (fpga_pci_poke(*(pci_bar_handle_t*)user_p, DRM_CTRL_ADDR+offset, value)) { ERROR("Unable to write to the fpga."); return 1; } @@ -236,7 +238,7 @@ int generate_coin(pci_bar_handle_t* pci_bar_handle, uint32_t ip_index, uint32_t uint32_t c; for(c=0; c < coins; c++) { - if (write_drm_reg32(ACTIVATOR_0_BASE_ADDR + INC_EVENT_REG_OFFSET + ip_index * ACTIVATOR_RANGE_ADDR, 0, pci_bar_handle)) { + if (write_register(DRM_ACTR_ADDR + INC_EVENT_REG_OFFSET + ip_index * DRM_ACTR_ADDR_RANGE, 0, pci_bar_handle)) { ERROR("Failed to increment event counter on activator #%u.", ip_index); return -1; } @@ -253,8 +255,7 @@ int print_all_information( DrmManager* pDrmManager ) { \"session_id\": null,\ \"metered_data\": null,\ \"nodelocked_request_file\": null,\ - \"custom_field\": null,\ - \"strerror\": null }"; + \"custom_field\": null }"; if (DrmManager_get_json_string(pDrmManager, info_in, &info_out )) { ERROR("Failed to get all DRM information: %s", pDrmManager->error_message); @@ -289,7 +290,7 @@ int get_activators_status( DrmManager* pDrmManager, pci_bar_handle_t* pci_bar_ha all_active = true; for(i=0; ierror_message); return -1; @@ -588,7 +589,7 @@ int batch_mode(pci_bar_handle_t* pci_bar_handle, const char* credentialFile, con /* Allocate a DrmManager, providing our previously defined callbacks*/ if (DRM_OK != DrmManager_alloc(&pDrmManager, configurationFile, credentialFile, - read_drm_reg32, write_drm_reg32, print_drm_error, + read_register, write_register, print_drm_error, pci_bar_handle )) { ERROR("Error allocating DRM Manager object"); diff --git a/tests/utils/drmutil.cpp b/tests/utils/aws/hdk/drmutil.cpp similarity index 94% rename from tests/utils/drmutil.cpp rename to tests/utils/aws/hdk/drmutil.cpp index fac8e048..afa8def2 100644 --- a/tests/utils/drmutil.cpp +++ b/tests/utils/aws/hdk/drmutil.cpp @@ -52,15 +52,17 @@ using namespace Accelize::DRM; #define ERROR(format, ...) do { if (sCurrentVerbosity >= LOG_ERROR) __LOG__("ERROR", COLOR_RED , format, ##__VA_ARGS__); } while(0) -#define INC_EVENT_REG_OFFSET 0x8 - #define PCI_VENDOR_ID 0x1D0F /* Amazon PCI Vendor ID */ #define PCI_DEVICE_ID 0xF000 /* PCI Device ID preassigned by Amazon for F1 applications */ /* Here we add the DRM controller base address */ -#define DRM_CTRL_BASE_ADDR 0x00000 -#define ACTIVATOR_0_BASE_ADDR 0x10000 -#define ACTIVATOR_RANGE_ADDR 0x10000 +#define DRM_CTRL_ADDR 0x0000000 +#define DRM_ACTR_ADDR 0x0010000 +#define DRM_ACTR_ADDR_RANGE 0x10000 + +#define ACT_STATUS_REG_OFFSET 0x38 +#define MAILBOX_REG_OFFSET 0x3C +#define INC_EVENT_REG_OFFSET 0x40 #define TRY try { @@ -227,8 +229,8 @@ std::vector tokenize( std::string str ) { /** Define Three callback for the DRM Lib **/ /* Callback function for DRM library to perform a thread safe register read */ -int read_drm_reg32( uint32_t offset, uint32_t* p_value, void* user_p ) { - if (fpga_pci_peek(*(pci_bar_handle_t*)user_p, DRM_CTRL_BASE_ADDR+offset, p_value)) { +int read_register( uint32_t offset, uint32_t* p_value, void* user_p ) { + if (fpga_pci_peek(*(pci_bar_handle_t*)user_p, offset, p_value)) { ERROR("Unable to read from the fpga!"); return 1; } @@ -236,18 +238,14 @@ int read_drm_reg32( uint32_t offset, uint32_t* p_value, void* user_p ) { } /* Callback function for DRM library to perform a thread safe register write */ -int write_drm_reg32( uint32_t offset, uint32_t value, void* user_p ) { - if (fpga_pci_poke(*(pci_bar_handle_t*)user_p, DRM_CTRL_BASE_ADDR+offset, value)) { +int write_register( uint32_t offset, uint32_t value, void* user_p ) { + if (fpga_pci_poke(*(pci_bar_handle_t*)user_p, offset, value)) { ERROR("Unable to write to the fpga."); return 1; } return 0; } -/* Callback function for DRM library in case of asynchronous error during operation */ -void print_drm_error( const std::string errmsg, void* /*user_p*/ ) { - ERROR("From async callback: %s", errmsg.c_str()); -} /** Thread functions that push and pull random data to/from FPGA streams **/ @@ -255,7 +253,7 @@ int generate_coin(pci_bar_handle_t* pci_bar_handle, uint32_t ip_index, uint32_t uint32_t c; for(c=0; c < coins; c++) { - if (write_drm_reg32(ACTIVATOR_0_BASE_ADDR + INC_EVENT_REG_OFFSET + ip_index * ACTIVATOR_RANGE_ADDR, 0, pci_bar_handle)) { + if (write_register(DRM_ACTR_ADDR + INC_EVENT_REG_OFFSET + ip_index * DRM_ACTR_ADDR_RANGE, 0, pci_bar_handle)) { ERROR("Failed to increment event counter on activator #%u.", ip_index); return -1; } @@ -303,7 +301,7 @@ int get_activators_status( DrmManager* pDrmManager, pci_bar_handle_t* pci_bar_ha all_active = true; for(i=0; i +#include +#include + +#include "xcl2.hpp" + +// Accelize DRMLib +#include "accelize/drm.h" + +using namespace std; +using std::vector; + +using namespace Accelize::DRM; + + +xclDeviceHandle boardHandler; + + +/* + * Read Register Function + */ +int32_t read_register(uint32_t addr, uint32_t* value) +{ + if(xclLockDevice(boardHandler)) { + cout << "[ERROR] xclLock failed ..." << endl; + return 1; + } + int ret = (int)xclRead(boardHandler, XCL_ADDR_KERNEL_CTRL, addr, value, 4); + if(ret <= 0) { + cout << "[ERROR] " << __FUNCTION__ << ": Failed to read @0x" << hex << addr << dec << endl; + return 1; + } + if(xclUnlockDevice(boardHandler)) { + cout << "[ERROR] xclUnlock failed ..." << endl; + return -1; + } + return 0; +} + +/* + * Write Register Function + */ +int32_t write_register(uint32_t addr, uint32_t value) +{ + if(xclLockDevice(boardHandler)) { + cout << "[ERROR] xclLock failed ..." << endl; + return 1; + } + int ret = (int)xclWrite(boardHandler, XCL_ADDR_KERNEL_CTRL, addr, &value, 4); + if(ret <= 0) { + cout << "[ERROR] " << __FUNCTION__ << ": Failed to write @0x" << hex << addr << dec << endl; + return 1; + } + if(xclUnlockDevice(boardHandler)) { + cout << "[ERROR] xclUnlock failed ..." << endl; + return -1; + } + return 0; +} + + +/** + * Entry point + */ +int main(int argc, char **argv) { + if (argc != 2) { + cout << "Usage: " << argv[0] << " " << endl; + return EXIT_FAILURE; + } + + string binaryFile = argv[1]; + + //Allocate Memory in Host Memory + auto vector_size_bytes = sizeof(int) * DATA_SIZE; + + vector> source_input(DATA_SIZE); + vector> source_hw_results(DATA_SIZE); + vector> source_sw_results(DATA_SIZE); + + // Create the test data and Software Result + for (int i = 0; i < DATA_SIZE; i++) { + source_input[i] = i; + source_sw_results[i] = i + INCR_VALUE; + source_hw_results[i] = 0; + } + + //OPENCL HOST CODE AREA START + cl_int err; + cl::CommandQueue q; + cl::Context context; + cl::Program program; + //Create Program and Kernels. + auto devices = xcl::get_xil_devices(); + + // read_binary_file() is a utility API which will load the binaryFile + // and will return the pointer to file buffer. + auto fileBuf = xcl::read_binary_file(binaryFile); + cl::Program::Binaries bins{{fileBuf.data(), fileBuf.size()}}; + int valid_device = 0; + for (unsigned int i = 0; i < devices.size(); i++) { + auto device = devices[i]; + // Creating Context and Command Queue for selected Device + OCL_CHECK(err, context = cl::Context({device}, NULL, NULL, NULL, &err)); + OCL_CHECK(err, + q = cl::CommandQueue(context, + device, + CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | + CL_QUEUE_PROFILING_ENABLE, + &err)); + + cout << "Trying to program device[" << i + << "]: " << device.getInfo() << endl; + program = cl::Program(context, {device}, bins, NULL, &err); + if (err != CL_SUCCESS) { + cout << "Failed to program device[" << i + << "] with xclbin file!\n"; + } else { + cout << "Device[" << i << "]: program successful!\n"; + valid_device++; + break; // we break because we found a valid device + } + } + if (valid_device == 0) { + cout << "Failed to program any device found, exit!\n"; + exit(EXIT_FAILURE); + } + + // Init xclhal2 library + if(xclProbe() < 1) { + cout << "[ERROR] xclProbe failed ..." << endl; + return -1; + } + boardHandler = xclOpen(0, "xclhal2_logfile.log", XCL_INFO); + if(boardHandler == NULL) { + cout << "[ERROR] xclOpen failed ..." << endl; + return -1; + } + + // Read DRM Controller version register + uint32_t reg; + write_register(DRM_CTRL_ADDR + 0x0, 0); + read_register(DRM_CTRL_ADDR + 0x70, ®); + cout << "DRM Controller version: " << hex << reg << dec << endl; + + // Check DRM Activator existance + read_register(DRM_ACTR_ADDR + 0x40, ®); + cout << "DRM Activator existance: " << hex << reg << dec << endl; + if (reg != 0x600DC0DE) { + cout << "Error: DRM Activator existance should be 0x600DC0DE" << endl; + return -1; + } + + // Check DRM Activator status + read_register(DRM_ACTR_ADDR + 0x38, ®); + if (reg != 0) { + cout << "Error: DRM Activator status should be 0, not " << reg << endl; + return -1; + } + + // Check DRM Detection Method + read_register(DRM_CTRL_ADDR + 0xFFFC, ®); + cout << "DRM Controller frequency counter = 0x" << hex << reg << dec << endl; + write_register(DRM_CTRL_ADDR + 0xFFFC, 0); + sleep(1); + read_register(DRM_CTRL_ADDR + 0xFFFC, ®); + cout << "DRM Controller frequency counter = 0x" << hex << reg << dec << endl; + + //ACCELIZE DRMLIB CODE AREA START + DrmManager *pDrmManager = new DrmManager( + string("conf.json"), + string("/dev/shm/cred.json"), + [&]( uint32_t offset, uint32_t* p_value ) { // Read DRM register callback + return read_register( DRM_CTRL_ADDR + offset, p_value, pci_bar_handle ); + }, + [&]( uint32_t offset, uint32_t value ) { // Write DRM register callback + return write_register( DRM_CTRL_ADDR + offset, value, pci_bar_handle ); + }, + [&]( const string& errmsg ) { // DRM Error callback + cout << "ERROR: From async callback: " << errmsg.c_str() << endl; + } + ); + cout << "[DRMLIB] Allocated" << endl; + + try { + + pDrmManager->activate(true); + + // Check DRM Activator status + read_register(DRM_ACTR_ADDR + 0x38, ®); + if (reg != 3) { + throw exception("Error: DRM Activator status should be 3"); + } + cout << "[DRMLIB] Design unlocked" << endl; + //ACCELIZE DRMLIB CODE AREA STOP + + OCL_CHECK( + err, + cl::Kernel krnl_adder_stage(program, "krnl_adder_stage_rtl", &err)); + OCL_CHECK( + err, + cl::Kernel krnl_input_stage(program, "krnl_input_stage_rtl", &err)); + OCL_CHECK( + err, + cl::Kernel krnl_output_stage(program, "krnl_output_stage_rtl", &err)); + + //Allocate Buffer in Global Memory + OCL_CHECK(err, + cl::Buffer buffer_input(context, + CL_MEM_USE_HOST_PTR | CL_MEM_READ_ONLY, + vector_size_bytes, + source_input.data(), + &err)); + OCL_CHECK(err, + cl::Buffer buffer_output(context, + CL_MEM_USE_HOST_PTR | CL_MEM_WRITE_ONLY, + vector_size_bytes, + source_hw_results.data(), + &err)); + + auto inc = INCR_VALUE; + auto size = DATA_SIZE; + //Set the Kernel Arguments + OCL_CHECK(err, err = krnl_input_stage.setArg(0, buffer_input)); + OCL_CHECK(err, err = krnl_input_stage.setArg(1, size)); + OCL_CHECK(err, err = krnl_adder_stage.setArg(0, inc)); + OCL_CHECK(err, err = krnl_adder_stage.setArg(1, size)); + OCL_CHECK(err, err = krnl_output_stage.setArg(0, buffer_output)); + OCL_CHECK(err, err = krnl_output_stage.setArg(1, size)); + + //Copy input data to device global memory + cl::Event write_event; + OCL_CHECK( + err, + err = q.enqueueMigrateMemObjects( + {buffer_input}, 0 /* 0 means from host*/, NULL, &write_event)); + + //Launch the Kernel + vector eventVec; + eventVec.push_back(write_event); + OCL_CHECK(err, err = q.enqueueTask(krnl_input_stage, &eventVec)); + OCL_CHECK(err, err = q.enqueueTask(krnl_adder_stage, &eventVec)); + OCL_CHECK(err, err = q.enqueueTask(krnl_output_stage, &eventVec)); + + //wait for all kernels to finish their operations + OCL_CHECK(err, err = q.finish()); + + //Copy Result from Device Global Memory to Host Local Memory + OCL_CHECK(err, + err = q.enqueueMigrateMemObjects({buffer_output}, + CL_MIGRATE_MEM_OBJECT_HOST)); + OCL_CHECK(err, err = q.finish()); + + //OPENCL HOST CODE AREA END + + //ACCELIZE DRMLIB CODE AREA START + pDrmManager=>deactivate(false) + cout << "[DRMLIB] Design locked" << endl; + + } catch( const Exception& e ) { + cout << "ERROR: [DRMLIB] Following error occurred: " << e.what() << endl; + } catch( const exception& e ) { + cout << "ERROR: Following error occurred: " << e.what() << endl; + } catch(...) { + cout << "ERROR: Unsupported error" << endl; + } + delete pDrmManager; + pDrmManager = nullptr; + //ACCELIZE DRMLIB CODE AREA STOP + + // Check DRM Activator status + read_register(DRM_ACTR_ADDR + 0x38, ®); + if (reg != 0) { + cout << "Error: DRM Activator status should be 0, not " << reg << endl; + return -1; + } + + // Release xclhal2 board handler + xclClose(boardHandler); + + // Compare the results of the Device to the simulation + int match = 0; + for (int i = 0; i < DATA_SIZE; i++) { + if (source_hw_results[i] != source_sw_results[i]) { + cout << "Error: Result mismatch" << endl; + cout << "i = " << i << " CPU result = " << source_sw_results[i] + << " Device result = " << source_hw_results[i] + << endl; + match = 1; + break; + } + } + + + cout << "TEST " << (match ? "FAILED" : "PASSED") << endl; + return (match ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/tests/utils/vitis/src/host.cpp b/tests/utils/aws/vitis/src/host_c.cpp similarity index 80% rename from tests/utils/vitis/src/host.cpp rename to tests/utils/aws/vitis/src/host_c.cpp index 071f4ece..e09d61d8 100644 --- a/tests/utils/vitis/src/host.cpp +++ b/tests/utils/aws/vitis/src/host_c.cpp @@ -58,16 +58,16 @@ xclDeviceHandle boardHandler; int32_t read_register(uint32_t addr, uint32_t* value) { if(xclLockDevice(boardHandler)) { - std::cout << "[ERROR] xclLock failed ..." << std::endl; + printf("[ERROR] xclLock failed\n"); return 1; } int ret = (int)xclRead(boardHandler, XCL_ADDR_KERNEL_CTRL, addr, value, 4); if(ret <= 0) { - std::cout << "[ERROR] " << __FUNCTION__ << ": Failed to read @0x" << std::hex << addr << std::dec << std::endl; + printf("[ERROR] %s: Failed to read @0x%08X\n", __FUNCTION__, addr); return 1; } if(xclUnlockDevice(boardHandler)) { - std::cout << "[ERROR] xclUnlock failed ..." << std::endl; + printf("[ERROR] xclUnlock failed\n"); return -1; } return 0; @@ -79,16 +79,16 @@ int32_t read_register(uint32_t addr, uint32_t* value) int32_t write_register(uint32_t addr, uint32_t value) { if(xclLockDevice(boardHandler)) { - std::cout << "[ERROR] xclLock failed ..." << std::endl; + printf("[ERROR] xclLock failed\n"); return 1; } int ret = (int)xclWrite(boardHandler, XCL_ADDR_KERNEL_CTRL, addr, &value, 4); if(ret <= 0) { - std::cout << "[ERROR] " << __FUNCTION__ << ": Failed to write @0x" << std::hex << addr << std::dec << std::endl; + printf("[ERROR] %s: Failed to write @0x%08X\n", __FUNCTION__, addr); return 1; } if(xclUnlockDevice(boardHandler)) { - std::cout << "[ERROR] xclUnlock failed ..." << std::endl; + printf("[ERROR] xclUnlock failed\n"); return -1; } return 0; @@ -123,7 +123,7 @@ void drm_error_callback( const char* errmsg, void* context ){ */ int main(int argc, char **argv) { if (argc != 2) { - std::cout << "Usage: " << argv[0] << " " << std::endl; + printf("Usage: %s ", argv[0]); return EXIT_FAILURE; } @@ -132,9 +132,9 @@ int main(int argc, char **argv) { //Allocate Memory in Host Memory auto vector_size_bytes = sizeof(int) * DATA_SIZE; - std::vector> source_input(DATA_SIZE); - std::vector> source_hw_results(DATA_SIZE); - std::vector> source_sw_results(DATA_SIZE); + vector> source_input(DATA_SIZE); + vector> source_hw_results(DATA_SIZE); + vector> source_sw_results(DATA_SIZE); // Create the test data and Software Result for (int i = 0; i < DATA_SIZE; i++) { @@ -167,31 +167,29 @@ int main(int argc, char **argv) { CL_QUEUE_PROFILING_ENABLE, &err)); - std::cout << "Trying to program device[" << i - << "]: " << device.getInfo() << std::endl; + printf("Trying to program device[%d]: %s\n", i, device.getInfo()); program = cl::Program(context, {device}, bins, NULL, &err); if (err != CL_SUCCESS) { - std::cout << "Failed to program device[" << i - << "] with xclbin file!\n"; + printf("Failed to program device[%d] with xclbin file!\n", i); } else { - std::cout << "Device[" << i << "]: program successful!\n"; + printf("Device[%d]: program successful!\n", i); valid_device++; break; // we break because we found a valid device } } if (valid_device == 0) { - std::cout << "Failed to program any device found, exit!\n"; + printf("Failed to program any device found, exit!\n"); exit(EXIT_FAILURE); } // Init xclhal2 library if(xclProbe() < 1) { - std::cout << "[ERROR] xclProbe failed ..." << std::endl; + printf("[ERROR] xclProbe failed\n"); return -1; } boardHandler = xclOpen(0, "xclhal2_logfile.log", XCL_INFO); if(boardHandler == NULL) { - std::cout << "[ERROR] xclOpen failed ..." << std::endl; + printf("[ERROR] xclOpen failed\n"); return -1; } @@ -199,20 +197,20 @@ int main(int argc, char **argv) { uint32_t reg; write_register(DRM_CTRL_ADDRESS + 0x0, 0); read_register(DRM_CTRL_ADDRESS + 0x70, ®); - std::cout << "DRM Controller version: " << std::hex << reg << std::dec << std::endl; + printf("DRM Controller version: %X\n", reg); // Check DRM Activator existance read_register(DRM_ACTR_ADDRESS + 0x40, ®); - std::cout << "DRM Activator existance: " << std::hex << reg << std::dec << std::endl; + printf("DRM Activator existance: %X\n", reg); if (reg != 0x600DC0DE) { - std::cout << "Error: DRM Activator existance should be 0x600DC0DE" << std::endl; + printf("Error: DRM Activator existance should be 0x600DC0DE\n"); return -1; } // Check DRM Activator status read_register(DRM_ACTR_ADDRESS + 0x38, ®); if (reg != 0) { - std::cout << "Error: DRM Activator status should be 0, not " << reg << std::endl; + printf("Error: DRM Activator status should be 0, not %d\n", reg); return -1; } @@ -235,7 +233,7 @@ int main(int argc, char **argv) { printf("Error allocating DRM Manager object: %s", pDrmManager->error_message); return -1; } - std::cout << "[DRMLIB] Allocated" << std::endl; + printf("[DRMLIB] Allocated\n"); if (DRM_OK != DrmManager_activate(pDrmManager, false)) { printf("Error activating DRM Manager object: %s", pDrmManager->error_message); @@ -245,11 +243,11 @@ int main(int argc, char **argv) { // Check DRM Activator status read_register(DRM_ACTR_ADDRESS + 0x38, ®); if (reg != 3) { - std::cout << "Error: DRM Activator status should be 3, not " << reg << std::endl; + printf("Error: DRM Activator status should be 3, not %d\n", reg); DrmManager_free(&pDrmManager); return -1; } - std::cout << "[DRMLIB] Design unlocked" << std::endl; + printf("[DRMLIB] Design unlocked\n"); //ACCELIZE DRMLIB CODE AREA STOP OCL_CHECK( @@ -294,7 +292,7 @@ int main(int argc, char **argv) { {buffer_input}, 0 /* 0 means from host*/, NULL, &write_event)); //Launch the Kernel - std::vector eventVec; + vector eventVec; eventVec.push_back(write_event); OCL_CHECK(err, err = q.enqueueTask(krnl_input_stage, &eventVec)); OCL_CHECK(err, err = q.enqueueTask(krnl_adder_stage, &eventVec)); @@ -315,7 +313,7 @@ int main(int argc, char **argv) { if (DRM_OK != DrmManager_deactivate(pDrmManager, false)) printf("Error deactivating DRM Manager object: %s", pDrmManager->error_message); else - std::cout << "[DRMLIB] Design locked" << std::endl; + printf("[DRMLIB] Design locked\n"); if (DRM_OK != DrmManager_free(&pDrmManager)) printf("Error deallocating DRM Manager object: %s", pDrmManager->error_message); @@ -324,8 +322,7 @@ int main(int argc, char **argv) { // Check DRM Activator status read_register(DRM_ACTR_ADDRESS + 0x38, ®); if (reg != 0) { - std::cout << "Error: DRM Activator status should be 0, not " << reg << std::endl; - DrmManager_free(&pDrmManager); + printf("Error: DRM Activator status should be 0, not %s", reg); return -1; } @@ -336,16 +333,14 @@ int main(int argc, char **argv) { int match = 0; for (int i = 0; i < DATA_SIZE; i++) { if (source_hw_results[i] != source_sw_results[i]) { - std::cout << "Error: Result mismatch" << std::endl; - std::cout << "i = " << i << " CPU result = " << source_sw_results[i] - << " Device result = " << source_hw_results[i] - << std::endl; + printf("Error: Result mismatch\n"); + printf("i = %d: CPU result = %d vs Device result = %d", i, source_sw_results[i], source_hw_results[i]); match = 1; break; } } - std::cout << "TEST " << (match ? "FAILED" : "PASSED") << std::endl; + printf("TEST %s", match ? "FAILED" : "PASSED"); return (match ? EXIT_FAILURE : EXIT_SUCCESS); } diff --git a/tests/utils/vitis/utils.mk b/tests/utils/aws/vitis/utils.mk similarity index 100% rename from tests/utils/vitis/utils.mk rename to tests/utils/aws/vitis/utils.mk diff --git a/tests/utils/vitis/xcl2.mk b/tests/utils/aws/vitis/xcl2.mk similarity index 100% rename from tests/utils/vitis/xcl2.mk rename to tests/utils/aws/vitis/xcl2.mk