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

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:

stateMeaningWhat to do
AlreadyV2No V1 license to move and the V2 license is valid.Follow status.
MovedThe license moved from V1 to V2 on this call.Follow status.
NothingToMoveNo 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).
NotNeededOnPlatformNo move is needed on this platform (Linux: V2 is identical to V1); the normal start-up step ran.Follow status.
StayedOnV1The 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.
InterruptedThe 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.
WrongHostIdSchemeThe 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