.. include:: definitions.rstinc *************** License systems *************** To use AGX Dynamics, a valid license must be present. .. _license_system: =================== License system =================== A license is acquired via an activation process where a `license id` and a `activation password` are used to perform an online activation that will result in a local license file. The activation request will encode hardware information from the current computer. Hence a license is only valid on the machine where the activation was performed. To help with the activation, a :ref:`License Manager` utility using Python is included with AGX. If PySide and Qt are available locally, the utility provides a GUI. If not, the utility can still be used as a command-line-interface (CLI) tool, see: :ref:`license_manager_cli`. The utility, ``LicenseManager.py`` is located in ``/bin/${ARCH}`` where ``ARCH`` is either ``x64``, ``x86`` or empty - depending on the operating system. .. note:: If you are using Windows, the license manager utility can also be launched via the Start menu. Just press the Windows button and write: :code:`license` and you will find the AGX License Manager. .. _license_manager: ----------------------------------- License Activation and Deactivation ----------------------------------- To activate a license: * Launch the LicenseManager utility * Fill in the license id * Fill in the activation password * Change the output path if needed * Click activate to generate a license file that unlocks AGX Dynamics on the computer/hardware where the activation took place. The license file will be named `agx.lfx` and will be placed in the current users home directory. .. figure:: images/license-manager-1.png License manager running in a Unix operating system. .. figure:: images/license-manager-1-windows.png License manager running in a Windows operating system. After a successful license activation the License Manager will show information for the license including which modules that are enabled and how long the license is valid. .. figure:: images/license-manager-2.png Successful activation of the license. Policies ^^^^^^^^^^ Different license types have different policies. Runtime license ------------------- A Runtime License cannot be deactivated by the user and normally does not have to be validated again online after the first activation. Developer license ------------------- A personal developer license can be deactivated on one machine and activated on another machine i.e transferred. A license can only be activated a limited number of times (10). When the maximum number of activations are reached you need to contact Algoryx Simulation. Developer licenses will also require an online heartbeat that will periodically refresh the license from the server. ----------------------------------- License file location ----------------------------------- By default, AGX will look for a license file named ``agx.lfx``. AGX will try to locate the file automatically via the ``RESOURCE_PATH`` and those directories are initialized from the environment variable ``AGX_FILE_PATH``. This setup is done via the provided ``setup_env`` scripts. AGX could be installed where the current user does not have write access. This could be for example under the ``c:\Program Files`` directory in Windows or under ``/opt/Algoryx/`` in Linux. Therefore, AGX also searches in the current users home-directory for license files. In Windows this is the ``Algoryx\agx`` subdirectory to the current users ``LocalAppData`` folder (``%USERPROFILE%\AppData\Local``). Full path example: ``C:\Users\\AppData\Local\Algoryx\agx\``. In Linux we are adhering to `XDG specification `_ and the directory ``${XDG_CONFIG_HOME}/agx/`` is used as the default storage directory for the license file. If that environment variable is not defined, ``~/.config/`` is used in its place resulting in e.g. ``/home//.config/agx/``. Read more on locating files in :ref:`locating-files`. ------------------------- Runtime deployment ------------------------- This section describes the workflow for providing a Runtime license to an end-user. When deploying an application using AGX Dynamics, activation must be performed on the end-user machine. We do not recommend embedding of any plain text information in your application. We therefore provide a way to encrypt the runtime activation information. Selecting `File > Encrypt runtime...` opens the following dialog: .. image:: images/license-manager-3.png The `build directory` is where your built application resides. The reference file should be a relative path to a static file that is part of your application. Using the button `...` to browse for directory and file will fill in a path relative the build directory. The static file is used during the activation. If the static file is changed, the encrypted runtime has to be regenerated to be usable. When clicking generate, the file `agx.rtlfx` will be saved to the build directory. .. note:: The runtime activation id and activation password are not tested online when generating the encrypted runtime information. Make sure to enter the information correctly. This file can then be used with the ``agx::Runtime::activateEncryptedRuntime( rtflx_path, output_license_path )`` method. Example code: .. code-block:: c++ auto runtime = agx::Runtime::instance(); if ( runtime->isValid() ) { // We have a valid license already. return; } agx::String rtflxPath = .... ; agx::String outputLicensePath = ... ; bool status = runtime->activateEncryptedRuntime( rtflxPath, outputLicensePath ); if ( !status ) { LOGGER_WARNING() << "Could not activate runtime: " << rt->getStatus() << LOGGER_ENDL(); } else { LOGGER_INFO() << "Runtime license: " << outputLicensePath << LOGGER_ENDL(); } ------------------------ Offline Activation ------------------------ Activating AGX and receiving a license is an online process. It is still possible to activate without internet. Part one: * Start the license manager * Fill in license id * Fill in activation password * Select File > Offline activation > Generate activation request... * Fill in a filename for the activation request that will be stored to file. Part two: * Take the generated request file on a USB stick to another computer that has internet access. * Upload the file or its contents to the `manual request activation site `_. * Save the response to a new file on the USB stick. Part three: * Fill in or change the `Output file` field in the License Manager * Select File > Offline activation > Process activation response... * Select the file with the activation response on the USB stick. * A license file should be created locally for futher use. * The license will be tied to the machine that created the offline activation request. .. _license_manager_cli: ------------------------------ Command line interface ------------------------------ If the required python libraries are not installed, including PySide2, the python script LicenseManager.py can be used with a command line interface. Below is the available command line options: .. code-block:: console AGX-2.36.0.0> python bin\x64\LicenseManager.py Error: Could not import PySide2 for Qt GUI. Only command line usage is available: usage: LicenseManager [-h] [--list] [--activate ActivationId ActivationPass OutputLicense] [--deactivate LicenseFile] [--refresh LicenseFile] [--create-activation-request ActivationId ActivationPass OutputFile] [--process-activation-response ReponseFile LicenseFile] Utility to manage licenses for AGX Dynamics optional arguments: -h, --help show this help message and exit --list Search for license files and show license information --activate ActivationId ActivationPass OutputLicense Activate a license and store the license to file --deactivate LicenseFile Deactivate a license and remove file --refresh LicenseFile Perform a manual refresh (online check) of license file --create-activation-request ActivationId ActivationPass OutputFile Generate a license activation request on a disconnected machine. --process-activation-response ReponseFile LicenseFile Process the response from an activation request. To activate a license using the license id and an activation code: .. code-block:: console AGX-2.36.0.0> python bin\x64\LicenseManager.py --activate 25556071 2x3D6Y6C agx.lfx Performing license activation License file: agx.lfx User: John Doe Contact: john.doe@email.com Valid until: 2023-08-07 Modules: AgX AgX-Particles AgX-Cable AgX-CableDamage AgX-Wires AgX-WireLink AgX-Hydraulics AgX-Hydrodynamics AgX-DriveTrain AgX-Tires AgX-Tracks AgX-Terrain AgX-Granular AgX-Simulink AgX-MultiWires Available licenses can be listed using the `--list` option which give the same output as above. ------------------------------ Using AGX in Docker containers ------------------------------ To use AGX, a license is required and this license is acquired via the activation process. As mentioned in an earlier section, the activation request will contain hashed hardware information and the issued license will contain the same identifiers. If AGX is being activated from within a docker container, then container information will be part of the hashed hardware information. One can therefore not move license files between different docker containers since the hardware information will not match. It is also not possible to move a license while from the host machine into the container or vice versa. .. _old_license_system: ================== Old License system ================== This chapter describes the previous license system utilizing agx.lic files. An application built with AGX requires a valid license to run. AGX can either be licensed with a *runtime*-license, or a *developer license*. A runtime-license usually does not have a time limit, but needs to be tied to a network adapter in your computer. License information for a node-locked license is generated through a four step process: 1. Download the license executable available for all platforms `here `_. 2. Next, execute the **RuntimeKeyGenerator** that correspond to your platform. This will generate a number of Hardware ID:s based on the available network adaptors (NIC). 3. Copy the list of the Hardware ID:s and send the following information to support@algoryx.se: - User/company name - Contact/email - HardwareID (select one whole line from the output of RuntimeKeyGenerator) - Url (Personal or your company’s) 4. You will receive a file in email which should be named agx.lic that you should place in the installation directory of AGX Dynamics, or one of the directories specified by the environment variable AGX_FILE_PATH, or with the AGX API call :cpp:`agxIO::Environment::getFilePath(agx::Environment::RESOURCES)` (see :numref:`locating-files`). ------------------------- Sample Windows session ------------------------- Below is output from the RuntimeKeyGenerator.exe: .. image:: images/license_system_1.png -------------------- Sample Linux session -------------------- Output from a typical Linux session: .. code-block:: console johnd@ubuntu:~$ ~/Downloads/RuntimeKeyGenerator-amd64-ubuntu-20.04 Available unique ids: TYPE Hardware ID Comment ------------------------------------------------------------------------------ NIC 36A55A36955110F55967514527F8FFD3 wlo1 One of these Hardware Id value(s) should be used when acquiring a license from Algoryx johnd@ubuntu:~$ -------------------- License deployment -------------------- This section describes the workflow for shipping the license with your end-user application. When deploying an application based on AGX Dynamics, the application must be accompanied by a valid license issued from Algoryx. This license must be a commercial valid runtime license intended for the application as written in the AGX Dynamics license agreement. A Subscription or Developer license must NOT be used for deploying applications to third-party customers. License file ^^^^^^^^^^^^^^ To be able to run an application with AGX Dynamics a valid license is required. This license file is distributed as a text file agx.lic as part of the licensing procedure. During internal development, an OEM/Developer license can/should be used. Usually the license file (agx.lic) is placed into a directory where AGX can locate it (see :numref:`executing_an_agx_application`). A license file contains a number of fields: - User: Name of the user/company/scope - Contact: email address to the licensee - EndDate: Last date when this license is valid - HwKey: List of hardware keys for which this license is valid - Modules: List of AGX modules - Version: For which version of AGX this license is valid - EndOfUpdate: Compared to the build date of AGX Dynamics and specifies the last date for which this license is valid. Runtime license deployment ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ When an application is being deployed, we recommend *that you do not ship the agx.lic on disk*. The main reason for this is to avoid leaking the license file in clear text on the internet. A runtime license usually has the following properties: - EndDate: None - meaning it will be valid forever - EndOfUpdate - If set, it indicates that this is a runtime license with maintenance/update period. - A specified AGX version: indicates which version of AGX is being utilized in the application. For example: “2.25.0.3” .. note:: To reduce the risk of having a license file distributed over the internet, we strongly recommends that an obfuscated (non-readable text) license file is used. .. _obfuscate_license_file: Validate using obfuscated license file ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The process of obfscating a license is where you take the original content of a license file and run it through a tool which generates a long string which represents the license information. To convert a license file into an obfuscated license string you use the `RuntimeKeyGenerator` executable which is available for all platforms at the following `link `_. For version 2.26.0.0 and later it is also available in your AGX installation. To obfuscate a license file you use the command: .. code-block:: console > RuntimeKeyGenerator --obfuscate agx.lic obfuscated.txt The content of obfuscated.txt can now be copy-pasted into your source code and used as an argument to the verifyAndUnlock method of the Runtime class: .. code-block:: const char* licenseStr = “rF3pUP9LX+m0lP6IFoYOMBaLIq8RvYmPFro0vjjdCjP6WK+rFoXVB6k0cMb0kw2iZa9NoA2irw7PgcwAN1YF46P/Wh3623cjEuXZ8/coslPalc5e/p+Z8G/DAPzI+IvwwxXBg4yzPTsE9CVKm9x5wYLoDQysHdALjiz4fdYsYhYGpOpFb3V2h0c4K/7V0PiLXzICK4jskYUGwP6tNfXzbl4L7aYW0PdiBzeo4JhOpTMuXLtI1Lagk+ZbZhmFbvY5ZejLqlQiohJf4zfl6cWAOgkMkKrnh2PZIMR7pnCPbWktGVTdhNPD1wmJEW/+kMs9999Z6EmaKAlHqvienW22um1LNCMZdgykbtZCWvsgH/qUrfUZrl/QXtbyY83xNrlFUj7zKZjTUbE1TxMdVwNBNxVapjJSxgBqbHakl229wvhi3ZPd3zph6DWNucKdM1a0gqHb4XsVxx6buBnJgm+3jV7AW2A59Go5BCdhLQLrmGjWGz7QrUmptMu//yQKsxsE0HT0ZABr/Hu7CCQIxnVE8mEsQ3ZtcwShrpa9mzq/trS5Zl/LYwIN5G1ayKxTy+UXzriMCC4NPRcpN6YuOzcicqf/Ont5ZCcDCGUcGef2HzBH8GDkHH3umUMeVSfpF8Tvk-/qmArdimyxPzy9SGsz2Zd/PZiu2KgMA5Nca38p0j8ulV4tASpXqCpKY8nWH5xCWe4kfO7pWZaJH+s0FghHx9H+fwc71kC2AAeyr8N+PPUnfnNprV3FIuaTdnaj1mCjVqXcVusWmYqF7JhcPffVPE9rkVdNO2qTNkpywwSGwfhyZmmJASByEqq4qp35AavGi3/twWTnWep1kt9ADcZlCG6fewsg5VrHBb7DDgNmcCWVLE1ew5D8bIpq1aukd8tl3hBqaDcgkdATEA369WJlg==”; // Unlock AGX dynamics with the obfuscated license bool isValid = agx::Runtime::instance()->verifyAndUnlock(licenseStr); ---------------------------------------- Validating using license in clear text ---------------------------------------- The second way of validating a license file is to use the text in the license file without obfuscating. **However we do not recommend using this as the license text will be embedded in the binary as text strings.** .. code-block:: c // Read the content of the license file into a string variable std::string licenseFileContent = read_license_file_content(); // Unlock using the text string containing the license file bool valid = agx::Runtime::instance()->unlock( licenseFileContent.c_str() ); if (valid) // We got a valid license file