UNPKG

@iotize/tap

Version:

IoTize Device client for Javascript

1,128 lines (1,120 loc) 107 kB
import { CodeError, isCodeError } from '@iotize/common/error'; import { FirmwareState } from '@iotize/tap/service/impl/firmware'; import { hexStringToBuffer, asciiStringToByteBuffer } from '@iotize/common/byte-converter'; import { StepOperations } from '@iotize/common/task-manager'; import { deepCopy, sleep } from '@iotize/common/utility'; import { SpecialFeature, AppPathType, TapError } from '@iotize/tap'; import { DEFAULT_SCRAM_SALT_GENERATOR, ScramAuth, hashLoginPassword } from '@iotize/tap/auth'; import { TapRequestFrame, ResultCode } from '@iotize/tap/client/api'; import { TapStreamWriter, NumberConverter } from '@iotize/tap/client/impl'; import { variableDataTypeToByteSize, getConverterFromVariableType } from '@iotize/tap/data'; import { CloudPlatform, LowPowerOptimizationLevel, TargetProtocol, HostProtocol, NfcConnectionPriority, WifiKeyVisibility, WifiMode, WifiProtocol, WifiSSIDVisibility, VariableType, converters as converters$1, FirmwareState as FirmwareState$1 } from '@iotize/tap/service/all'; import { VariableMetaConfigConverter } from '@iotize/tap/service/impl/variable'; import { TapConfigJsonSchema, CommonTypeJsonSchema, TapTypeJsonSchema } from '@iotize/tap/config/schema/v1'; import Ajv from 'ajv'; import { converters } from '@iotize/tap/service/core'; import { SerialSettings, TargetCanProtocolConfiguration } from '@iotize/tap/service/impl/target'; /** * TODO move to TapConfiguratorError */ class ConfigKeyNotSupportedByFirmwareVersion extends Error { constructor(configKey, firmwareVersion, constraint) { super(`Configuration key "${configKey}" is not available for you firmware version (${firmwareVersion}). \ ${constraint.minApiVersion ? `Minimal firmware version: ${constraint.minApiVersion}.` : ''}\ ${constraint.maxApiVersion ? `Maximal firmware version: ${constraint.maxApiVersion}.` : ''}`); this.configKey = configKey; this.firmwareVersion = firmwareVersion; this.constraint = constraint; } } class TapConfiguratorError extends CodeError { constructor(code, msg, cause) { super(msg, code); this.cause = cause; } static internalError(msg, cause) { return new TapConfiguratorError(TapConfiguratorError.Code.InternalError, msg, cause); } static unexpectedFirmwareState(state) { return new TapConfiguratorError(TapConfiguratorError.Code.UnexpectedFirmwareState, `Firmware state is not in expected mode. It should be ${FirmwareState.NORMAL} or ${FirmwareState.LEGACY} but found ${state}`); } static invalidConfiguration(message) { return new TapConfiguratorError(TapConfiguratorError.Code.InvalidSchema, message); } } (function (TapConfiguratorError) { let Code; (function (Code) { Code["UnexpectedFirmwareState"] = "TapConfiguratorErrorUnexpectedFirmwareState"; Code["InvalidSchema"] = "TapConfiguratorErrorIvalidSchema"; Code["InternalError"] = "TapConfiguratorErrorInternalError"; })(Code = TapConfiguratorError.Code || (TapConfiguratorError.Code = {})); class InvalidSchemaError extends TapConfiguratorError { constructor(validate) { super(Code.InvalidSchema, `\ Invalid Tap configuration file: ${InvalidSchemaError.ajvErrorsToString(validate.errors)}`); this.validate = validate; this.errors = this.validate.errors || []; } static ajvErrorsToString(errors) { // console.log('errors', JSON.stringify(errors, undefined, 4)); return errors ? errors .map((error) => { let message; const instancePath = error.instancePath || error.dataPath; switch (error.keyword) { case 'additionalProperties': const params = error.params; message = `${instancePath} should not have additional property "${params .additionalProperty}"`; break; default: message = `${instancePath} ${error.message} (keyword: ${error.keyword})`; } return `\t- ${message}`; }) .join('\n') : 'Unknown errors'; } } TapConfiguratorError.InvalidSchemaError = InvalidSchemaError; })(TapConfiguratorError || (TapConfiguratorError = {})); const ANONYMOUS_USER = { username: 'anonymous', password: '', id: 0, lifeTime: 30, }; const ADMIN_USER = { username: 'admin', password: 'admin', id: 0xffff, lifeTime: 30, }; const SUPERVISOR_USER = { username: 'supervisor', password: 'supervisor', id: 0xfffe, lifeTime: 30, }; const SERIAL_SERVER_USER = { username: 'SerialServer', password: 'SerialServer', lifeTime: 4000, id: 0xfffc, }; const SPECIAL_USERS = [ ANONYMOUS_USER, ADMIN_USER, SUPERVISOR_USER, ]; const DEFAULT_HASH_ITERATION_COUNT = 5000; function getProfileIdFromConfig(profile) { const specialUserInfo = SPECIAL_USERS.find((v) => profile.username === v.username); if (specialUserInfo) { return specialUserInfo.id; } const profileId = profile['id']; // TODO check if (profileId === undefined) { throw TapConfiguratorError.invalidConfiguration(`Profile id is required for ${profile['username']}`); } return profileId; } /** * * @param versionToCheck * @param versionToCompareTo * @returns * 1 if versionToCheck > versionToCompareTo * 0 if versionToCheck == versionToCompareTo * -1 if versionToCheck < versionToCompareTo */ function compareVersionNumbers(versionToCheck, versionToCompareTo) { var v1parts = versionToCheck.split('.').map((v) => { const asInt = parseInt(v); if (isNaN(asInt)) { throw new Error(`Value "${versionToCheck}" is not a valid string version`); } return asInt; }); var v2parts = versionToCompareTo.split('.').map((v) => { const asInt = parseInt(v); if (isNaN(asInt)) { throw new Error(`Value "${versionToCompareTo}" is not a valid string version`); } return asInt; }); for (var i = 0; i < v1parts.length; ++i) { if (v2parts.length === i) { return 1; } if (v1parts[i] === v2parts[i]) { continue; } if (v1parts[i] > v2parts[i]) { return 1; } return -1; } if (v1parts.length != v2parts.length) { return -1; } return 0; } /** * Return true if versionToCheck >= versionToCompareTo * @param versionToCheck version to check * @param versionToCompareTo version to compare to * @returns versionToCheck >= versionToCompareTo */ function isTapFirmwareVersionGreaterThanOrEqual(versionToCheck, versionToCompareTo) { return compareVersionNumbers(versionToCheck, versionToCompareTo) >= 0; } /** * Return true if versionToCheck <= versionToCompareTo * @param versionToCheck * @param versionToCompareTo * @returns versionToCheck <= versionToCompareTo */ function isTapFirmwareVersionLessThanOrEqual(versionToCheck, versionToCompareTo) { return compareVersionNumbers(versionToCheck, versionToCompareTo) <= 0; } function enumKeyToEnumValue(value, enumMapping) { return toEnum(value, enumMapping); } function enumKeysToEnumValues(values, enumMapping) { return values.map((value) => enumKeyToEnumValue(value, enumMapping)); } /** * Convert */ function toEnum(value, enumMapping) { if (!value) { throw new Error(`Missing first attribute for toEnum. ${Object.keys(enumMapping).join(', ')}`); } if (typeof value !== 'string') { throw new Error(`Enum key must be a string. Given: ${JSON.stringify(value)}. ${Object.keys(enumMapping).join(', ')}`); } value = value.toUpperCase(); if (!(value in enumMapping)) { throw new Error(`Missing enum value "${value}". Available: ${Object.keys(enumMapping).join(', ')}`); } return enumMapping[value]; } function enumToString(value, mapping) { if (!(value in mapping)) { throw new Error(`Missing mapping for ${value}. Available: ${Object.keys(mapping).join(', ')}`); } return mapping[value]; } function isSpecialProfileUsername(username) { return SPECIAL_USERS.filter((v) => username === v.username).length > 0; } function isSpecialProfileId(id) { return SPECIAL_USERS.filter((v) => id === v.id).length > 0; } function configValueToBytes(input) { if (input instanceof Uint8Array) { return input; } else if (typeof input === 'string') { if (input.substring(0, 2).toLowerCase() === '0x') { return hexStringToBuffer(input); } else { return asciiStringToByteBuffer(input); } } else { return Uint8Array.from(input); } } function getByAttr(filterKey, v, data) { let array; if (Array.isArray(data)) { array = data; } else { array = Object.keys(data).map((key) => data[key]); } return array.filter((value) => value[filterKey] == v)[0] || undefined; } const TSTYPE_CLASS = { Uint8Array, }; const ɵ0$4 = (schema) => { const classObject = TSTYPE_CLASS[schema]; return function (data) { return !classObject || data instanceof classObject; }; }; const tsTypeKeyword = { keyword: 'tsType', compile: ɵ0$4, }; const ipv4Format = /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/; function createAjvInstance(schemas) { schemas = schemas || [ TapConfigJsonSchema, CommonTypeJsonSchema, TapTypeJsonSchema, ]; const ajv8Options = { schemas, strict: false, strictSchema: false, }; const ajv = new Ajv(ajv8Options); ajv.addKeyword(tsTypeKeyword.keyword, tsTypeKeyword); ajv.addFormat('ipv4', ipv4Format); return ajv; } function getJsonSchemaValidator(schemas) { const ajv = createAjvInstance(); const schemaId = 'http://iotize.com/schemas/v1/tap-config.json'; // TODO config must match schema api file value const validator = ajv.getSchema(schemaId); if (!validator) { throw new Error(`Cannot create JSON validator function from schema ${schemaId}`); } return validator; } // export function checkErrors(config: Object) { // const validator = getJsonSchemaValidator(); // validator(config); // return validator.errors; // } /** * Validate schema. Throw error if schema is not valid * @throws @{link TapConfiguratorError} * @param config the tap config object * @param schemas optial schema used for validation. If not provided, default one will be used * * @returns validator function */ function validateTapConfiguratorConfig(config, schemas) { const validator = getJsonSchemaValidator(schemas); const valid = validator(config); if (!valid) { throw new TapConfiguratorError.InvalidSchemaError(validator); } return validator; } function parseTapConfiguratorConfig(input) { let config; try { config = JSON.parse(input); } catch (err) { throw new Error(`Cannot parse Tap configurator config content. ${err.message}`); } validateTapConfiguratorConfig(config); return config; } /** * Generated file. Do not edit */ const ɵ0$3 = (context) => { return context.service.interface.putApplicationDataCall(configValueToBytes(context.value)); }, ɵ1$2 = (context) => { return context.service.interface.putAppNameCall(context.value); }, ɵ2$2 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.113')) { return new ConfigKeyNotSupportedByFirmwareVersion('application.productCode', context.firmwareVersion, { minApiVersion: '1.113', maxApiVersion: undefined, }); } } return context.service.interface.putProductCodeCall(context.value); }, ɵ3$1 = (context) => { return context.service.interface.putUniversalLinkCall(context.value); }, ɵ4$1 = (context) => { return context.service.interface.putAppPathCall(context.value); }, ɵ5$1 = (context) => { return context.service.cloud.putDataLogPublishTopicCall(context.value); }, ɵ6$1 = (context) => { return context.service.cloud.putDataLogSubscribeTopicCall(context.value); }, ɵ7$1 = (context) => { return context.service.cloud.putDataLogUploadPeriodCall(context.value); }, ɵ8$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionLessThanOrEqual(context.firmwareVersion, '1.103')) { return new ConfigKeyNotSupportedByFirmwareVersion('cloud.mqtt.brokerPort', context.firmwareVersion, { minApiVersion: undefined, maxApiVersion: '1.103', }); } } return context.service.cloud.putMqttBrokerPortCall(context.value); }, ɵ9$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionLessThanOrEqual(context.firmwareVersion, '1.103')) { return new ConfigKeyNotSupportedByFirmwareVersion('cloud.mqtt.clientId', context.firmwareVersion, { minApiVersion: undefined, maxApiVersion: '1.103', }); } } return context.service.cloud.putMqttClientIdCall(context.value); }, ɵ10$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionLessThanOrEqual(context.firmwareVersion, '1.103')) { return new ConfigKeyNotSupportedByFirmwareVersion('cloud.mqtt.password', context.firmwareVersion, { minApiVersion: undefined, maxApiVersion: '1.103', }); } } return context.service.cloud.putMqttPasswordCall(context.value); }, ɵ11$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionLessThanOrEqual(context.firmwareVersion, '1.103')) { return new ConfigKeyNotSupportedByFirmwareVersion('cloud.mqtt.username', context.firmwareVersion, { minApiVersion: undefined, maxApiVersion: '1.103', }); } } return context.service.cloud.putMqttUsernameCall(context.value); }, ɵ12$1 = (context) => { return context.service.cloud.putPlatformCall(enumKeyToEnumValue(context.value, CloudPlatform)); }, ɵ13$1 = (context) => { return context.service.interface.putConfigFormatVersionCall(context.value); }, ɵ14$1 = (context) => { return context.service.bundle.createCall(context.param); }, ɵ15$1 = (context) => { return context.service.bundle.putAclCall(context.param, context.value); }, ɵ16$1 = (context) => { return context.service.bundle.putDataLogCryptoGroupIdCall(context.param, context.value); }, ɵ17$1 = (context) => { return context.service.bundle.putDataLogPeriodCall(context.param, context.value); }, ɵ18$1 = (context) => { return context.service.bundle.putNameCall(context.param, context.value); }, ɵ19$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.23')) { return new ConfigKeyNotSupportedByFirmwareVersion('data.features[].bundleId', context.firmwareVersion, { minApiVersion: '1.23', maxApiVersion: undefined, }); } } return context.service.interface.setSpecialFeatureProfileCall(context.param, context.value); }, ɵ20$1 = (context) => { return context.service.group.createCall(context.param); }, ɵ21$1 = (context) => { return context.service.group.putAliasCall(context.param, context.value); }, ɵ22$1 = (context) => { return context.service.group.changePasswordKeyCall(context.param, configValueToBytes(context.value)); }, ɵ23$1 = (context) => { return context.service.group.putSessionLifetimeCall(context.param, context.value); }, ɵ24$1 = (context) => { return context.service.group.changePasswordCall(context.param, context.value); }, ɵ25$1 = (context) => { return context.service.group.putNameCall(context.param, context.value); }, ɵ26$1 = (context) => { return context.service.variable.createCall(context.param, context.value); }, ɵ27$1 = (context) => { return context.service.variable.putVariableAddressCall(context.param, context.value); }, ɵ28$1 = (context) => { return context.service.variable.putBundleIdCall(context.param, context.value); }, ɵ29$1 = (context) => { return context.service.variable.putNumberOfElementsCall(context.param, context.value); }, ɵ30$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.73')) { return new ConfigKeyNotSupportedByFirmwareVersion('data.variables[].meta', context.firmwareVersion, { minApiVersion: '1.73', maxApiVersion: undefined, }); } } return context.service.variable.putMetaCall(context.param, context.value); }, ɵ31$1 = (context) => { return context.service.variable.putModbusVariableAddressCall(context.param, context.value); }, ɵ32$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.73')) { return new ConfigKeyNotSupportedByFirmwareVersion('data.variables[].rawMeta', context.firmwareVersion, { minApiVersion: '1.73', maxApiVersion: undefined, }); } } return context.service.variable.putRawMetaCall(context.param, configValueToBytes(context.value)); }, ɵ33$1 = (context) => { return context.service.variable.putTypeCall(context.param, context.value); }, ɵ34$1 = (context) => { return context.service.variable.setValueCall(context.param, configValueToBytes(context.value)); }, ɵ35$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.90')) { return new ConfigKeyNotSupportedByFirmwareVersion('jvm.code', context.firmwareVersion, { minApiVersion: '1.90', maxApiVersion: undefined, }); } } return context.service.jvm.appendCodeAppendCalls(configValueToBytes(context.value)); }, ɵ36$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.90')) { return new ConfigKeyNotSupportedByFirmwareVersion('jvm.codeSize', context.firmwareVersion, { minApiVersion: '1.90', maxApiVersion: undefined, }); } } return context.service.jvm.putCodeSizeCall(context.value); }, ɵ37$1 = (context) => { return context.service.jvm.putProfileIdCall(context.value); }, ɵ38$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '2.7')) { return new ConfigKeyNotSupportedByFirmwareVersion('ports.ethernet.gatewayIp', context.firmwareVersion, { minApiVersion: '2.7', maxApiVersion: undefined, }); } } return context.service.ethernet.putGatewayIpCall(context.value); }, ɵ39$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '2.7')) { return new ConfigKeyNotSupportedByFirmwareVersion('ports.ethernet.ip', context.firmwareVersion, { minApiVersion: '2.7', maxApiVersion: undefined, }); } } return context.service.ethernet.putIpCall(context.value); }, ɵ40$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '2.7')) { return new ConfigKeyNotSupportedByFirmwareVersion('ports.ethernet.ipMask', context.firmwareVersion, { minApiVersion: '2.7', maxApiVersion: undefined, }); } } return context.service.ethernet.putIpMaskCall(context.value); }, ɵ41$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '2.11')) { return new ConfigKeyNotSupportedByFirmwareVersion('tap.autoRebootTimeout', context.firmwareVersion, { minApiVersion: '2.11', maxApiVersion: undefined, }); } } return context.service.interface.putAutoRebootTimeoutCall(context.value); }, ɵ42$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.86')) { return new ConfigKeyNotSupportedByFirmwareVersion('tap.certificate.privateKey', context.firmwareVersion, { minApiVersion: '1.86', maxApiVersion: undefined, }); } } return context.service.interface.putCertificatePrivateKeyAppendCalls(configValueToBytes(context.value)); }, ɵ43$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.86')) { return new ConfigKeyNotSupportedByFirmwareVersion('tap.certificate.publicKey', context.firmwareVersion, { minApiVersion: '1.86', maxApiVersion: undefined, }); } } return context.service.interface.putCertificatePublicKeyAppendCalls(configValueToBytes(context.value)); }, ɵ44$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.86')) { return new ConfigKeyNotSupportedByFirmwareVersion('tap.certificate.rootKey', context.firmwareVersion, { minApiVersion: '1.86', maxApiVersion: undefined, }); } } return context.service.interface.putCertificateRootKeyAppendCalls(configValueToBytes(context.value)); }, ɵ45$1 = (context) => { return context.service.interface.putMaxLowPowerTimeCall(context.value); }, ɵ46$1 = (context) => { return context.service.interface.putPowerOptimisationLevelCall(enumKeyToEnumValue(context.value, LowPowerOptimizationLevel)); }, ɵ47$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '2.15')) { return new ConfigKeyNotSupportedByFirmwareVersion('tap.powerOptimizationOptions', context.firmwareVersion, { minApiVersion: '2.15', maxApiVersion: undefined, }); } } return context.service.interface.putPowerOptimisationOptionsCall(context.value); }, ɵ48$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.11')) { return new ConfigKeyNotSupportedByFirmwareVersion('tap.scram.hashIteration', context.firmwareVersion, { minApiVersion: '1.11', maxApiVersion: undefined, }); } } return context.service.scram.putHashIterationCall(context.value); }, ɵ49$1 = (context) => { return context.service.interface.putSecurityOptionsCall(context.value); }, ɵ50$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.107')) { return new ConfigKeyNotSupportedByFirmwareVersion('tap.time.ntpServer', context.firmwareVersion, { minApiVersion: '1.107', maxApiVersion: undefined, }); } } return context.service.time.putNtpServerCall(context.value); }, ɵ51$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.107')) { return new ConfigKeyNotSupportedByFirmwareVersion('tap.time.zone', context.firmwareVersion, { minApiVersion: '1.107', maxApiVersion: undefined, }); } } return context.service.time.putTimeZoneCall(context.value); }, ɵ52$1 = (context) => { return context.service.target.putFirmwareVersionCall(context.value); }, ɵ53$1 = (context) => { return context.service.target.putModbusDefaultSlaveAddressCall(context.value); }, ɵ54$1 = (context) => { return context.service.target.putProtocolCall(enumKeyToEnumValue(context.value, TargetProtocol)); }, ɵ55$1 = (context) => { return context.service.interface.putConfigVersionCall(context.value); }, ɵ56$1 = (context) => { return context.service.interface.putAuthorizedHostProtocolCall(enumKeysToEnumValues(context.value, HostProtocol)); }, ɵ57$1 = (context) => { return context.service.interface.putHostInactivityPeriodCall(context.value); }, ɵ58$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '2.13')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.options.network', context.firmwareVersion, { minApiVersion: '2.13', maxApiVersion: undefined, }); } } return context.service.interface.putNetworkOptionsCall(context.value); }, ɵ59$1 = (context) => { return context.service.interface.putPairingOptionsCall(context.value); }, ɵ60$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '2.7')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.ethernet.dnsIp', context.firmwareVersion, { minApiVersion: '2.7', maxApiVersion: undefined, }); } } return context.service.ethernet.putDnsIpCall(context.value); }, ɵ61$1 = (context) => { return context.service.lora.putConfigCall(context.value); }, ɵ62$1 = (context) => { return context.service.lora.putIdsCall(configValueToBytes(context.value)); }, ɵ63$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '2.11')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.lte.applicationData', context.firmwareVersion, { minApiVersion: '2.11', maxApiVersion: undefined, }); } } return context.service.lte.putApplicationDataCall(configValueToBytes(context.value)); }, ɵ64$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.86')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.mqtt.brokerCertificate', context.firmwareVersion, { minApiVersion: '1.86', maxApiVersion: undefined, }); } } return context.service.mqtt.putBrokerCertificateAppendCalls(configValueToBytes(context.value)); }, ɵ65$1 = (context) => { return context.service.mqtt.putBrokerHostnameCall(context.value); }, ɵ66$1 = (context) => { return context.service.mqtt.putBrokerPortCall(context.value); }, ɵ67$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.86')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.mqtt.clientId', context.firmwareVersion, { minApiVersion: '1.86', maxApiVersion: undefined, }); } } return context.service.mqtt.putClientIdCall(context.value); }, ɵ68$1 = (context) => { return context.service.mqtt.putPasswordCall(context.value); }, ɵ69$1 = (context) => { return context.service.mqtt.putRelayNetKeyCall(context.value); }, ɵ70$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.86')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.mqtt.requestTopic', context.firmwareVersion, { minApiVersion: '1.86', maxApiVersion: undefined, }); } } return context.service.mqtt.putRequestTopicCall(context.value); }, ɵ71$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.107')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.mqtt.responseTopic', context.firmwareVersion, { minApiVersion: '1.107', maxApiVersion: undefined, }); } } return context.service.mqtt.putResponseTopicCall(context.value); }, ɵ72$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.86')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.mqtt.topicPrefix', context.firmwareVersion, { minApiVersion: '1.86', maxApiVersion: undefined, }); } } return context.service.mqtt.putTopicPrefixCall(context.value); }, ɵ73$1 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.86')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.mqtt.username', context.firmwareVersion, { minApiVersion: '1.86', maxApiVersion: undefined, }); } } return context.service.mqtt.putUsernameCall(context.value); }, ɵ74 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.55')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.nfc.autoLogProfileId', context.firmwareVersion, { minApiVersion: '1.55', maxApiVersion: undefined, }); } } return context.service.interface.putNfcAutologProfileIdCall(context.value); }, ɵ75 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.85')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.nfc.connectionPriority', context.firmwareVersion, { minApiVersion: '1.85', maxApiVersion: undefined, }); } } return context.service.interface.putNfcConnectionPriorityCall(enumKeyToEnumValue(context.value, NfcConnectionPriority)); }, ɵ76 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.88')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.wifi.countryCode', context.firmwareVersion, { minApiVersion: '1.88', maxApiVersion: undefined, }); } } return context.service.wifi.putCountryCodeCall(context.value); }, ɵ77 = (context) => { return context.service.wifi.putDnsIpCall(context.value); }, ɵ78 = (context) => { return context.service.wifi.putGatewayIpCall(context.value); }, ɵ79 = (context) => { return context.service.wifi.putIpCall(context.value); }, ɵ80 = (context) => { return context.service.wifi.putKeyCall(context.value); }, ɵ81 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.88')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.wifi.keyVisibility', context.firmwareVersion, { minApiVersion: '1.88', maxApiVersion: undefined, }); } } return context.service.wifi.putKeyVisibilityCall(enumKeyToEnumValue(context.value, WifiKeyVisibility)); }, ɵ82 = (context) => { return context.service.wifi.putIpMaskCall(context.value); }, ɵ83 = (context) => { return context.service.wifi.putModeCall(enumKeyToEnumValue(context.value, WifiMode)); }, ɵ84 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '2.13')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.wifi.networkMode', context.firmwareVersion, { minApiVersion: '2.13', maxApiVersion: undefined, }); } } return context.service.wifi.putNetworkModeCall(enumKeyToEnumValue(context.value, WifiMode)); }, ɵ85 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.88')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.wifi.protocol', context.firmwareVersion, { minApiVersion: '1.88', maxApiVersion: undefined, }); } } return context.service.wifi.putProtocolCall(enumKeysToEnumValues(context.value, WifiProtocol)); }, ɵ86 = (context) => { return context.service.wifi.putSSIDCall(context.value); }, ɵ87 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.88')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.wifi.ssidVisibility', context.firmwareVersion, { minApiVersion: '1.88', maxApiVersion: undefined, }); } } return context.service.wifi.putSSIDVisibilityCall(enumKeyToEnumValue(context.value, WifiSSIDVisibility)); }, ɵ88 = (context) => { if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '1.88')) { return new ConfigKeyNotSupportedByFirmwareVersion('wireless.protocols.wifi.txPower', context.firmwareVersion, { minApiVersion: '1.88', maxApiVersion: undefined, }); } } return context.service.wifi.putTxPowerCall(context.value); }; const WRITE_CONFIGURATOR_CONFIG$1 = { 'application.data': ɵ0$3, 'application.name': ɵ1$2, 'application.productCode': ɵ2$2, 'application.universalLink': ɵ3$1, 'application.uri': ɵ4$1, 'cloud.dataLog.mqttPublishTopic': ɵ5$1, 'cloud.dataLog.mqttSubscribeTopic': ɵ6$1, 'cloud.dataLog.uploadPeriod': ɵ7$1, 'cloud.mqtt.brokerPort': ɵ8$1, 'cloud.mqtt.clientId': ɵ9$1, 'cloud.mqtt.password': ɵ10$1, 'cloud.mqtt.username': ɵ11$1, 'cloud.platform': ɵ12$1, configFormatVersion: ɵ13$1, 'data.bundles[]': ɵ14$1, 'data.bundles[].acl[].$': ɵ15$1, 'data.bundles[].dataLog.cryptoGroupId': ɵ16$1, 'data.bundles[].dataLog.period': ɵ17$1, 'data.bundles[].name': ɵ18$1, 'data.features[].bundleId': ɵ19$1, 'data.profiles[]': ɵ20$1, 'data.profiles[].alias': ɵ21$1, 'data.profiles[].key': ɵ22$1, 'data.profiles[].lifeTime': ɵ23$1, 'data.profiles[].password': ɵ24$1, 'data.profiles[].username': ɵ25$1, 'data.variables[]': ɵ26$1, 'data.variables[].address': ɵ27$1, 'data.variables[].bundleId': ɵ28$1, 'data.variables[].length': ɵ29$1, 'data.variables[].meta': ɵ30$1, 'data.variables[].modbusAddress': ɵ31$1, 'data.variables[].rawMeta': ɵ32$1, 'data.variables[].type': ɵ33$1, 'data.variables[].value': ɵ34$1, 'jvm.code': ɵ35$1, 'jvm.codeSize': ɵ36$1, 'jvm.profileId': ɵ37$1, 'ports.ethernet.gatewayIp': ɵ38$1, 'ports.ethernet.ip': ɵ39$1, 'ports.ethernet.ipMask': ɵ40$1, 'tap.autoRebootTimeout': ɵ41$1, 'tap.certificate.privateKey': ɵ42$1, 'tap.certificate.publicKey': ɵ43$1, 'tap.certificate.rootKey': ɵ44$1, 'tap.maxLowPowerTime': ɵ45$1, 'tap.powerOptimization': ɵ46$1, 'tap.powerOptimizationOptions': ɵ47$1, 'tap.scram.hashIteration': ɵ48$1, 'tap.security': ɵ49$1, 'tap.time.ntpServer': ɵ50$1, 'tap.time.zone': ɵ51$1, 'target.firmwareVersion': ɵ52$1, 'target.modbusDefaultSlaveAddress': ɵ53$1, 'target.protocol.type': ɵ54$1, version: ɵ55$1, 'wireless.options.authorizedProtocols': ɵ56$1, 'wireless.options.inactivityTimeout': ɵ57$1, 'wireless.options.network': ɵ58$1, 'wireless.options.pairing': ɵ59$1, 'wireless.protocols.ethernet.dnsIp': ɵ60$1, 'wireless.protocols.lora.config': ɵ61$1, 'wireless.protocols.lora.ids': ɵ62$1, 'wireless.protocols.lte.applicationData': ɵ63$1, 'wireless.protocols.mqtt.brokerCertificate': ɵ64$1, 'wireless.protocols.mqtt.brokerHostname': ɵ65$1, 'wireless.protocols.mqtt.brokerPort': ɵ66$1, 'wireless.protocols.mqtt.clientId': ɵ67$1, 'wireless.protocols.mqtt.password': ɵ68$1, 'wireless.protocols.mqtt.relayNetKey': ɵ69$1, 'wireless.protocols.mqtt.requestTopic': ɵ70$1, 'wireless.protocols.mqtt.responseTopic': ɵ71$1, 'wireless.protocols.mqtt.topicPrefix': ɵ72$1, 'wireless.protocols.mqtt.username': ɵ73$1, 'wireless.protocols.nfc.autoLogProfileId': ɵ74, 'wireless.protocols.nfc.connectionPriority': ɵ75, 'wireless.protocols.wifi.countryCode': ɵ76, 'wireless.protocols.wifi.dnsIp': ɵ77, 'wireless.protocols.wifi.gatewayIp': ɵ78, 'wireless.protocols.wifi.ip': ɵ79, 'wireless.protocols.wifi.key': ɵ80, 'wireless.protocols.wifi.keyVisibility': ɵ81, 'wireless.protocols.wifi.mask': ɵ82, 'wireless.protocols.wifi.mode': ɵ83, 'wireless.protocols.wifi.networkMode': ɵ84, 'wireless.protocols.wifi.protocol': ɵ85, 'wireless.protocols.wifi.ssid': ɵ86, 'wireless.protocols.wifi.ssidVisibility': ɵ87, 'wireless.protocols.wifi.txPower': ɵ88, }; const ɵ0$2 = (context) => { var _a, _b, _c, _d, _e; const protocolType = ((_b = (_a = context.config) === null || _a === void 0 ? void 0 : _a.target) === null || _b === void 0 ? void 0 : _b.type) === 'MCU' ? (_e = (_d = (_c = context.config) === null || _c === void 0 ? void 0 : _c.target) === null || _d === void 0 ? void 0 : _d.protocol) === null || _e === void 0 ? void 0 : _e.type : 'MODBUS'; switch (protocolType) { case 'NONE': case 'SWD': // case 'JTAG': case 'GPIO': case 'CUSTOM': return TapConfiguratorError.invalidConfiguration(`Target protocol "${protocolType}" does not accept any additional configuration`); case 'S3P': return context.service.target.putS3PConfigurationCall(context.value); case 'MODBUS_TCP': if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '2.6')) { return new ConfigKeyNotSupportedByFirmwareVersion('target.protocol.config', context.firmwareVersion, { minApiVersion: '2.6', maxApiVersion: undefined, }); } } return context.service.target.putModbusTcpConfigurationCall(context.value); case 'MODBUS': case 'SERIAL': const tapnpassConfigJson = context.value; const tapnpassConfigApi = tapnpassConfigJsonToApi(tapnpassConfigJson); return context.service.target.putSerialModbusConfigurationCall(tapnpassConfigApi); case 'CAN': if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '2.6')) { return new ConfigKeyNotSupportedByFirmwareVersion('target.protocol.config', context.firmwareVersion, { minApiVersion: '2.6', maxApiVersion: undefined, }); } } const canConfigJson = context.value; const canConfigApi = canConfigJsonToApi(canConfigJson); return context.service.target.putCanConfigurationCall(canConfigApi); default: return TapConfiguratorError.invalidConfiguration(`Target protocol "${protocolType}" is not supported by this version of the configurator`); } }, ɵ1$1 = (context) => { var _a; if (context.firmwareVersion) { if (!isTapFirmwareVersionGreaterThanOrEqual(context.firmwareVersion, '2.6')) { return new ConfigKeyNotSupportedByFirmwareVersion('slaveServer', context.firmwareVersion, { minApiVersion: '2.6', maxApiVersion: undefined, }); } } const protocolType = (_a = context.value) === null || _a === void 0 ? void 0 : _a.type; switch (protocolType) { case undefined: throw new Error(`Undefined property`); case 'SPI': return context.service.slaveServer.putSpiProtocolConfigurationCall(); case 'MODBUS_TCP': const modbusTcpConfig = context.value .config; return context.service.slaveServer.putModbusTcpProtocolConfigurationCall(modbusTcpConfig); case 'MODBUS_RTU': const tapnpassConfigJson = context.value .config; const tapnpassConfigApi = tapnpassConfigJsonToApi(tapnpassConfigJson); return context.service.slaveServer.putModbusRtuProtocolConfigurationCall(tapnpassConfigApi); case 'CAN': const canConfigJson = context.value.config; const canConfigApi = canConfigJsonToApi(canConfigJson); return context.service.slaveServer.putCanProtocolConfigurationCall(canConfigApi); default: return TapConfiguratorError.invalidConfiguration(`Slave server protocol "${protocolType}" is not supported by this version of the configurator`); } }, ɵ2$1 = (context) => { const loadJvmCodeCalls = WRITE_CONFIGURATOR_CONFIG$1['jvm.code'](context); if (loadJvmCodeCalls instanceof Error) { return loadJvmCodeCalls; } else { const clearCodeCall = context.service.jvm.clearCodeCall(); clearCodeCall.body = Uint8Array.from([0]); return [clearCodeCall, ...loadJvmCodeCalls]; } }; const WRITE_CONFIGURATOR_CUSTOM_CONFIG = { 'target.protocol.config': ɵ0$2, slaveServer: ɵ1$1, 'jvm.code': ɵ2$1, }; const WRITE_CONFIGURATOR_CONFIG = Object.assign(Object.assign({}, WRITE_CONFIGURATOR_CONFIG$1), WRITE_CONFIGURATOR_CUSTOM_CONFIG); const DEFAULT_MODBUS_CONFIG = { offsetFirstRegister: false, slave: 0, }; const DEFAULT_USB_CONFIG = { aliases: [], }; function tapnpassConfigJsonToApi(jsonConfig) { return { modbus: jsonConfig.modbus || DEFAULT_MODBUS_CONFIG, serial: { baudRate: jsonConfig.serial.baudRate, bitParity: toEnum(jsonConfig.serial.bitParity, SerialSettings.BitParity), dataBits: toEnum(jsonConfig.serial.dataBits, SerialSettings.DataBits), handshakeDelimiter: toEnum(jsonConfig.serial.handshakeDelimiter, SerialSettings.HandshakeDelimiter), hardwareFlowControl: toEnum(jsonConfig.serial.hardwareFlowControl, SerialSettings.HardwareFlowControl), identification: jsonConfig.serial.identification, ledStatus: jsonConfig.serial.ledStatus, physicalPort: toEnum(jsonConfig.serial.physicalPort, SerialSettings.PhysicalPort), stopBits: toEnum(jsonConfig.serial.stopBits, SerialSettings.StopBits), timeout: jsonConfig.serial.timeout, }, usb: jsonConfig.usb || DEFAULT_USB_CONFIG, }; } function canConfigJsonToApi(canConfigJson) { const canConfigApi = { code: converters.uint32.decode(configValueToBytes(canConfigJson.code)), mask: converters.uint32.decode(configValueToBytes(canConfigJson.mask)), filter: toEnum(canConfigJson.filter, TargetCanProtocolConfiguration.Filter), frequency: canConfigJson.frequency, mode: toEnum(canConfigJson.mode, TargetCanProtocolConfiguration.Mode), }; return canConfigApi; } var __awaiter$1 = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; const variableMetaConverter = new VariableMetaConfigConverter(); const IGNORE_KEYS = ['version', 'tap.security']; const USER_CREATE_KEY = 'data.profiles[]'; const CREATE_VARIABLE_CONFIG_KEY = 'data.variables[]'; function isHexString(input) { if (typeof input !== 'string') { return false; } return !!input.match(/^(0x)?([a-fA-F0-9])*$/); } function tapConfigToServiceCalls(config, options) { var _a; function addCalls(calls, newCalls) { if (Array.isArray(newCalls)) { calls.push(...newCalls); } else { calls.push(newCalls); } } function createWriteConfigCall(key, callContext) { if (!(key in WRITE_CONFIGURATOR_CONFIG)) { throw new Error(`Invalid API configuration. Configuration key "${key}" does not exist`); } const callFactory = WRITE_CONFIGURATOR_CONFIG[key]; return callFactory(callContext); } function baseConfigObjectToCalls(entry, configKey, pathParameter) { const calls = []; if (entry === undefined) { return calls; } else if (Array.isArray(entry)) { const newConfigKey = configKey + '[]'; for (const itemValue of entry) { if (itemValue.id || itemValue.id === 0) { pathParameter = itemValue.id; } if (pathParameter === undefined) { throw new Error(`Item must have an id for key "${newConfigKey}`); // TODO we need to know parent profile ? } // If there is a create instance function if (newConfigKey in WRITE_CONFIGURATOR_CONFIG) { if (newConfigKey === USER_CREATE_KEY && isSpecialProfileId(pathParameter)) { // If it's a special user profile, we dont need the create call } else { // throw new Error(`Missing create method for config key "${newConfigKey}"`); let createBody; if (newConfigKey === CREATE_VARIABLE_CONFIG_KEY) { if (itemValue.metaDataLength) { createBody = itemValue.metaDataLength; } else if (itemValue.rawMeta) { createBody = itemValue.rawMeta.length; } } const createCallParam = { firmwareVersion: options.firmwareVersion, service: options.service, value: createBody, param: pathParameter, }; if (createBody === undefined) { delete createCallParam.value; } try { const newCalls = WRITE_CONFIGURATOR_CONFIG[newConfigKey](createCallParam); addCalls(calls, newCalls); } catch (err) { const error = err; throw TapConfiguratorError.internalError(`Cannot generate configuration requests from configuration key ${newConfigKey}. Cause: ${error.message}`, error); } } } calls.push(...baseConfigObjectToCalls(itemValue, newConfigKey, pathParameter)); } } else { if (`${configKey}.$` in WRITE_CONFIGURATOR_CONFIG) { try { addCalls(calls, createWriteConfigCall(`${configKey}.$`, { firmwareVersion: options.firmwareVersion, service: options.service, value: entry,