/// 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; };