///
import { Buffer } from 'buffer';
import PythonStruct, { DataType } from 'python-struct';
import { Parameter } from './parameter';
import { HardwareDescription } from './hardware-description';
import { SmmOd } from './smm-od';
import { SmmBinaryHeader } from './types';
/**
* Extends the base `Parameter` interface to include SMM-specific details.
*
* @extends {Parameter}
*/
export interface SmmParameter extends Parameter {
deviceSerialNumber: string;
}
/**
* Object index of the Detected Module Ident List, `0xF050`, from the Modular Device Profile (ETG.5001).
* A device declares it when it can carry a detachable module and report which one is attached.
*/
export declare const OD_INDEX_DETECTED_MODULE_IDENT_LIST = 61520;
/**
* Whether a device's object dictionary declares the Modular Device Profile.
*
* Only a product that can carry a detachable module implements it. Among the SOMANET devices, that is
* Circulo Safe Motion and ACTILINK-JD, which declare `0xF000`, `0xF030` and `0xF050`; a Node, a Circulo
* and an Integro declare none of them. A Circulo NG declares none either — integrated FSoE safety is a
* different thing from a module discovered over the profile, and its only F-range object is `0xF980`,
* the FSoE slave address.
*
* This says the device *can* carry a module, not that one is attached: a Circulo Safe Motion with no
* module fitted still declares `0xF050`, and reads 0 from `0xF050:02`. Presence is the right test for
* whether the SMM path applies at all, which is what the Setup Wizard and the SMM parameter space are.
*/
export declare function declaresModularDeviceProfile(parameterIndexes: readonly number[]): boolean;
/**
* Whether a device keeps its safety configuration on a detachable safety module, which is what decides
* whether the SMM parameter space and the SMM Setup Wizard apply to it at all.
*
* Answered from the device's own object dictionary where possible. The dictionary is the standard
* interface — CoE objects defined by ETG, readable from any compliant device — and it states this
* outright, where a product ID only lets us infer it from a table we maintain by hand. It also needs no
* client release to classify a product that does not exist yet.
*
* `productId` is the fallback for a dictionary that has not been read. An empty or absent index list
* means "not read", never "declares nothing": on a device whose dictionary could not be read, answering
* `false` would silently take the safety configuration path away from a product that has one.
*/
export declare function supportsSafetyModule(deviceParameterIndexes?: readonly number[] | null, productId?: number | string | HardwareDescription | null): boolean;
/**
* Resolves the appropriate SMM OD (Object Dictionary) version based on the provided parameter structure version.
*
* @param {number} [parameterStructureVersion=0x0041] - The version of the parameter structure to determine which SMM OD to return.
* @returns {SmmOd} - Returns `smmOdV1` if the version is less than `0x0203`, otherwise returns `smmOdV2`.
*/
export declare function resolveSmmOd(parameterStructureVersion?: number): SmmOd;
/**
* Builds a bitmask for the safety parameters of a given group in the SMM parameter set.
*
* The bitmask is an array of bytes where each bit represents whether a specific safety
* parameter belongs to the specified group. The group index determines which group's
* parameters are marked as `1` in the bitmask, and others are marked as `0`.
*
* @param groupIndex - The index of the group for which to build the bitmask. The index corresponds
* to the position of the group in the safety parameters.
* @param parameterStructureVersion - The version of the parameter struct to use. Defaults to `0x0041`.
*
* @returns A `Uint8Array` representing the bitmask for the specified group. Each byte contains 8 bits,
* where each bit corresponds to a safety parameter.
*
* @throws If the `groupIndex` is out of range or if the parameter structure is not valid for the given version.
*/
export declare function buildSmmParametersGroupBitmask(groupIndex: number, parameterStructureVersion?: number): Uint8Array;
/**
* Builds the structure format strings for each group of parameters based on the given struct version.
*
* This function maps parameters in the `smmOd` object to their respective safety groups, processes
* them, and converts their types to structure format characters (e.g., `<` for little-endian).
* The function supports different versions of the parameter struct format, defaulting to version `0x0041`.
*
* @param parameterStructureVersion - The version of the parameter struct to use. Defaults to `0x0041`.
*
* @returns An array of structure format strings for each group of parameters.
*/
export declare function buildSmmParametersGroupPackFormats(parameterStructureVersion?: number): string[];
/**
* Builds the structure format string for all parameters based on the given struct version.
*
* This function processes the parameters in the `smmOd` object, converting each parameter's type
* to its corresponding structure format character (e.g., `<` for little-endian). It supports different
* versions of the parameter struct format, defaulting to version `0x0041`.
*
* @param parameterStructureVersion - The version of the parameter struct to use. Defaults to `0x0041`.
*
* @returns A structure format string representing all the parameters, starting with a `<` (little-endian).
*/
export declare function buildSmmParametersPackFormat(parameterStructureVersion?: number): string;
/**
* Calculates a CRC-32 checksum using a custom SMM-specific polynomial lookup table.
*
* This CRC implementation is tailored for Safety Motion Module (SMM) data validation,
* ensuring data integrity across packed buffers. It supports an initial CRC seed,
* allowing for chained calculations or non-standard CRC resets.
*
* @param buffer - The input data buffer (`Uint8Array`) for which to calculate the CRC.
* @param initial - The initial CRC value, typically `0xFFFFFFFF` for standard calculations.
*
* @returns The computed CRC-32 checksum as a 32-bit unsigned integer.
*/
export declare function calcSmmCRC32(buffer: Uint8Array, initial: number): number;
/**
* Packs SMM (Safety Motion Module) credentials (username and password) into a fixed-size binary format.
* Each field is padded or truncated to 24 bytes.
*
* @param username - The username to be packed. It will be padded or truncated to 24 bytes.
* @param password - The password to be packed. It will also be padded or truncated to 24 bytes.
*
* @returns A `Buffer` containing the packed username and password.
*
* @throws Error if the username or password contains invalid characters or types.
*/
export declare function packSmmCredentials(username: string, password: string): Buffer;
/**
* Packs the new and old passwords into a fixed-size binary format for SMM (Safety Motion Module) password change operations.
* Each password is padded or truncated to 24 bytes.
*
* @param newPassword - The new password to be packed. It will be padded or truncated to 24 bytes.
* @param oldPassword - The current/old password to be packed. It will be padded or truncated to 24 bytes.
*
* @returns A `Buffer` containing the packed new and old passwords.
*
* @throws Error if either password contains invalid characters or types.
*/
export declare function packSmmChangePassword(newPassword: string, oldPassword: string): Buffer;
/**
* Packs SMM (Safety Motion Module) parameter values into a binary buffer,
* following the specified SMM parameter structure version.
* It computes and appends a CRC32 checksum to ensure data integrity.
*
* @param values - An array of `DataType` values to be packed.
* @param parameterStructureVersion - The version of the parameter struct to use. Defaults to `0x0041`.
*
* @returns An object containing:
* - `buffer`: A `Buffer` with the packed values followed by the CRC32 checksum.
* - `crc`: The computed CRC32 checksum for the packed data.
* - `crcBuffer`: A `Buffer` representing the packed CRC32 checksum.
* - `values`: The original `DataType[]` values.
* - `valuesBuffer`: A `Buffer` containing the packed values (without the CRC).
*
* @throws Error if packing fails due to an invalid structure or value mismatch.
*/
export declare function packSmmParameterValues(values: DataType[], parameterStructureVersion?: number): {
buffer: Buffer;
crc: number;
crcBuffer: Buffer;
values: PythonStruct.DataType[];
valuesBuffer: Buffer;
};
/**
* Unpacks SMM (Safety Motion Module) parameter values from a `Uint8Array` buffer
* according to the specified parameter structure version.
*
* This function decodes the packed buffer back into its original data values,
* using the structure format defined for the given SMM parameter structure version.
*
* @param values - A `Uint8Array` representing the packed parameter values.
* @param parameterStructureVersion - The version of the parameter struct to use. Defaults to `0x0041`.
*
* @returns An array of unpacked values, decoded according to the structure format.
*
* @throws Error if the unpacking fails or the data format is incorrect.
*/
export declare function unpackSmmParameterValues(values: Uint8Array, parameterStructureVersion?: number): PythonStruct.DataType[];
/**
* Packs SMM (Safety Motion Module) parameter values into a buffer for verification,
* including a bitmask and CRC32 checksum to ensure data integrity.
*
* This function prepares data specifically for verification purposes, combining
* parameter values, a group-specific bitmask, and a CRC32 checksum.
*
* @param values - An array of `DataType` representing the parameter values to be packed.
* @param groupIndex - The index of the parameter group, determining the bitmask and packing format.
* @param parameterStructureVersion - The version of the parameter struct to use. Defaults to `0x0041`.
*
* @returns An object containing:
* - `buffer`: A `Uint8Array` combining the bitmask and CRC32 checksum for verification.
* - `crc`: The CRC32 checksum calculated from the packed data and bitmask.
*
* @throws Error if the groupIndex is invalid or packing fails.
*/
export declare function packSmmParameterValuesForVerification(values: DataType[], groupIndex: number, parameterStructureVersion?: number): {
buffer: Uint8Array;
crc: number;
};
/**
* Packs a `Date` object into a binary buffer in a specific format for the SMM (Safety Motion Module).
* The date is serialized into the following fields: year (2 bytes), month (1 byte), day (1 byte),
* hours (1 byte), minutes (1 byte), seconds (1 byte), and a trailing byte (set to 0).
* The packed data can be used for storing or transmitting the date in a structured format compatible with SMM.
*
* @param date - The `Date` object to be packed. It is expected to be in UTC time.
*
* @returns A `Buffer` containing the packed date.
*/
export declare function packSmmDate(date: Date): Buffer;
/**
* Packs a validation report for the SMM (Safety Motion Module), including a CRC, date, and credentials.
* The function takes a content `Uint8Array`, a `Date`, a `username`, and a `password`, and returns an object
* containing the packed report, the CRC, and the credentials used for packing.
*
* The packed report includes the following components:
* - CRC32 checksum of the content.
* - The date packed into a specific format.
* - The credentials (username and password) packed into a specific format.
*
* @param content - The content of the validation report, as a `Uint8Array`.
* @param date - The date of the report to be packed into the format used by SMM.
* @param username - The username associated with the report.
* @param password - The password associated with the report.
*
* @returns An object containing:
* - `buffer`: A `Uint8Array` that includes the packed CRC, date, and credentials.
* - `crc`: The CRC32 checksum of the `content`.
* - `credentials`: The packed username and password.
*/
export declare function packSmmValidationReport(content: Uint8Array, date: Date, username: string, password: string): {
buffer: Uint8Array;
crc: number;
credentials: Buffer;
};
/**
* Packs a CRC (Cyclic Redundancy Check) value into a 4-byte little-endian binary format.
* This is typically used for verifying software updates in the SMM (Safety Motion Module).
*
* @param crc - The CRC value to be packed, represented as a 32-bit unsigned integer.
*
* @returns A `Buffer` containing the packed CRC value in little-endian format.
*
* @throws Error if the provided CRC is not a valid number.
*/
export declare function packSmmSoftwareUpdateCrc(crc: number): Buffer;
/**
* Retrieves the names of all safety parameter groups from the specified parameter structure version.
*
* The function returns a list of unique group names based on the version of the parameter structure.
* It will select `smmOdV1` if the version is lower than `0x0203`, and `smmOdV2` otherwise.
*
* @param parameterStructureVersion - The version of the parameter struct to use. Defaults to `0x0041`.
*
* @returns An array of strings representing the group names in the safety parameters.
*/
export declare function getSmmParametersGroupNames(parameterStructureVersion?: number): string[];
export declare const smmOdV1DefaultValues: any[];
/**
* Interface representing a safety statusword bit.
* A safety statusword bit contains:
* - `name`: A human-readable label for the bit.
* - `abbrv`: An optional abbreviation for the bit.
* - `description`: An optional description of the bit's purpose.
*
* Example:
* ```typescript
* const statusBit: SafetyStatuswordBit = {
* name: 'STO state',
* abbrv: 'STO',
* description: 'Safety Torque Off state'
* };
* ```
*/
export interface SafetyStatuswordBit {
abbrv?: string;
description?: string;
name: string;
}
/**
* Extends the `SafetyStatuswordBit` interface by adding a `value` property.
* This represents a safety status word bit with its corresponding numerical value.
*
* Example:
* ```typescript
* const statusBitValue: SafetyStatuswordBitValue = {
* name: 'STO state',
* abbrv: 'STO',
* description: 'Safety Torque Off state',
* value: 1
* };
* ```
*/
export type SafetyStatuswordBitValue = SafetyStatuswordBit & {
value: number;
};
/**
* Represents a safety statusword bit value, optionally including associated
* SMM parameters.
*
* This type extends the `SafetyStatuswordBitValue` by adding an optional
* `smmParameters` field, which holds an array of `SmmParameter` objects.
* This is useful when a safety statusword bit needs to carry additional
* information about its associated SMM parameters.
*/
export type SafetyStatuswordBitValueWithSmmParameters = SafetyStatuswordBitValue & {
smmParameters?: SmmParameter[];
};
/**
* Represents an array of safety statusword bits, where each element corresponds
* to a specific bit within a 4-byte safety statusword. Each entry includes:
* - the name of the bit,
* - an optional abbreviation, and
* - a brief description of its function or purpose.
*
* @note This structure is specifically used for SMM LW1.
*/
export declare const safetyStatuswordBitsV1: SafetyStatuswordBit[];
/**
* Represents an array of safety statusword bits, where each element corresponds
* to a specific bit within a 4-byte safety statusword. Each entry provides:
* - the bit's name,
* - an optional abbreviation, and
* - a brief description of its function or purpose.
*
* @note This structure is used specifically for SMM LW2.
*/
export declare const safetyStatuswordBitsV2: SafetyStatuswordBit[];
/**
* Represents an array of safety statusword bits, where each element corresponds
* to a specific bit within a 4-byte safety statusword. Each entry includes:
* - the bit's name,
* - an optional abbreviation, and
* - a brief description of its function or purpose.
*
* @note This structure is intended for devices without SMM.
*/
export declare const safetyStatuswordBits: SafetyStatuswordBit[];
/**
* Retrieves the safety statusword bits corresponding to the specified parameter structure version.
*
* Behavior based on `parameterStructureVersion`:
* - If `undefined` or not provided, returns the non-SMM bits (`safetyStatuswordBits`).
* - If less than `0x0203`, returns the LW1 bits (`safetyStatuswordBitsV1`).
* - If `0x0203` or greater, returns the LW2 bits (`safetyStatuswordBitsV2`).
*
* @param parameterStructureVersion - Optional version of the parameter structure used to select
* which set of statusword bits to return.
* @returns An array of `SafetyStatuswordBit` objects for the appropriate non-SMM, LW1, or LW2 set.
*/
export declare function getSafetyStatuswordBits(parameterStructureVersion?: number): SafetyStatuswordBit[];
/**
* Retrieves the names or descriptions of safety statusword bits based on the parameter structure version.
*
* This function returns a 2D array, where each inner array corresponds to a byte in the safety statusword
* and contains the names or descriptions of the bits in that byte. If a bit has a `name`, it is used;
* otherwise, the `description` is returned.
*
* The function uses `getSafetyStatuswordBits` to select the appropriate set of bits:
* - If `parameterStructureVersion` is `undefined` or not provided, returns the non-SMM bits (2 bytes).
* - If less than `0x0203`, returns the LW1 bits (4 bytes).
* - If `0x0203` or greater, returns the LW2 bits (4 bytes).
*
* @param parameterStructureVersion - Optional version of the parameter structure used to select
* which set of statusword bits to use.
* @returns A 2D array of strings, where each inner array contains the names or descriptions of the
* safety statusword bits for that byte. Non-SMM arrays contain only 2 inner arrays (bytes).
*/
export declare function getSafetyStatuswordBitNames(parameterStructureVersion?: number): string[][];
/**
* Converts a grouped map of SMM parameters/values into a flat array suitable for transmission.
*
* During transmission, the Safety-Limited Speed (SLS) groups must be transposed.
* That is, instead of sending the values grouped by SLS1, SLS2, SLS3, and SLS4 in order,
* the values are interleaved such that:
*
* Input:
* - SLS1: [a1, a2, a3, ...]
* - SLS2: [b1, b2, b3, ...]
* - SLS3: [c1, c2, c3, ...]
* - SLS4: [d1, d2, d3, ...]
*
* Output:
* - [a1, b1, c1, d1, a2, b2, c2, d2, a3, b3, c3, d3, ...]
*
* This function:
* - Accepts an object mapping group names to arrays of parameters/values (e.g., `"Safety functions (SOS)"`, `"SLS1"`, etc.).
* - Locates the starting index of the SLS groups by finding the first key that includes `"SLS"`.
* - Extracts and transposes the four SLS groups into `n` arrays of 4 elements each.
* - Inserts the transposed data in place of the original SLS groups.
* - Preserves the order of all other groups before and after the SLS block.
* - Returns the entire structure as a flattened one-dimensional array.
*
* @template T - The type of parameter values contained in each group.
* @param obj - An object whose keys are group names and values are arrays of parameters/values.
* @returns A flat array of all parameter values, reordered for transmission.
*/
export declare function convertGroupedSmmParametersToTransmitData(obj: {
[key: string]: T[];
}): T[];
/**
* Parses the binary header of an SMM firmware image and extracts structured metadata.
*
* This function automatically detects and supports both LW1 and LW2 firmware header versions.
* It unpacks the corresponding fields and returns an object containing detailed header information,
* including hardware/software versions, header length, binary lengths, CRCs, and other custom fields.
*
* Header version detection:
* - LW1: header version < 1.0.0
* - LW2: header version >= 1.0.0
*
* Extracted fields include:
* - `headerVersion`: Encoded numeric header version.
* - `swVersion`: Encoded software version.
* - `lengthBinaryA` / `lengthBinaryB`: Lengths of the binary parts.
* - `crcA` / `crcB`: Checksums of the binary parts (hexadecimal string).
*
* @param smmFirmwareBinary - Raw binary data of the SMM firmware as a `Uint8Array`.
* @returns An `SmmBinaryHeader` object containing the parsed header fields.
*
* @throws If the binary header cannot be parsed or is invalid.
*/
export declare function parseSmmBinaryHeaders(smmFirmwareBinary: Uint8Array): SmmBinaryHeader;
/**
* Encodes a semantic version string or number into a single number using bitwise operations.
* The encoding packs the major version in the high byte and the minor version in the low byte:
*
* encoded = (major << 8) | minor
*
* Examples:
* '1.3' => 0x0103 (259)
* '77.0' => 0x4d00 (19712)
*
* @param semver - Semantic version as a string (e.g., "1.3") or a numeric code.
* @returns Bitwise encoded version as a number. Returns 0 if parsing fails.
*/
export declare function bitwiseEncodeSemverString(semver: string | number): number;
/**
* Decodes a number version into a semantic version string using bitwise operations.
* The decoding unpacks the major version from the high byte and the minor version from the low byte:
*
* decoded = `${(version >> 8) & 0xff}.${(version & 0xff)}`
*
* Examples:
* '259' => 0x0103 (1.3)
* '19712' => 0x4d00 (77.0)
*
* @param version - Bitwise encoded version as a number.
* @returns Semantic version string (e.g., "1.3"). Returns "0.0" if decoding fails.
*/
export declare function bitwiseDecodeNumberVersion(version: number): string;
/**
* Determines whether a target SMM firmware version can be installed on a device,
* based on the device's serial number, its current firmware version, and the target version.
*
* Certain SMM firmware versions have special rules:
* - Versions v77.0, v77.1, and v99.0 are intentionally numbered high to avoid confusion
* with versions 0.77.0, 0.77.1, and 0.99.0.
*
* Rules:
* 1. v99.0 can always be installed.
* - v77.0 can only be installed on encrypted Circulo 7 devices **after** v99.0.
* - v77.1 can only be installed on encrypted Circulo 9 devices **after** v99.0.
* 2. Versions v1.92 - v1.99 are unencrypted and **cannot** be installed on devices
* that already have encrypted firmware.
* 3. Encrypted firmware versions (>= v1.3) can only be installed on devices with
* encrypted firmware, and unencrypted versions can only be installed on devices
* with unencrypted firmware.
*
* @param deviceSerialNumber - The serial number of the device.
* @param deviceSmmFirmwareVersion - The current SMM firmware version of the device
* (number or semver string).
* @param targetSmmFirmwareVersion - The target SMM firmware version to install
* (number or semver string).
* @param force - If `true`, bypasses certain checks and forces the installation.
* @returns `true` if installation is allowed, `false` otherwise.
*/
export declare function checkSmmFirmwareInstallationAllowed(deviceSerialNumber: string, deviceSmmFirmwareVersion: number | string, targetSmmFirmwareVersion: number | string, force?: boolean): boolean;
export declare const smmFirmwareSpecialVersions: number[];
export declare const smmFirmwareUnencryptedVersions: number[];
/**
* Extracts metadata from a given SMM firmware version, including whether it is a special
* version and whether it is encrypted.
*
* Internally, the firmware version is first encoded using `bitwiseEncodeSemverString`.
* The function then:
* 1. Checks if the version is considered "special" (currently v77.0, v77.1, or v99.0).
* 2. Determines if the firmware is encrypted based on version rules:
* - Versions >= 1.3 are encrypted.
* - Exceptions: versions v1.92 through v1.99 are not encrypted.
*
* @param firmwareVersion - The firmware version to analyze, provided as a number or string.
* @returns An object containing:
* - `version`: The encoded firmware version number.
* - `isSpecial`: `true` if the version is in the list of special versions.
* - `isEncrypted`: `true` if the version is considered encrypted according to the rules.
*/
export declare function getInformationFromSmmFirmwareVersion(firmwareVersion: number | string): {
version: number;
isSpecial: boolean;
isEncrypted: boolean;
};