EddystoneService::EddystoneError_t EddystoneService::startBeaconService(void)
{
    if (operationMode == EDDYSTONE_MODE_BEACON) {
        /* Nothing to do, we are already in beacon mode */
        return EDDYSTONE_ERROR_NONE;
    } else if (!urlFramePeriod && !uidFramePeriod && !tlmFramePeriod) {
        /* Nothing to do, the period is 0 for all frames */
        return EDDYSTONE_ERROR_INVALID_ADVERTISING_INTERVAL;
    }

    if (operationMode == EDDYSTONE_MODE_CONFIG) {
        ble.shutdown();
        /* Free unused memory */
        freeConfigCharacteristics();
    }

    if (!ble.hasInitialized()) {
        operationMode = EDDYSTONE_MODE_BEACON;
        ble.init(this, &EddystoneService::bleInitComplete);
        /* Set the device name once more */
        ble.gap().setDeviceName(reinterpret_cast<const uint8_t *>(deviceName));
        return EDDYSTONE_ERROR_NONE;
    }

    operationMode = EDDYSTONE_MODE_BEACON;
    setupBeaconService();

    return EDDYSTONE_ERROR_NONE;
}
EddystoneService::EddystoneError_t EddystoneService::stopCurrentService(void)
{
    switch (operationMode) {
    case EDDYSTONE_MODE_NONE:
        return EDDYSTONE_ERROR_INVALID_STATE;
    case EDDYSTONE_MODE_BEACON:
        ble.shutdown();
        stopBeaconService();
        break;
    case EDDYSTONE_MODE_CONFIG:
        ble.shutdown();
        freeConfigCharacteristics();
        break;
    default:
        /* Some error occurred */
        error("Invalid EddystonService mode");
        break;
    }
    operationMode = EDDYSTONE_MODE_NONE;
    /* Currently on some platforms, the BLE stack handles power management,
     * so we should bring it up again, but not configure it.
     * Once the system sleep without BLE initialised is fixed, remove this
     */
    ble.init(this, &EddystoneService::bleInitComplete);

    return EDDYSTONE_ERROR_NONE;
}
EddystoneService::EddystoneError_t EddystoneService::startBeaconService(void)
{
    if (operationMode == EDDYSTONE_MODE_BEACON) {
        /* Nothing to do, we are already in beacon mode */
        return EDDYSTONE_ERROR_NONE;
    } else if (!urlFramePeriod && !uidFramePeriod && !tlmFramePeriod) {
        /* Nothing to do, the period is 0 for all frames */
        return EDDYSTONE_ERROR_INVALID_BEACON_PERIOD;
    }

    if (operationMode == EDDYSTONE_MODE_CONFIG) {
        ble.shutdown();
        /* Free unused memory */
        freeConfigCharacteristics();
        operationMode = EDDYSTONE_MODE_BEACON;
        ble.init(this, &EddystoneService::bleInitComplete);
        return EDDYSTONE_ERROR_NONE;
    }

    operationMode = EDDYSTONE_MODE_BEACON;
    setupBeaconService();

    return EDDYSTONE_ERROR_NONE;
}