"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var MPDU_exports = {};
__export(MPDU_exports, {
  AckLongRangeMPDU: () => AckLongRangeMPDU,
  AckZWaveMPDU: () => AckZWaveMPDU,
  BeamStop: () => BeamStop,
  ExplorerZWaveMPDU: () => ExplorerZWaveMPDU,
  InclusionRequestExplorerZWaveMPDU: () => InclusionRequestExplorerZWaveMPDU,
  LongRangeBeamStart: () => LongRangeBeamStart,
  LongRangeMPDU: () => LongRangeMPDU,
  MulticastZWaveMPDU: () => MulticastZWaveMPDU,
  NormalExplorerZWaveMPDU: () => NormalExplorerZWaveMPDU,
  RoutedZWaveMPDU: () => RoutedZWaveMPDU,
  SearchResultExplorerZWaveMPDU: () => SearchResultExplorerZWaveMPDU,
  SinglecastLongRangeMPDU: () => SinglecastLongRangeMPDU,
  SinglecastZWaveMPDU: () => SinglecastZWaveMPDU,
  ZWaveBeamStart: () => ZWaveBeamStart,
  ZWaveMPDU: () => ZWaveMPDU,
  beamToFrame: () => beamToFrame,
  mpduToFrame: () => mpduToFrame,
  mpduToLongRangeFrame: () => mpduToLongRangeFrame,
  mpduToZWaveFrame: () => mpduToZWaveFrame,
  parseBeamFrame: () => parseBeamFrame,
  parseMPDU: () => parseMPDU,
  znifferDataMessageToCorruptedFrame: () => znifferDataMessageToCorruptedFrame
});
module.exports = __toCommonJS(MPDU_exports);
var import_core = require("@zwave-js/core");
var import_serial = require("@zwave-js/serial");
var import_serialapi = require("@zwave-js/serial/serialapi");
var import_shared = require("@zwave-js/shared");
var import_Types = require("./_Types.js");
function getChannelConfiguration(region) {
  switch (region) {
    case import_core.ZnifferRegion.Japan:
    case import_core.ZnifferRegion.Korea:
      return "3";
    case import_core.ZnifferRegion["USA (Long Range)"]:
    case import_core.ZnifferRegion["USA (Long Range, backup)"]:
    case import_core.ZnifferRegion["USA (Long Range, end device)"]:
      return "4";
    default:
      return "1/2";
  }
}
__name(getChannelConfiguration, "getChannelConfiguration");
function longRangeBeamPowerToDBm(power) {
  return [
    -6,
    -2,
    2,
    6,
    10,
    13,
    16,
    19,
    21,
    23,
    25,
    26,
    27,
    28,
    29,
    30
  ][power];
}
__name(longRangeBeamPowerToDBm, "longRangeBeamPowerToDBm");
function formatNodeId(nodeId) {
  return nodeId.toString().padStart(3, "0");
}
__name(formatNodeId, "formatNodeId");
function formatRoute(source, repeaters, destination, direction, currentHop, failedHop) {
  return [
    direction === "outbound" ? formatNodeId(source) : formatNodeId(destination),
    ...repeaters.map(formatNodeId),
    direction === "outbound" ? formatNodeId(destination) : formatNodeId(source)
  ].map((id, i) => {
    if (i === 0)
      return id;
    if (i - 1 === failedHop)
      return " \xD7 " + id;
    if (i - 1 === currentHop) {
      return (direction === "outbound" ? " \xBB " : " \xAB ") + id;
    }
    return (direction === "outbound" ? " \u203A " : " \u2039 ") + id;
  }).join("");
}
__name(formatRoute, "formatRoute");
function parseMPDU(frame) {
  switch (frame.channel) {
    case 0:
    case 1:
    case 2:
      return ZWaveMPDU.from(frame);
    case 3:
    case 4:
      return LongRangeMPDU.from(frame);
    default:
      import_core.validatePayload.fail(`Unsupported channel ${frame.channel}. MPDU payload: ${(0, import_shared.buffer2hex)(frame.payload)}`);
  }
}
__name(parseMPDU, "parseMPDU");
class LongRangeMPDU {
  static {
    __name(this, "LongRangeMPDU");
  }
  constructor(options) {
    const data = options.data;
    this.frameInfo = options.frameInfo;
    if (options.frameInfo.channel !== 3) {
      import_core.validatePayload.fail(`Unsupported channel ${options.frameInfo.channel} for LongRangeMPDU`);
    }
    this.homeId = data.readUInt32BE(0);
    const nodeIds = data.readUIntBE(4, 3);
    this.sourceNodeId = nodeIds >>> 12;
    this.destinationNodeId = nodeIds & 4095;
    const frameControl = data[8];
    this.ackRequested = !!(frameControl & 128);
    const hasExtendedHeader = !!(frameControl & 64);
    this.headerType = frameControl & 7;
    this.sequenceNumber = data[9];
    this.noiseFloor = (0, import_serialapi.parseRSSI)(data, 10);
    this.txPower = data.readInt8(11);
    let offset = 12;
    if (hasExtendedHeader) {
      const extensionControl = data[offset++];
      const extensionLength = extensionControl & 7;
      offset += extensionLength;
    }
    const Constructor = this.headerType === import_core.MPDUHeaderType.Acknowledgement ? AckLongRangeMPDU : this.headerType === import_core.MPDUHeaderType.Singlecast ? SinglecastLongRangeMPDU : void 0;
    if (!Constructor) {
      import_core.validatePayload.fail(`Unsupported Long Range MPDU header type ${this.headerType}`);
    } else if (new.target !== Constructor && !(0, import_shared.staticExtends)(new.target, Constructor)) {
      return new Constructor(options);
    }
    this.payload = data.subarray(offset);
  }
  frameInfo;
  homeId;
  sourceNodeId;
  destinationNodeId;
  ackRequested;
  headerType;
  sequenceNumber;
  noiseFloor;
  txPower;
  payload;
  static from(msg) {
    return new LongRangeMPDU({
      data: msg.payload,
      frameInfo: (0, import_shared.pick)(msg, [
        "channel",
        "frameType",
        "region",
        "protocolDataRate",
        "rssiRaw"
      ])
    });
  }
  toLogEntry() {
    const tags = [
      formatRoute(
        this.sourceNodeId,
        [],
        this.destinationNodeId,
        // Singlecast frames do not contain a bit for this, we consider them all "outbound"
        "outbound",
        0
      )
    ];
    if (this.headerType === import_core.MPDUHeaderType.Acknowledgement) {
      tags.unshift("ACK");
    }
    const message = {
      "sequence no.": this.sequenceNumber,
      channel: this.frameInfo.channel,
      "protocol/data rate": (0, import_core.znifferProtocolDataRateToString)(this.frameInfo.protocolDataRate),
      "TX power": `${this.txPower} dBm`,
      RSSI: this.frameInfo.rssi != void 0 ? (0, import_core.rssiToString)(this.frameInfo.rssi) : this.frameInfo.rssiRaw.toString(),
      "noise floor": (0, import_core.rssiToString)(this.noiseFloor)
    };
    if (this.headerType !== import_core.MPDUHeaderType.Acknowledgement) {
      message["ack requested"] = this.ackRequested;
    }
    if (this.payload.length > 0) {
      message.payload = (0, import_shared.buffer2hex)(this.payload);
    }
    return {
      tags,
      message
    };
  }
}
class SinglecastLongRangeMPDU extends LongRangeMPDU {
  static {
    __name(this, "SinglecastLongRangeMPDU");
  }
  toLogEntry() {
    const { tags, message: original } = super.toLogEntry();
    const message = {
      ...original,
      payload: (0, import_shared.buffer2hex)(this.payload)
    };
    return {
      tags,
      message
    };
  }
}
class AckLongRangeMPDU extends LongRangeMPDU {
  static {
    __name(this, "AckLongRangeMPDU");
  }
  constructor(options) {
    super(options);
    this.incomingRSSI = (0, import_serialapi.parseRSSI)(this.payload, 0);
    this.payload = this.payload.subarray(1);
  }
  incomingRSSI;
  toLogEntry() {
    const { tags, message: original } = super.toLogEntry();
    const message = {
      ...original,
      "incoming RSSI": (0, import_core.rssiToString)(this.incomingRSSI)
    };
    if (this.payload.length > 0) {
      message.payload = (0, import_shared.buffer2hex)(this.payload);
    }
    return {
      tags,
      message
    };
  }
}
class ZWaveMPDU {
  static {
    __name(this, "ZWaveMPDU");
  }
  constructor(options) {
    const data = options.data;
    this.frameInfo = options.frameInfo;
    let destinationOffset = 8;
    const frameControl = data.subarray(5, 7);
    switch (options.frameInfo.channel) {
      case 0:
      case 1: {
        this.routed = !!(frameControl[0] & 128);
        this.ackRequested = !!(frameControl[0] & 64);
        this.lowPower = !!(frameControl[0] & 32);
        this.speedModified = !!(frameControl[0] & 16);
        this.headerType = frameControl[0] & 15;
        this.beamingInfo = frameControl[1] & 96;
        this.sequenceNumber = frameControl[1] & 15;
        break;
      }
      case 2: {
        this.routed = false;
        this.ackRequested = !!(frameControl[0] & 128);
        this.lowPower = !!(frameControl[0] & 64);
        this.speedModified = false;
        this.headerType = frameControl[0] & 15;
        this.beamingInfo = frameControl[1] & 112;
        this.sequenceNumber = data[destinationOffset];
        destinationOffset++;
        break;
      }
      case 3:
      case 4: {
        import_core.validatePayload.fail(`Channel ${options.frameInfo.channel} (ZWLR) must be parsed as a LongRangeMPDU!`);
      }
      default: {
        import_core.validatePayload.fail(`Unsupported channel ${options.frameInfo.channel}. MPDU payload: ${(0, import_shared.buffer2hex)(data)}`);
      }
    }
    const Constructor = this.headerType === import_core.MPDUHeaderType.Acknowledgement ? AckZWaveMPDU : this.headerType === import_core.MPDUHeaderType.Routed || this.headerType === import_core.MPDUHeaderType.Singlecast && this.routed ? RoutedZWaveMPDU : this.headerType === import_core.MPDUHeaderType.Singlecast ? SinglecastZWaveMPDU : this.headerType === import_core.MPDUHeaderType.Multicast ? MulticastZWaveMPDU : this.headerType === import_core.MPDUHeaderType.Explorer ? ExplorerZWaveMPDU : void 0;
    if (!Constructor) {
      import_core.validatePayload.fail(`Unsupported MPDU header type ${this.headerType}`);
    } else if (new.target !== Constructor && !(0, import_shared.staticExtends)(new.target, Constructor)) {
      return new Constructor(options);
    }
    this.homeId = data.readUInt32BE(0);
    this.sourceNodeId = data[4];
    const destinationLength = this.headerType === import_core.MPDUHeaderType.Multicast ? 30 : 1;
    this.destinationBuffer = data.subarray(destinationOffset, destinationOffset + destinationLength);
    this.payload = data.subarray(destinationOffset + destinationLength);
  }
  frameInfo;
  homeId;
  sourceNodeId;
  routed;
  ackRequested;
  lowPower;
  speedModified;
  headerType;
  beamingInfo;
  sequenceNumber;
  destinationBuffer;
  payload;
  static from(msg) {
    return new ZWaveMPDU({
      data: msg.payload,
      frameInfo: (0, import_shared.pick)(msg, [
        "channel",
        "frameType",
        "region",
        "protocolDataRate",
        "rssiRaw"
      ])
    });
  }
  toLogEntry() {
    const tags = [formatNodeId(this.sourceNodeId)];
    const message = {
      "sequence no.": this.sequenceNumber,
      channel: this.frameInfo.channel,
      "protocol/data rate": (0, import_core.znifferProtocolDataRateToString)(this.frameInfo.protocolDataRate) + (this.speedModified ? " (reduced)" : ""),
      RSSI: this.frameInfo.rssi != void 0 ? (0, import_core.rssiToString)(this.frameInfo.rssi) : this.frameInfo.rssiRaw.toString()
    };
    return {
      tags,
      message
    };
  }
}
class SinglecastZWaveMPDU extends ZWaveMPDU {
  static {
    __name(this, "SinglecastZWaveMPDU");
  }
  constructor(options) {
    super(options);
    this.destinationNodeId = this.destinationBuffer[0];
  }
  destinationNodeId;
  toLogEntry() {
    const { tags, message: original } = super.toLogEntry();
    tags[0] = formatRoute(
      this.sourceNodeId,
      [],
      this.destinationNodeId,
      // Singlecast frames do not contain a bit for this, we consider them all "outbound"
      "outbound",
      0
    );
    const message = {
      ...original,
      "ack requested": this.ackRequested,
      payload: (0, import_shared.buffer2hex)(this.payload)
    };
    return {
      tags,
      message
    };
  }
}
class AckZWaveMPDU extends ZWaveMPDU {
  static {
    __name(this, "AckZWaveMPDU");
  }
  constructor(options) {
    super(options);
    this.destinationNodeId = this.destinationBuffer[0];
  }
  destinationNodeId;
  toLogEntry() {
    const { tags, message } = super.toLogEntry();
    tags[0] = formatRoute(
      this.sourceNodeId,
      [],
      this.destinationNodeId,
      // ACK frames do not contain a bit for this, we consider them all "inbound"
      "inbound",
      0
    );
    tags.unshift("ACK");
    return {
      tags,
      message
    };
  }
}
class RoutedZWaveMPDU extends ZWaveMPDU {
  static {
    __name(this, "RoutedZWaveMPDU");
  }
  constructor(options) {
    super(options);
    const channelConfig = getChannelConfiguration(this.frameInfo.region);
    this.direction = this.payload[0] & 1 ? "inbound" : "outbound";
    this.routedAck = !!(this.payload[0] & 2);
    this.routedError = !!(this.payload[0] & 4);
    const hasExtendedHeader = !!(this.payload[0] & 8);
    if (this.routedError) {
      this.failedHop = this.payload[0] >>> 4;
    } else if (channelConfig === "1/2") {
      this.speedModified = !!(this.payload[0] & 16);
    }
    this.hop = this.payload[1] & 15;
    if (this.direction === "inbound") {
      this.hop = (this.hop + 1) % 16;
    }
    const numRepeaters = this.payload[1] >>> 4;
    this.repeaters = [...this.payload.subarray(2, 2 + numRepeaters)];
    let offset = 2 + numRepeaters;
    if (channelConfig === "3") {
      this.destinationWakeup = this.payload[offset++] === 2;
    }
    if (hasExtendedHeader) {
      const headerPreamble = this.payload[offset++];
      const headerLength = headerPreamble >>> 4;
      const headerType = headerPreamble & 15;
      const header = this.payload.subarray(offset, offset + headerLength);
      offset += headerLength;
      if (headerType === 0) {
        this.destinationWakeupType = header[0] & 64 ? "1000ms" : header[0] & 32 ? "250ms" : void 0;
      } else if (headerType === 1) {
        const repeaterRSSI = [];
        for (let i = 0; i < numRepeaters; i++) {
          repeaterRSSI.push((0, import_serialapi.parseRSSI)(header, i));
        }
        this.repeaterRSSI = repeaterRSSI;
      }
    }
    this.payload = this.payload.subarray(offset);
    this.destinationNodeId = this.destinationBuffer[0];
  }
  destinationNodeId;
  direction;
  routedAck;
  routedError;
  failedHop;
  hop;
  repeaters;
  destinationWakeup;
  destinationWakeupType;
  repeaterRSSI;
  toLogEntry() {
    const { tags, message: original } = super.toLogEntry();
    tags[0] = formatRoute(this.sourceNodeId, this.repeaters, this.destinationNodeId, this.direction, this.hop, this.failedHop);
    const message = {
      ...original,
      "ack requested": this.ackRequested,
      payload: (0, import_shared.buffer2hex)(this.payload)
    };
    return {
      tags,
      message
    };
  }
}
class MulticastZWaveMPDU extends ZWaveMPDU {
  static {
    __name(this, "MulticastZWaveMPDU");
  }
  constructor(options) {
    super(options);
    const control = this.destinationBuffer[0];
    import_core.validatePayload.withReason("Invalid multicast control byte")(control === 29);
    this.destinationNodeIds = (0, import_core.parseNodeBitMask)(this.destinationBuffer.subarray(1));
  }
  destinationNodeIds;
  toLogEntry() {
    const { tags, message: original } = super.toLogEntry();
    tags.push("MULTICAST");
    const message = {
      destinations: this.destinationNodeIds.join(", "),
      ...original,
      payload: (0, import_shared.buffer2hex)(this.payload)
    };
    return {
      tags,
      message
    };
  }
}
class ExplorerZWaveMPDU extends ZWaveMPDU {
  static {
    __name(this, "ExplorerZWaveMPDU");
  }
  constructor(options) {
    super(options);
    this.version = this.payload[0] >>> 5;
    this.command = this.payload[0] & 31;
    this.stop = !!(this.payload[1] & 4);
    this.direction = this.payload[1] & 2 ? "inbound" : "outbound";
    this.sourceRouted = !!(this.payload[1] & 1);
    this.randomTXInterval = this.payload[2];
    this.ttl = this.payload[3] >>> 4;
    const numRepeaters = this.payload[3] & 15;
    this.repeaters = [...this.payload.subarray(4, 4 + numRepeaters)];
    const Constructor = this.command === import_Types.ExplorerFrameCommand.Normal ? NormalExplorerZWaveMPDU : this.command === import_Types.ExplorerFrameCommand.InclusionRequest ? InclusionRequestExplorerZWaveMPDU : this.command === import_Types.ExplorerFrameCommand.SearchResult ? SearchResultExplorerZWaveMPDU : void 0;
    if (!Constructor) {
      import_core.validatePayload.fail(`Unsupported Explorer MPDU command ${this.command}`);
    } else if (new.target !== Constructor && !(0, import_shared.staticExtends)(new.target, Constructor)) {
      return new Constructor(options);
    }
    this.destinationNodeId = this.destinationBuffer[0];
    this.payload = this.payload.subarray(8);
  }
  destinationNodeId;
  version;
  command;
  stop;
  sourceRouted;
  direction;
  randomTXInterval;
  ttl;
  repeaters;
}
class NormalExplorerZWaveMPDU extends ExplorerZWaveMPDU {
  static {
    __name(this, "NormalExplorerZWaveMPDU");
  }
  constructor(options) {
    super(options);
  }
  toLogEntry() {
    const { tags, message: original } = super.toLogEntry();
    tags[0] = formatRoute(
      this.sourceNodeId,
      this.repeaters,
      this.destinationNodeId,
      // Explorer frames do not contain a bit for the direction, we consider them all "outbound"
      "outbound",
      4 - this.ttl
    );
    tags.unshift("EXPLORER");
    const message = {
      ...original,
      "ack requested": this.ackRequested,
      payload: (0, import_shared.buffer2hex)(this.payload)
    };
    return {
      tags,
      message
    };
  }
}
class InclusionRequestExplorerZWaveMPDU extends ExplorerZWaveMPDU {
  static {
    __name(this, "InclusionRequestExplorerZWaveMPDU");
  }
  constructor(options) {
    super(options);
    this.networkHomeId = this.payload.readUInt32BE(0);
    this.payload = this.payload.subarray(4);
  }
  /** The home ID of the repeating node */
  networkHomeId;
  toLogEntry() {
    const { tags, message: original } = super.toLogEntry();
    tags[0] = formatRoute(
      this.sourceNodeId,
      this.repeaters,
      this.destinationNodeId,
      // Explorer frames do not contain a bit for the direction, we consider them all "outbound"
      "outbound",
      4 - this.ttl
    );
    tags.unshift("INCL REQUEST");
    const message = {
      ...original,
      "network home ID": this.networkHomeId.toString(16).padStart(8, "0"),
      payload: (0, import_shared.buffer2hex)(this.payload)
    };
    return {
      tags,
      message
    };
  }
}
class SearchResultExplorerZWaveMPDU extends ExplorerZWaveMPDU {
  static {
    __name(this, "SearchResultExplorerZWaveMPDU");
  }
  constructor(options) {
    super(options);
    this.searchingNodeId = this.payload[0];
    this.frameHandle = this.payload[1];
    this.resultTTL = this.payload[2] >>> 4;
    const numRepeaters = this.payload[2] & 15;
    this.resultRepeaters = [
      ...this.payload.subarray(3, 3 + numRepeaters)
    ];
    this.payload = new import_shared.Bytes();
  }
  /** The node ID that sent the explorer frame that's being answered here */
  searchingNodeId;
  /** The sequence number of the original explorer frame */
  frameHandle;
  resultTTL;
  resultRepeaters;
  toLogEntry() {
    const { tags, message: original } = super.toLogEntry();
    tags[0] = formatRoute(
      this.sourceNodeId,
      this.repeaters,
      this.destinationNodeId,
      // Explorer frames do not contain a bit for the direction, we consider their responses "inbound"
      "inbound",
      4 - this.ttl
    );
    tags.unshift("EXPLORER RESULT");
    const message = {
      ...original,
      "frame handle": this.frameHandle,
      "result TTL": this.resultTTL,
      "result repeaters": this.resultRepeaters.join(", ")
    };
    return {
      tags,
      message
    };
  }
}
function parseBeamFrame(frame) {
  if (frame.frameType === import_serial.ZnifferFrameType.BeamStop) {
    return new BeamStop({
      data: frame.payload,
      frameInfo: frame
    });
  }
  const channelConfig = getChannelConfiguration(frame.region);
  switch (channelConfig) {
    case "1/2":
    case "3": {
      return new ZWaveBeamStart({
        data: frame.payload,
        frameInfo: frame
      });
    }
    case "4": {
      return new LongRangeBeamStart({
        data: frame.payload,
        frameInfo: frame
      });
    }
    default:
      import_core.validatePayload.fail(
        // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
        `Unsupported channel configuration ${channelConfig}. MPDU payload: ${(0, import_shared.buffer2hex)(frame.payload)}`
      );
  }
}
__name(parseBeamFrame, "parseBeamFrame");
class ZWaveBeamStart {
  static {
    __name(this, "ZWaveBeamStart");
  }
  constructor(options) {
    const data = options.data;
    this.frameInfo = options.frameInfo;
    const channelConfig = getChannelConfiguration(this.frameInfo.region);
    switch (channelConfig) {
      case "1/2":
      case "3":
        break;
      case "4": {
        import_core.validatePayload.fail(`Channel configuration 4 (ZWLR) must be parsed as a LongRangeMPDU!`);
      }
      default: {
        import_core.validatePayload.fail(
          // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
          `Unsupported channel configuration ${channelConfig}. MPDU payload: ${(0, import_shared.buffer2hex)(data)}`
        );
      }
    }
    this.destinationNodeId = data[1];
    if (data[2] === 1) {
      this.homeIdHash = data[3];
    }
  }
  frameInfo;
  homeIdHash;
  destinationNodeId;
  toLogEntry() {
    const tags = [
      `BEAM \xBB ${formatNodeId(this.destinationNodeId)}`
    ];
    const message = {
      channel: this.frameInfo.channel,
      "protocol/data rate": (0, import_core.znifferProtocolDataRateToString)(this.frameInfo.protocolDataRate),
      RSSI: this.frameInfo.rssi != void 0 ? (0, import_core.rssiToString)(this.frameInfo.rssi) : this.frameInfo.rssiRaw.toString()
    };
    return {
      tags,
      message
    };
  }
}
class LongRangeBeamStart {
  static {
    __name(this, "LongRangeBeamStart");
  }
  constructor(options) {
    const data = options.data;
    this.frameInfo = options.frameInfo;
    const channelConfig = getChannelConfiguration(this.frameInfo.region);
    switch (channelConfig) {
      case "1/2":
      case "3":
        break;
      case "4": {
        import_core.validatePayload.fail(`Channel configuration 4 (ZWLR) must be parsed as a LongRangeMPDU!`);
      }
      default: {
        import_core.validatePayload.fail(
          // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
          `Unsupported channel configuration ${channelConfig}. MPDU payload: ${(0, import_shared.buffer2hex)(data)}`
        );
      }
    }
    const txPower = data[1] >>> 4;
    this.txPower = longRangeBeamPowerToDBm(txPower);
    this.destinationNodeId = data.readUInt16BE(1) & 4095;
    this.homeIdHash = data[3];
  }
  frameInfo;
  homeIdHash;
  destinationNodeId;
  txPower;
  toLogEntry() {
    const tags = [
      `BEAM \xBB ${formatNodeId(this.destinationNodeId)}`
    ];
    const message = {
      channel: this.frameInfo.channel,
      "protocol/data rate": (0, import_core.znifferProtocolDataRateToString)(this.frameInfo.protocolDataRate),
      "TX power": `${this.txPower} dBm`,
      RSSI: this.frameInfo.rssi != void 0 ? (0, import_core.rssiToString)(this.frameInfo.rssi) : this.frameInfo.rssiRaw.toString()
    };
    return {
      tags,
      message
    };
  }
}
class BeamStop {
  static {
    __name(this, "BeamStop");
  }
  constructor(options) {
    this.frameInfo = options.frameInfo;
  }
  frameInfo;
  toLogEntry() {
    const tags = [
      "BEAM STOP"
    ];
    const message = {
      channel: this.frameInfo.channel
    };
    return {
      tags,
      message
    };
  }
}
function mpduToFrame(mpdu, payloadCC) {
  if (mpdu instanceof ZWaveMPDU) {
    return mpduToZWaveFrame(mpdu, payloadCC);
  } else if (mpdu instanceof LongRangeMPDU) {
    return mpduToLongRangeFrame(mpdu, payloadCC);
  }
  throw new import_core.ZWaveError(`mpduToFrame not supported for ${mpdu.constructor.name}`, import_core.ZWaveErrorCodes.Argument_Invalid);
}
__name(mpduToFrame, "mpduToFrame");
function mpduToZWaveFrame(mpdu, payloadCC) {
  const retBase = {
    protocol: import_core.Protocols.ZWave,
    channel: mpdu.frameInfo.channel,
    region: mpdu.frameInfo.region,
    rssiRaw: mpdu.frameInfo.rssiRaw,
    rssi: mpdu.frameInfo.rssi,
    protocolDataRate: mpdu.frameInfo.protocolDataRate,
    speedModified: mpdu.speedModified,
    sequenceNumber: mpdu.sequenceNumber,
    homeId: mpdu.homeId,
    sourceNodeId: mpdu.sourceNodeId
  };
  if (mpdu instanceof SinglecastZWaveMPDU) {
    const ret = {
      ...retBase,
      ackRequested: mpdu.ackRequested,
      payload: payloadCC ?? mpdu.payload
    };
    if (mpdu.destinationNodeId === import_core.NODE_ID_BROADCAST) {
      return {
        type: import_Types.ZWaveFrameType.Broadcast,
        destinationNodeId: mpdu.destinationNodeId,
        ...ret
      };
    } else {
      return {
        type: import_Types.ZWaveFrameType.Singlecast,
        destinationNodeId: mpdu.destinationNodeId,
        ...ret
      };
    }
  } else if (mpdu instanceof AckZWaveMPDU) {
    return {
      type: import_Types.ZWaveFrameType.AckDirect,
      ...retBase,
      destinationNodeId: mpdu.destinationNodeId
    };
  } else if (mpdu instanceof MulticastZWaveMPDU) {
    return {
      type: import_Types.ZWaveFrameType.Multicast,
      ...retBase,
      destinationNodeIds: [...mpdu.destinationNodeIds],
      payload: payloadCC ?? mpdu.payload
    };
  } else if (mpdu instanceof RoutedZWaveMPDU) {
    return {
      type: import_Types.ZWaveFrameType.Singlecast,
      ...retBase,
      destinationNodeId: mpdu.destinationNodeId,
      ackRequested: mpdu.ackRequested,
      payload: payloadCC ?? mpdu.payload,
      direction: mpdu.direction,
      hop: mpdu.hop,
      repeaters: [...mpdu.repeaters],
      repeaterRSSI: mpdu.repeaterRSSI && [...mpdu.repeaterRSSI],
      routedAck: mpdu.routedAck,
      routedError: mpdu.routedError,
      failedHop: mpdu.failedHop
    };
  } else if (mpdu instanceof ExplorerZWaveMPDU) {
    const explorerBase = {
      ...retBase,
      destinationNodeId: mpdu.destinationNodeId,
      ackRequested: mpdu.ackRequested,
      direction: mpdu.direction,
      repeaters: [...mpdu.repeaters],
      ttl: mpdu.ttl
    };
    if (mpdu instanceof NormalExplorerZWaveMPDU) {
      return {
        type: import_Types.ZWaveFrameType.ExplorerNormal,
        payload: payloadCC ?? mpdu.payload,
        ...explorerBase
      };
    } else if (mpdu instanceof SearchResultExplorerZWaveMPDU) {
      return {
        type: import_Types.ZWaveFrameType.ExplorerSearchResult,
        ...explorerBase,
        searchingNodeId: mpdu.searchingNodeId,
        frameHandle: mpdu.frameHandle,
        resultTTL: mpdu.resultTTL,
        resultRepeaters: [...mpdu.resultRepeaters]
      };
    } else if (mpdu instanceof InclusionRequestExplorerZWaveMPDU) {
      return {
        type: import_Types.ZWaveFrameType.ExplorerInclusionRequest,
        payload: payloadCC ?? mpdu.payload,
        ...explorerBase,
        networkHomeId: mpdu.networkHomeId
      };
    }
  }
  throw new import_core.ZWaveError(`mpduToZWaveFrame not supported for ${mpdu.constructor.name}`, import_core.ZWaveErrorCodes.Argument_Invalid);
}
__name(mpduToZWaveFrame, "mpduToZWaveFrame");
function mpduToLongRangeFrame(mpdu, payloadCC) {
  const retBase = {
    protocol: import_core.Protocols.ZWaveLongRange,
    channel: mpdu.frameInfo.channel,
    region: mpdu.frameInfo.region,
    protocolDataRate: mpdu.frameInfo.protocolDataRate,
    rssiRaw: mpdu.frameInfo.rssiRaw,
    rssi: mpdu.frameInfo.rssi,
    noiseFloor: mpdu.noiseFloor,
    txPower: mpdu.txPower,
    sequenceNumber: mpdu.sequenceNumber,
    homeId: mpdu.homeId,
    sourceNodeId: mpdu.sourceNodeId,
    destinationNodeId: mpdu.destinationNodeId
  };
  if (mpdu instanceof SinglecastLongRangeMPDU) {
    const ret = {
      ...retBase,
      ackRequested: mpdu.ackRequested,
      payload: payloadCC ?? mpdu.payload
    };
    if (mpdu.destinationNodeId === import_core.NODE_ID_BROADCAST_LR) {
      return {
        type: import_Types.LongRangeFrameType.Broadcast,
        ...ret,
        destinationNodeId: mpdu.destinationNodeId
        // Make TS happy
      };
    } else {
      return {
        type: import_Types.LongRangeFrameType.Singlecast,
        ...ret
      };
    }
  } else if (mpdu instanceof AckLongRangeMPDU) {
    return {
      type: import_Types.LongRangeFrameType.Ack,
      ...retBase,
      incomingRSSI: mpdu.incomingRSSI,
      payload: mpdu.payload
    };
  }
  throw new import_core.ZWaveError(`mpduToLongRangeFrame not supported for ${mpdu.constructor.name}`, import_core.ZWaveErrorCodes.Argument_Invalid);
}
__name(mpduToLongRangeFrame, "mpduToLongRangeFrame");
function beamToFrame(beam) {
  const retBase = {
    channel: beam.frameInfo.channel,
    region: beam.frameInfo.region,
    rssiRaw: beam.frameInfo.rssiRaw,
    rssi: beam.frameInfo.rssi,
    protocolDataRate: beam.frameInfo.protocolDataRate
  };
  if (beam instanceof ZWaveBeamStart) {
    return {
      protocol: import_core.Protocols.ZWave,
      type: import_Types.ZWaveFrameType.BeamStart,
      ...retBase,
      destinationNodeId: beam.destinationNodeId,
      homeIdHash: beam.homeIdHash
    };
  } else if (beam instanceof LongRangeBeamStart) {
    return {
      protocol: import_core.Protocols.ZWaveLongRange,
      type: import_Types.LongRangeFrameType.BeamStart,
      ...retBase,
      destinationNodeId: beam.destinationNodeId,
      homeIdHash: beam.homeIdHash,
      txPower: beam.txPower
    };
  } else {
    const isLR = beam.frameInfo.channel === 4;
    if (isLR) {
      return {
        protocol: import_core.Protocols.ZWaveLongRange,
        type: import_Types.LongRangeFrameType.BeamStop,
        channel: beam.frameInfo.channel
      };
    } else {
      return {
        protocol: import_core.Protocols.ZWave,
        type: import_Types.ZWaveFrameType.BeamStop,
        channel: beam.frameInfo.channel
      };
    }
  }
}
__name(beamToFrame, "beamToFrame");
function znifferDataMessageToCorruptedFrame(msg, rssi) {
  if (msg.checksumOK) {
    throw new import_core.ZWaveError(`znifferDataMessageToCorruptedFrame expects the checksum to be incorrect`, import_core.ZWaveErrorCodes.Argument_Invalid);
  }
  return {
    channel: msg.channel,
    region: msg.region,
    rssiRaw: msg.rssiRaw,
    rssi,
    protocolDataRate: msg.protocolDataRate,
    payload: msg.payload
  };
}
__name(znifferDataMessageToCorruptedFrame, "znifferDataMessageToCorruptedFrame");
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  AckLongRangeMPDU,
  AckZWaveMPDU,
  BeamStop,
  ExplorerZWaveMPDU,
  InclusionRequestExplorerZWaveMPDU,
  LongRangeBeamStart,
  LongRangeMPDU,
  MulticastZWaveMPDU,
  NormalExplorerZWaveMPDU,
  RoutedZWaveMPDU,
  SearchResultExplorerZWaveMPDU,
  SinglecastLongRangeMPDU,
  SinglecastZWaveMPDU,
  ZWaveBeamStart,
  ZWaveMPDU,
  beamToFrame,
  mpduToFrame,
  mpduToLongRangeFrame,
  mpduToZWaveFrame,
  parseBeamFrame,
  parseMPDU,
  znifferDataMessageToCorruptedFrame
});
//# sourceMappingURL=MPDU.js.map
