Move a Released Product to Host ID V2
From 1.10.0 the KEYZY C++ Client Library uses Host ID scheme V2 by default. A product released on an earlier version uses V1, and rebuilding it with the new default changes every device’s host id: all existing activations would have to re-activate. From 1.10.2, migrateHostIdV1toV2() moves those users to V2 on their own devices, without user input.
Who needs this: only a product released on a library version before 1.10.0. A new product keeps the default, V2, and needs nothing on this page.
Prerequisites
- The KEYZY C++ Client Library 1.10.2 or later
- A product released with
HostIdScheme::V1that uses semi-online or online activation
What the Call Does
For a product released with HostIdScheme::V1 (every product released on an SDK before 1.10.0). Construct the activator with HostIdScheme::V2 (the default) and call migrateHostIdV1toV2() on every start, in place of the first step of your start-up flow (validateOffline() for semi-online, validateOnline() for online). On the next start, every user with a working V1 license moves to V2 without noticing anything. A user whose V1 license has run out on the device (not started for a while) moves too, as long as the serial is still stored. A user whose device ID has already changed under V1 moves to V2 with the serial stored on the device; if their device limit is full, an old activation has to be removed first, as today.
The parameter says how your product activates its licenses: HostIdMigrationMode::SemiOnline (activateSemiOnline(), also server-side trials from registerTrial()) or HostIdMigrationMode::Online (activateOnline() and validateOnline()).
Call it once per process, before any other license call.
Offline Activation
Offline activation (activateOffline()) is not supported. Keep a product sold with offline licenses on HostIdScheme::V1, or send each user a new license file made for their V2 host id.
Return Values
The call returns two values:
status(LicenseStatus): can the user use the product now. Handle it as in your start-up flow.VALIDdoes not mean the move has finished.state(HostIdMigrationState): what happened to the move.
state | Meaning | What to do |
|---|---|---|
AlreadyV2 | No V1 license to move and the V2 license is valid. | Follow status. |
Moved | The license moved from V1 to V2 on this call. | Follow status. |
NothingToMove | No working license to move. The result of the normal start-up step, or the reason it could not run, is in status. | Follow status (for example, show the serial form on CLIENT_SERIAL_DOES_NOT_EXIST). |
NotNeededOnPlatform | No move is needed on this platform (Linux: V2 is identical to V1); the normal start-up step ran. | Follow status. |
StayedOnV1 | The move did not finish this time; the license stays on V1 for this start. Whether it can be used is in status. | For the rest of this run, use an activator constructed with HostIdScheme::V1 (example below). The next start tries again. |
Interrupted | The move started but did not finish, and there is no license on the device for now. | Follow status: it says why. Once the cause is gone (for example the connection is back, or the subscription is renewed), the next start finishes the move with the stored serial; the user enters nothing. |
WrongHostIdScheme | The activator was constructed with HostIdScheme::V1; nothing was done and status is INVALID. | An integration error: construct it with HostIdScheme::V2. |
Semi-Online Start-Up Flow
Semi-online start-up flow with the move:
// 1. Create the activator and validator (once, at startup), on HostIdScheme::V2 (the default)
auto pActivator = std::make_unique<Keyzy::KeyzyLicenseActivator>(productData);
auto pValidator = pActivator->getLicenseValidator();
// 2. In place of validateOffline(): moves a V1 license to V2 when there is one
Keyzy::HostIdMigrationResult result =
pActivator->migrateHostIdV1toV2(Keyzy::HostIdMigrationMode::SemiOnline);
Keyzy::LicenseStatus status = result.status;
if (result.state == Keyzy::HostIdMigrationState::StayedOnV1)
{
// The move did not finish this time: use V1 for the rest of this run, the next launch tries again
productData._hostIdScheme = Keyzy::HostIdScheme::V1;
pActivator = std::make_unique<Keyzy::KeyzyLicenseActivator>(productData);
pValidator = pActivator->getLicenseValidator();
status = pValidator->validateOffline(); // also fills the license details
}
if (status == Keyzy::LicenseStatus::VALID)
{
// License is valid. Renew silently: refreshes if online, ignored if offline
pActivator->activateSemiOnline();
}
else
{
// 3. The call has already tried the stored serial:
// ask for a serial only when there is no usable one on the device
if (status == Keyzy::LicenseStatus::CLIENT_SERIAL_DOES_NOT_EXIST ||
status == Keyzy::LicenseStatus::SERIAL_INVALID ||
status == Keyzy::LicenseStatus::ACTIVATION_DEACTIVATED)
{
std::string serial = getSerialFromUser(); // your UI code
status = pActivator->activateSemiOnline(serial);
}
if (status != Keyzy::LicenseStatus::VALID)
{
// 4. Show a message that fits the status
}
}
Online Start-Up Flow
Online start-up flow with the move:
// 1. Create the activator and validator (once, at startup), on HostIdScheme::V2 (the default)
auto pActivator = std::make_unique<Keyzy::KeyzyLicenseActivator>(productData);
auto pValidator = pActivator->getLicenseValidator();
// 2. In place of validateOnline(): moves a V1 activation to V2 when there is one
Keyzy::HostIdMigrationResult result =
pActivator->migrateHostIdV1toV2(Keyzy::HostIdMigrationMode::Online);
Keyzy::LicenseStatus status = result.status;
if (result.state == Keyzy::HostIdMigrationState::StayedOnV1)
{
// The move did not finish this time: use V1 for the rest of this run, the next launch tries again
productData._hostIdScheme = Keyzy::HostIdScheme::V1;
pActivator = std::make_unique<Keyzy::KeyzyLicenseActivator>(productData);
pValidator = pActivator->getLicenseValidator();
status = pValidator->validateOnline(); // also fills the license details
}
if (status != Keyzy::LicenseStatus::VALID)
{
// 3. Ask for a serial only when there is no usable one on the device
if (status == Keyzy::LicenseStatus::INVALID ||
status == Keyzy::LicenseStatus::CLIENT_SERIAL_DOES_NOT_EXIST ||
status == Keyzy::LicenseStatus::SERIAL_INVALID ||
status == Keyzy::LicenseStatus::ACTIVATION_DEACTIVATED)
{
std::string serial = getSerialFromUser(); // your UI code
status = pActivator->activateOnline(serial);
}
if (status != Keyzy::LicenseStatus::VALID)
{
// 4. Show a message that fits the status
}
}
How Long to Keep the Call
If your product was released with HostIdScheme::V1, keep the call in every release until a KEYZY SDK release marks it deprecated: a user who has not started your product since still needs it on their next start.
Next Steps
- Semi-Online Activation: the start-up flow without the move
- Online Activation: the start-up flow without the move
- C++ License Status Codes: every
LicenseStatusand what it means