# C++ SDK Configuration and Usage

C++ SDK allows implementing licensing in two ways:

* using the License and LicenseManager classes;
* using the LicenseHandler class.

LicenseHandler encapsulates License and LicenseManager functionality. By default, it is exceptions-free, but you can enable exceptions. It's up to you whether to use LicenseManager and License directly or use this class.

LicenseHandler is also useful for Unreal Engine clients because it is free of memory access violation problems due to runtime conflicts with UE.

This article has code samples for both approaches. In the other ones, we will demonstrate SDK usage only with LicenseManager and License. LicenseHandler class has methods corresponding to License/LicenseManager functionality.

See also our [Error Handling](https://docs.licensespring.com/sdks/tutorials/getting-started/c++/broken-reference) tutorial.

### Configuration

To initialize the SDK you will need to fill in your application name and version, product code, and LicenseSpring authentication credentials:

* API and shared key, or
* OAuth client\_id and client\_secret.

{% hint style="info" %}
OAuth support was added in v7.35.0 of the SDK. See [**OAuth Authorization**](https://docs.licensespring.com/sdks/tutorials/getting-started/c++/broken-reference) on how to set up OAuth.
{% endhint %}

{% hint style="info" %}
Refer to our [**hardware ID generation page**](https://docs.licensespring.com/sdks/tutorials/getting-started/c++/broken-reference) on how to pick the best hardware ID generation algorithm for your program.
{% endhint %}

All credentials can be found can be found on your LicenseSpring account under `Settings->Keys`:

![API and Shared Key Location](https://content.gitbook.com/content/gLzurdfXUuKr9IziZWLz/blobs/OAynXVJIIqzNh8znV1MY/E8UhHrENKuF%20RQw50B4nn_screenshotkeys.png)

Your product code is located in your product list under Configure Products:

![Product CoProduct Code Location Location](https://content.gitbook.com/content/gLzurdfXUuKr9IziZWLz/blobs/lzemWZgLetf0zIM1qWsi/LGlB_ERjJM0YF_0EHtMt2_screenshotproduct.png)

Please, keep in mind that the product code field is case-sensitive.

When you have the necessary values, create the configuration.

```cpp
std::string AppName = "My LicenseSpring Application";
std::string AppVersion = "1.0.0";
// use in case of standard authentication
std::string ApiKey = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
std::string SharedKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
// use in case of OAuth authentication
std::string ClientId = "xxxxxx-xxxxx-yyy";
std::string ClientSecret = "ssssssssssssssssssssssssssssss";

std::string ProductCode = "XX";

auto configuration = LicenseSpring::Configuration::Create( ApiKey, SharedKey, ProductCode, AppName, AppVersion );

// or
// setting CryptoProvider key is necessary when using OAuth
// configuration->getCryptoProvider->setKey("password for license encryption key generation");
// auto configuration = LicenseSpring::Configuration::CreateOAuth( ClientId, ClientSecret, ProductCode, AppName, AppVersion );
```

Now you can initialize LicenseManager or LicenseHandler using this configuration object.

{% tabs %}
{% tab title="LicenseManager" %}

```cpp
auto licenseManager = LicenseManager::create( configuration );
```

{% endtab %}

{% tab title="LicenseHandler" %}

```cpp
auto& licenseHandler = LicenseHandler::instance();
licenseHandler.reconfigure( configuration );
```

{% endtab %}
{% endtabs %}

### License Activation

The license keys are located in Licenses section:

![License Key Location](https://content.gitbook.com/content/gLzurdfXUuKr9IziZWLz/blobs/jDlWxxO3i60lbTl9vnno/xUdyMD7vPArcHnhvLlQxY_screenshotlicense.png)

To implement user-based licensing please refer to: [User-Based Licensing](https://docs.licensespring.com/sdks/tutorials/getting-started/c++/broken-reference).

To activate a license, create a LicenseID using the given key and call activation method.

{% tabs %}
{% tab title="LicenseManager" %}

```cpp
auto licenseId = LicenseID::fromKey( "XXXX-XXXX-XXXX-XXXX" );
auto license = licenseManager->activateLicense( licenseId );
```

{% endtab %}

{% tab title="LicenseHandler" %}

```cpp
auto& licenseHandler = LicenseHandler::instance();
auto licenseId = LicenseID::fromKey( "XXXX-XXXX-XXXX-XXXX" );
licenseHandler.activateLicense( licenseId );
```

{% endtab %}
{% endtabs %}

The process of activating a license refers to binding a device to a license. On the LicenseSpring platform, activating the license increments the total activations counter within the license.

{% hint style="info" %}
SSOException with the message "Customer account code is not set." can occur due to incorrect use of the activateLicense function. This function has two overloads. For a regular license activation, it takes only LicenseID. The overload that takes strings is used for SSO. For more information, see [Single Sign-On](https://docs.licensespring.com/sdks/tutorials/getting-started/c++/broken-reference).
{% endhint %}

### Local License

The local license is a copy of the license information that is saved on the end user's local computer. Users who have not activated the license on their end before will not have a local license. By default, the local license is stored: `%USERPROFILE%\AppData\Local\LicenseSpring\”Product Code”\License.key`.

See [Local License File](https://docs.licensespring.com/sdks/tutorials/getting-started/c++/broken-reference) for more information.

If a device already has a license, and you try to activate another license on that device, for the same product, that newly activated license will override the existing license, deleting it from the device. This will be on the developer to make sure that they check if a license exists on the device before a new activation:

{% tabs %}
{% tab title="LicenseManager" %}

```cpp
auto license = licenseManager->getCurrentLicense();
if( license == nullptr )
    //activate a new license
```

{% endtab %}

{% tab title="LicenseHandler" %}

```cpp
auto& licenseHandler = LicenseHandler::instance();
if( !licenseHandler.isLicenseExists() )
    //activate a new license
```

{% endtab %}
{% endtabs %}

### License Check

It is recommended to perform a local license check at application start to confirm that the local license file belongs to the current device and has not been transferred.

It is also useful to check whether the local license file has been tampered with and whether the local license is still valid.

An additional check verifies the license signature returned by the License API on license activation or check. If the license was tampered with, the local check will throw an exception if the `verifySignature` parameter is set to `true`.

{% hint style="danger" %}
If the license was activated with C++ SDK v7.32.0 or earlier, local check with signature verification will throw an exception because the local license state doesn't contain the signature signed by the LicenseSpring backend.

In that case, users must first either do an offline license update, or an online license check. This only needs to be done once.
{% endhint %}

{% tabs %}
{% tab title="License" %}

```cpp
bool verifySignature = false; // also false by default
license->localCheck( verifySignature );
//throws exceptions in case of errors
```

{% endtab %}

{% tab title="LicenseHandler" %}

```cpp
auto& licenseHandler = LicenseHandler::instance();
licenseHandler.checkLicenseLocal();
if( licenseHandler.wasError() )
    //handle errors
    LSErrorCode error = lh.getLastError();
else
    //license check is successful
```

{% endtab %}
{% endtabs %}

The local check can produce the following errors:

| Exception                         | Error code                                                                                            | Reason                                                     |
| --------------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| `LicenseStateException`           | <p><code>eLicenseDisabled</code><br><code>eLicenseInactive</code><br><code>eLicenseExpired</code></p> | License is in invalid state (disabled, epired or inactive) |
| `ProductMismatchException`        | `eProductMismatchError`                                                                               | License does not belong to configured product              |
| `DeviceNotLicensedException`      | `eDeviceError`                                                                                        | License does not belong to current device                  |
| `ClockTamperedException`          | `eClockTamperedError`                                                                                 | Detected cheating with system clock                        |
| `FloatingTimeoutExpiredException` | `eFloatingTimeoutExpired`                                                                             | Timeout for floating license has expired                   |
| `VMIsNotAllowedException`         | `eVMNotAllowed`                                                                                       | VM was detected while VM check is turned on                |
| `SignatureMismatchException`      | `eSignatureMismatchError`                                                                             | Local license signature has been tampered with.            |

Online license check refreshes the local license with the data from LicenseSpring backend:

{% tabs %}
{% tab title="License" %}

```cpp
license->check();
//throws exceptions in case of errors
```

{% endtab %}

{% tab title="LicenseHandler" %}

```cpp
auto& licenseHandler = LicenseHandler::instance();
licenseHandler.checkLicense();
if( licenseHandler.wasError() )
    //handle errors
    LSErrorCode error = lh.getLastError();
else
    //license check is successful
```

{% endtab %}
{% endtabs %}

The online check can produce the following errors:

| Exception                                                                                                              | Error code                                                                                                | Reason                                                                                                                                                                |
| ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `LicenseStateException`                                                                                                | <p><code>eLicenseDisabled</code><br><code>eLicenseInactive</code><br><code>eLicenseExpired</code></p>     | License is disabled, was reset or expired                                                                                                                             |
| <p><code>DeviceNotLicensedException</code><br><code>DeviceBlacklistedException</code></p>                              | <p><code>eDeviceError</code><br><code>eDeviceBlacklisted</code></p>                                       | License does not belong to current device or the device was blacklisted                                                                                               |
| <p><code>NoInternetException</code><br><code>NetworkTimeoutException</code><br><code>LicenseServerException</code></p> | <p><code>eNoInternetError</code><br><code>eNetworkTimeoutError</code><br><code>eServerError</code></p>    | Connection-related errors: if there's no Internet or an internal server error occured.                                                                                |
| `MaxFloatingReachedException`                                                                                          | `eMaxFloatingReached`                                                                                     | There are no free floating slots for license                                                                                                                          |
| `UnknownLicenseSpringException`                                                                                        | `eUnknownError`                                                                                           | Unknown error. Contact support in this case                                                                                                                           |
| `OAuthException`                                                                                                       | <p><code>eUnauthorizedClient</code><br><code>eOAuthRequired</code><br><code>eOAuthTokenExpired</code></p> | <p>Invalid client credentials.<br>License requires OAuth authentication.<br>OAuth token is expired. This shouldn't happen as the SDK keeps track of its lifetime.</p> |

This method also returns the most recent InstallationFile available for the license which can be useful for managing software updates.

For more information about managing software updates, see [Handling Product Versions](https://docs.licensespring.com/sdks/tutorials/getting-started/c++/broken-reference).

You can also check for active, valid, enabled, and expired licenses using `isActive`, `isValid`, `isEnabled`, and `isExpired` methods respectively.

Note that an active license does not necessarily mean a license is valid. A valid license means the license is active, enabled, and not expired. An active license means that the license is bound to a device, but may also be disabled or expired.

### Full Code Sample

Below you can find a code sample that initializes the SDK, retrieves a local license or activates a new one, and performs the necessary checks.

{% tabs %}
{% tab title="LicenseManager" %}

```cpp
std::string AppName = "My LicenseSpring Application";
std::string AppVersion = "1.0.0";
// use in case of standard authentication
std::string ApiKey = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
std::string SharedKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
// use in calse of OAuth authentication
std::string ClientId = "xxxxxx-xxxxx-yyy";
std::string ClientSecret = "ssssssssssssssssssssssssssssss";

std::string ProductCode = "XX";

auto configuration = LicenseSpring::Configuration::Create( ApiKey, SharedKey, ProductCode, AppName, AppVersion );

// or
// setting CryptoProvider key is necessary when using OAuth
// configuration->getCryptoProvider->setKey("password for license encryption key generation");
// auto configuration = LicenseSpring::Configuration::CreateOAuth( ClientId, ClientSecret, ProductCode, AppName, AppVersion );

try
{
    auto licenseManager = LicenseManager::create( configuration );
    auto license = licenseManager->getCurrentLicense();
    if( license == nullptr )
    {
        auto licenseId = LicenseID::fromKey( "XXXX-XXXX-XXXX-XXXX" );
        license = licenseManager->activateLicense( licenseId );
    }
    license->localCheck();
    license->check();
}
catch( const LicenseSpringException& ex )
{
    std::cout << "LicenseSpring exception encountered: " << ex.what();
}
```

{% endtab %}

{% tab title="LicenseHandler" %}

```cpp
std::string AppName = "My LicenseSpring Application";
std::string AppVersion = "1.0.0";
std::string ApiKey = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
std::string SharedKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
std::string ProductCode = "XX";

auto configuration = LicenseSpring::Configuration::Create( ApiKey, SharedKey, ProductCode, AppName, AppVersion );

auto& licenseHandler = LicenseHandler::instance();
licenseHandler.reconfigure( configuration );
if( !licenseHandler.isLicenseExists() )
{
    auto licenseId = LicenseID::fromKey( "XXXX-XXXX-XXXX-XXXX" );
    licenseHandler.activateLicense( licenseId );
    if( licenseHandler.wasError() )
        std::cout << "LicenseSpring error encountered: " << licenseHandler.getLastErrorMsg();
}

licenseHandler.checkLicenseLocal();
if( licenseHandler.wasError() )
    std::cout << "LicenseSpring error encountered: " << licenseHandler.getLastErrorMsg();

licenseHandler.checkLicense();
if( licenseHandler.wasError() )
    std::cout << "LicenseSpring error encountered: " << licenseHandler.getLastErrorMsg();
```

{% endtab %}
{% endtabs %}

### License Deactivation

Deactivating a license unbinds the device from the license, and decrements the number of total activations. Depending on the license transfer policy, this usually means that the license is freed up to be activated onto a new device. Deactivating is done using the following method:

{% tabs %}
{% tab title="License" %}

```cpp
if( license->deactivate() )
    std::cout << "License deactivated successfully.";
```

{% endtab %}

{% tab title="LicenseHandler" %}

```cpp
auto& licenseHandler = LicenseHandler::instance();
if( licenseHandler.deactivateLicense() )
    std::cout << "License deactivated successfully.";
```

{% endtab %}
{% endtabs %}

The `License::deactivate()` method allows to specify whether you want to remove the local license file after the deactivation. Set the `removeLocalData` parameter to `true` if you want the local files to be removed.
