diff --git a/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/commands/abstractCommand.ts b/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/commands/abstractCommand.ts index 5ddfe060b..e9dc9d563 100644 --- a/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/commands/abstractCommand.ts +++ b/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/commands/abstractCommand.ts @@ -77,6 +77,15 @@ export abstract class ViscaInquiryCommand extends AbstractCommand { } } +export abstract class ViscaDeviceSettingCommand extends AbstractCommand { + readonly commandType = CommandType.ViscaDeviceSetting + + deserializeReply(_payload: Buffer): unknown { + // No reply expected + return undefined + } +} + export abstract class ControlCommand extends AbstractCommand { readonly commandType = CommandType.ControlCommand diff --git a/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/commands/control/resetSeqNumberCommand.ts b/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/commands/control/resetSeqNumberCommand.ts index a1f9186e1..734d0331d 100644 --- a/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/commands/control/resetSeqNumberCommand.ts +++ b/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/commands/control/resetSeqNumberCommand.ts @@ -1,8 +1,8 @@ -import { ControlCommand } from '../abstractCommand.js' +import { ViscaDeviceSettingCommand } from '../abstractCommand.js' -/** The IF_Clear command */ -export class ResetSequenceNumberCommand extends ControlCommand { +/** The IF_Clear command - VISCA device setting command (type 0x0120), payload 8X 01 00 01 FF where X=1 for VISCA over IP */ +export class ResetSequenceNumberCommand extends ViscaDeviceSettingCommand { serialize() { - return Buffer.from([0x88, 0x01, 0x00, 0x01, 0xff]) + return Buffer.from([0x81, 0x01, 0x00, 0x01, 0xff]) } } diff --git a/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/enums.ts b/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/enums.ts index 82d0cdfcc..fd716db7d 100644 --- a/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/enums.ts +++ b/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/enums.ts @@ -2,6 +2,7 @@ export enum CommandType { ViscaCommand = 0x0100, ViscaInquiry = 0x0110, ViscaReply = 0x0111, + ViscaDeviceSetting = 0x0120, ControlCommand = 0x0200, ControlReply = 0x0201, } diff --git a/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/lib/socket.ts b/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/lib/socket.ts index a3b0b7d25..d87d521ff 100644 --- a/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/lib/socket.ts +++ b/packages/timeline-state-resolver/src/integrations/viscaOverIP/connection/lib/socket.ts @@ -133,7 +133,7 @@ export class ViscaUdpSocket extends EventEmitter { this._sendNextPacket() - this._localPacketId = this._localPacketId++ % this._maxPacketID + this._localPacketId = (this._localPacketId + 1) % this._maxPacketID return promise } @@ -150,21 +150,25 @@ export class ViscaUdpSocket extends EventEmitter { this._lastReceivedAt = Date.now() const type = packet.readUInt16BE(0) as CommandType - const length = packet.readUInt32BE(4) + const length = packet.readUInt16BE(2) if (this._debug) this.log('type', type, !!this._inFlight) if (type === CommandType.ViscaReply && this._inFlight) { // @todo: think about what resolves a command. - if (length === 3 && packet.readUInt8(9) === 0x41) { + if (length === 3 && (packet.readUInt8(9) & 0xf0) === 0x40) { // supposedly an ack return // completion resolves, and not ack so we skip - } else if (length === 4 && packet.readUInt8(9) === 0x51) { + } else if (length === 3 && (packet.readUInt8(9) & 0xf0) === 0x50) { // supposedly a completion + if (this._connectionState === ConnectionState.Connecting) { + this._connectionState = ConnectionState.Connected + this.emit('connected') + } this._inFlight.promise.resolve() - } else if (length === 4 && packet.readUInt16BE(9) === 0x6002) { + } else if (length === 4 && (packet.readUInt8(9) & 0xf0) === 0x60 && packet.readUInt8(10) === 0x02) { // supposedly a syntax error this._inFlight.promise.reject(new Error('Syntax Error')) - } else if (length === 4 && packet.readUInt16BE(9) === 0x6141) { + } else if (length === 4 && (packet.readUInt8(9) & 0xf0) === 0x60 && packet.readUInt8(10) === 0x41) { // supposedly not executable this._inFlight.promise.reject(new Error('Not executable')) } else {