diff --git a/CHANGELOG b/CHANGELOG index 123895af..ddac9bf1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +* Wed Nov 07 2018 Accelize v1.1.1 +- DOC: Documentation for ReadTheDoc +- FIX: Stop session issue on retry + * Mon Oct 08 2018 Accelize v1.1.0 - NEW: MeteringSessionManager robustness to network disconnections diff --git a/CMakeLists.txt b/CMakeLists.txt index 8094e4c2..f72cad1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,10 @@ cmake_minimum_required (VERSION 2.8.12) project(accelize/drmlib) +if(COVERAGE) +include(release-tools/cmake/codecoverage.cmake) +endif() + # Build Type set(default_build_type "RelWithDebInfo") if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) @@ -136,6 +140,25 @@ install(DIRECTORY ${CMAKE_BINARY_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLU install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses COMPONENT licenses) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/third-party-licenses/ DESTINATION ${CMAKE_INSTALL_DOCDIR}/licenses/third-party-licenses/ COMPONENT licenses) +message("CMAKE_BINARY_DIR is ${CMAKE_BINARY_DIR}") +message("CMAKE_CURRENT_SOURCE_DIR is ${CMAKE_CURRENT_SOURCE_DIR}") + +# Code coverage +option(COVERAGE "Activate code coverage" OFF) +if(COVERAGE) + get_filename_component(_coverage_path ${CMAKE_BINARY_DIR} DIRECTORY) + + APPEND_COVERAGE_FLAGS() + # Install coverage information (.gcno) and objects files generated by compiler + install(DIRECTORY ${CMAKE_BINARY_DIR}/CMakeFiles DESTINATION build_coverage/build/${CMAKE_BINARY_DIR}/ COMPONENT coverage) + + # Install sources + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/drm_controller_sdk DESTINATION build_coverage/src/${CMAKE_CURRENT_SOURCE_DIR}/ COMPONENT coverage) + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include DESTINATION build_coverage/src/${CMAKE_CURRENT_SOURCE_DIR}/ COMPONENT coverage) + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/internal_inc DESTINATION build_coverage/src/${CMAKE_CURRENT_SOURCE_DIR}/ COMPONENT coverage) + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/source DESTINATION build_coverage/src/${CMAKE_CURRENT_SOURCE_DIR}/ COMPONENT coverage) +endif(COVERAGE) + # Documentation option(DOC "Produce documentation" OFF) if(DOC) @@ -155,7 +178,7 @@ endif(DOC) # Packages set(CPACK_GENERATOR "TGZ;RPM") -set(CPACK_PACKAGE_NAME "libaccelize_drm") +set(CPACK_PACKAGE_NAME "libaccelize_drm${PACKAGE_NAME_SUFFIX}") set(CPACK_PACKAGE_VENDOR "Accelize") set(CPACK_PACKAGE_CONTACT "accelize.com") set(CPACK_PACKAGE_MAINTAINER "accelize.com") @@ -177,3 +200,7 @@ cpack_add_component(libraries GROUP devel) cpack_add_component(headers GROUP devel) cpack_add_component(doc GROUP devel) cpack_add_component(licenses GROUP devel) + +if(COVERAGE) +cpack_add_component(coverage GROUP devel) +endif() diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 47747c78..d1eef36b 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -22,3 +22,4 @@ FULL_PATH_NAMES=YES STRIP_FROM_PATH=@CMAKE_BINARY_DIR@ STRIP_FROM_INC_PATH=@CMAKE_BINARY_DIR@/include GENERATE_LATEX=NO +GENERATE_XML=YES diff --git a/doc/_static/accelize.css b/doc/_static/accelize.css new file mode 100644 index 00000000..5dc1e137 --- /dev/null +++ b/doc/_static/accelize.css @@ -0,0 +1,16 @@ +.wy-side-nav-search { + background-image: url("background.png"); + background-repeat: no-repeat; + background-size: contain; + background-position: top; + background-color: #ea7222 +} + +.wy-side-nav-search input[type="text"] { + border-color: #ea7222 +} + +.wy-side-nav-search > a, .wy-side-nav-search .wy-dropdown > a { + color: #ea7222 +} + diff --git a/doc/_static/accelize_logo.png b/doc/_static/accelize_logo.png new file mode 100644 index 00000000..19712f7c Binary files /dev/null and b/doc/_static/accelize_logo.png differ diff --git a/doc/_static/background.png b/doc/_static/background.png new file mode 100644 index 00000000..9e512e37 Binary files /dev/null and b/doc/_static/background.png differ diff --git a/doc/_static/favicon.ico b/doc/_static/favicon.ico new file mode 100644 index 00000000..009e905a Binary files /dev/null and b/doc/_static/favicon.ico differ diff --git a/doc/_static/logo.png b/doc/_static/logo.png new file mode 100644 index 00000000..c3531d7b Binary files /dev/null and b/doc/_static/logo.png differ diff --git a/doc/c_api.rst b/doc/c_api.rst new file mode 100644 index 00000000..109a17b9 --- /dev/null +++ b/doc/c_api.rst @@ -0,0 +1,33 @@ +C API +===== + +Files +----- + +common.h +~~~~~~~~ + +.. doxygenfile:: drmc/common.h + :project: drmlib + + +errorcode.h +~~~~~~~~~~~ + +.. doxygenfile:: drmc/errorcode.h + :project: drmlib + + +metering.h +~~~~~~~~~~ + +.. doxygenfile:: drmc/metering.h + :project: drmlib + + +version.h +~~~~~~~~~ + +.. doxygenfile:: drmc/version.h + :project: drmlib + diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 00000000..0c24b902 --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +"""Sphinx documentation """ + +# -- Path setup -------------------------------------------------------------- + +import os +import subprocess +from os.path import abspath, dirname +import sys + + + +# -- Project information ----------------------------------------------------- + +project = "drmlib" +copyright = "Accelize" +author = "jeydoux@accelize.com" +version = "v1.1" +release = "v1.1" + + +sys.path.append( "/home/me/docproj/ext/breathe/" ) + + +read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True' + +if read_the_docs_build: + + subprocess.call('pip install breathe', shell=True) + subprocess.call('doxygen Doxyfile.in', shell=True) + +breathe_projects = { + "drmlib":"xml/" + } + +extensions = [ 'breathe'] + +source_suffix = '.rst' +master_doc = 'index' +language = 'en' +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.settings'] +pygments_style = 'default' + + +# -- Options for HTML output ------------------------------------------------- + + +html_theme = 'sphinx_rtd_theme' + +html_favicon = '_static/favicon.ico' + +html_context = { + 'css_files': ['_static/accelize.css'], # Overwrite them style +} + +html_logo = '_static/logo.png' + +html_show_sourcelink = False + +html_show_sphinx = False + +# -- Options for HTMLHelp output --------------------------------------------- + +htmlhelp_basename = '%sdoc' % project + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = {} +latex_documents = [( + master_doc, '%s.tex' % project, '%s Documentation' % project, author, + 'manual')] + +latex_logo = '_static/logo.png' +# -- Options for manual page output ------------------------------------------ + +man_pages = [( + master_doc, "my_name", '%s Documentation' % project, + [author], 1)] + + +# -- Options for Texinfo output ---------------------------------------------- + +texinfo_documents = [( + master_doc, project, '%s Documentation' % project, author, project, + "my_description", 'Miscellaneous')] diff --git a/doc/cpp_api.rst b/doc/cpp_api.rst new file mode 100644 index 00000000..41d6e8b2 --- /dev/null +++ b/doc/cpp_api.rst @@ -0,0 +1,46 @@ +C++ API +======= + +Namespaces +---------- + +.. doxygennamespace:: Accelize::DRMLib + :project: drmlib + :undoc-members: + + +Classes +------- + +.. doxygenclass:: Accelize::DRMLib::MeteringSessionManager + :project: drmlib + + +.. doxygenclass:: Accelize::DRMLib::Exception + :project: drmlib + + +Files +----- + +session_manager.h +~~~~~~~~~~~~~~~~~ + +.. doxygenfile:: drm/session_manager.h + :project: drmlib + + + +error.h +~~~~~~~ + +.. doxygenfile:: drm/error.h + :project: drmlib + + +version.h +~~~~~~~~~ + +.. .. doxygenfile:: drm/version.h +.. :project: drmlib + \ No newline at end of file diff --git a/doc/index.rst b/doc/index.rst new file mode 100644 index 00000000..743e9212 --- /dev/null +++ b/doc/index.rst @@ -0,0 +1,9 @@ +DRM SDK API +=========== + + +.. toctree:: + :maxdepth: 5 + + cpp_api + c_api diff --git a/include/accelize/drmc/metering.h b/include/accelize/drmc/metering.h index e127ad10..a27df980 100644 --- a/include/accelize/drmc/metering.h +++ b/include/accelize/drmc/metering.h @@ -30,7 +30,7 @@ limitations under the License. extern "C" { #endif -#include "stdint.h" +#include struct MeteringSessionManager_s; diff --git a/source/session_manager.cpp b/source/session_manager.cpp index ebe2fd5e..70fc5b35 100644 --- a/source/session_manager.cpp +++ b/source/session_manager.cpp @@ -76,6 +76,9 @@ class DRMLIB_LOCAL MeteringSessionManager::Impl { std::string sessionID; std::string udid; std::string boardType; + Json::Value last_stop_session_json_req; + Json::Value last_start_session_json_req; + Json::Value last_resume_session_json_req; // thread to maintain alive std::future threadKeepAlive; @@ -221,7 +224,7 @@ class DRMLIB_LOCAL MeteringSessionManager::Impl { unsigned int numberOfDetectedIps; std::string saasChallenge; std::vector meteringFile; - checkDRMCtlrRet( getDrmController().endSessionAndExtractMeteringFile( numberOfDetectedIps, saasChallenge, meteringFile ) ); + checkDRMCtlrRet( getDrmController().endSessionAndExtractMeteringFile( numberOfDetectedIps, saasChallenge, meteringFile ) ); json_output["saasChallenge"] = saasChallenge; json_output["meteringFile"] = std::accumulate(meteringFile.begin(), meteringFile.end(), std::string("")); json_output["request"] = "close"; @@ -288,6 +291,8 @@ class DRMLIB_LOCAL MeteringSessionManager::Impl { next_license_duration = std::chrono::seconds(json_license["metering"]["timeoutSecond"].asUInt()); next_license_duration_exact = true; + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + debug_print_drm_hw_report(); } @@ -296,6 +301,7 @@ class DRMLIB_LOCAL MeteringSessionManager::Impl { static const std::string nullLicense(352, '0'); checkDRMCtlrRet( getDrmController().writeLicenseFilePageRegister() ); checkDRMCtlrRet( getDrmController().writeLicenseFileRegister(nullLicense) ); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); Assert(!isLicense_no_lock()); } @@ -308,6 +314,10 @@ class DRMLIB_LOCAL MeteringSessionManager::Impl { return (err == DrmControllerLibrary::mDrmErrorNoError); } + bool isSession_no_lock() { + return isLicense_no_lock(); + } + void debug_print_drm_hw_report() { /* This function must be used with mDrmControllerMutex locked */ if(!isDebug()) return; @@ -395,7 +405,7 @@ class DRMLIB_LOCAL MeteringSessionManager::Impl { Json::Value json_license; - Clock::time_point min_polling_deadline = sync_license_timepoint + current_license_duration; /* we can try polling until this deadline */ + Clock::time_point min_polling_deadline = sync_license_timepoint + current_license_duration - std::chrono::milliseconds(200); /* we can try polling until this deadline */ unsigned int retry_index = 0; Clock::time_point start_of_retry = Clock::now(); while(1) { /* Retry WS request */ @@ -523,7 +533,7 @@ class DRMLIB_LOCAL MeteringSessionManager::Impl { void auto_start_session() { // Detect if session was previously stopped - if(!DO_WITH_LOCK(isLicense_no_lock())) + if(!DO_WITH_LOCK(isSession_no_lock())) start_session(); else resume_session(); @@ -533,12 +543,14 @@ class DRMLIB_LOCAL MeteringSessionManager::Impl { if(sessionStarted) Throw(DRMBadArg, "Error : session already started"); - Json::Value json_req; - Info("Starting metering session..."); - getMeteringHead(json_req); - getMeteringStart(json_req); + if( last_start_session_json_req.isNull() ) { + Info("Starting metering session..."); + getMeteringHead(last_start_session_json_req); + getMeteringStart(last_start_session_json_req); + } - Json::Value json_license = getMeteringWSClient().getLicense(json_req); + Json::Value json_license = getMeteringWSClient().getLicense(last_start_session_json_req); + last_start_session_json_req = Json::Value(); setLicense(json_license); sessionID = json_license["metering"]["sessionId"].asString(); @@ -560,13 +572,16 @@ class DRMLIB_LOCAL MeteringSessionManager::Impl { Info("Stopping metering session..."); thread_stop(); - Json::Value json_req; - Debug("Get last metering data from session on DRM controller"); - getMeteringHead(json_req); - getMeteringStop(json_req); - json_req["sessionId"] = sessionID; - getMeteringWSClient().getLicense(json_req); - clearLicense(); + if( last_stop_session_json_req.isNull() ) { + Debug("Get last metering data from session on DRM controller"); + getMeteringHead(last_stop_session_json_req); + getMeteringStop(last_stop_session_json_req); + clearLicense(); + last_stop_session_json_req["sessionId"] = sessionID; + } + Json::Value json_license = getMeteringWSClient().getLicense(last_stop_session_json_req); + last_stop_session_json_req = Json::Value(); + sessionID = json_license["metering"]["sessionId"].asString(); Info("Stopped metering session with sessionId ", sessionID, " and uploaded last metering data"); sessionStarted = false; @@ -578,15 +593,18 @@ class DRMLIB_LOCAL MeteringSessionManager::Impl { if(DO_WITH_LOCK(isReadyForNewLicense_no_lock())) { Json::Value json_req; - getMeteringHead(json_req); - try{ - getMeteringWait(1, json_req); - } catch(const DrmControllerLibrary::DrmControllerTimeOutException& e) { - Unreachable(); //we have checked isReadyForNewLicense, should not block + if(last_resume_session_json_req.isNull()) { + getMeteringHead(last_resume_session_json_req); + try{ + getMeteringWait(1, last_resume_session_json_req); + } catch(const DrmControllerLibrary::DrmControllerTimeOutException& e) { + Unreachable(); //we have checked isReadyForNewLicense, should not block + } } - json_req["sessionId"] = sessionID; - Json::Value json_license = getMeteringWSClient().getLicense(json_req); + last_resume_session_json_req["sessionId"] = sessionID; + Json::Value json_license = getMeteringWSClient().getLicense(last_resume_session_json_req); + last_resume_session_json_req = Json::Value(); setLicense(json_license); sessionID = json_license["metering"]["sessionId"].asString();