start work towards DMP protocol decoding

This commit is contained in:
2024-12-08 21:23:33 -06:00
parent 9438986254
commit a10aebb248
6 changed files with 137 additions and 4 deletions
+13 -1
View File
@@ -1,7 +1,7 @@
# acn-js
not sure how far I will take this but messing around with E1.17 ACN protocol
## areas
## packet decoding
- rlp
- sdt
- vectors
@@ -23,4 +23,16 @@ not sure how far I will take this but messing around with E1.17 ACN protocol
- [x] DISCONNECT
- [x] DISCONNECTING
- dmp
- vectors
- [ ] GET_PROPERTY
- [ ] SET_PROPERTY
- [ ] GET_PROPERTY_REPLY
- [ ] EVENT
- [ ] SUBSCRIBE
- [ ] UNSUBSCRIBE
- [ ] GET_PROPERTY_FAIL
- [ ] SET_PROPERTY_FAIL
- [ ] SUBSCRIBE_ACCEPT
- [ ] SUBSCRIBE_REJECT
- [ ] SYNC_EVENT
- ddl
+21
View File
@@ -1,5 +1,6 @@
export enum Protocol {
SDT = 1,
DMP,
}
export enum SDTVector {
@@ -22,6 +23,26 @@ export enum SDTVector {
SESSIONS,
}
export enum DMPVector {
GET_PROPERTY = 1,
SET_PROPERTY,
GET_PROPERTY_REPLY,
EVENT,
RESERVED_1,
RESERVED_2,
SUBSCRIBE,
UNSUBSCRIBE,
GET_PROPERTY_FAIL,
SET_PROPERTY_FAIL,
RESERVED_3,
SUBSCRIBE_ACCEPT,
SUBSCRIBE_REJECT,
RESERVED_4,
RESERVED_5,
RESERVED_6,
SYNC_EVENT,
}
export enum TransportLayerAddressType {
SDT_ADDR_NULL = 0,
SDT_ADDR_IPV4,
+77
View File
@@ -0,0 +1,77 @@
import { DMPVector } from '../enums';
import { DeviceManagementProtocolPDU, DMPAddressDataType, DMPGetPropertyData } from '../types';
export function decode(bytes: Uint8Array): DeviceManagementProtocolPDU {
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
const flags = view.getUint8(0) >> 4;
const lengthFlag = ((flags >> 3) & 0x1) === 1;
const vectorFlag = ((flags >> 2) & 0x1) === 1;
const headerFlag = ((flags >> 1) & 0x1) === 1;
if (!vectorFlag) {
throw new Error('SDT PDU must have a vector');
}
const dataFlag = (flags & 0x1) === 1;
if (!dataFlag) {
// TODO(jwetzell): idk if this is true
throw new Error('SDT PDU must have data');
}
const lengthH = view.getUint8(0) & 0x0f;
let lengthOffset = 1;
const lengthL = view.getUint8(lengthOffset);
let length = (lengthH << 8) + lengthL;
if (lengthFlag) {
lengthOffset += 1;
const lengthX = view.getUint8(lengthOffset);
length = (lengthH << 16) + (lengthL << 8) + lengthX;
}
let vectorOffset = lengthOffset + 1;
if (lengthFlag) {
vectorOffset += 1;
}
const vector = view.getUint8(vectorOffset);
let headerOffset = (vectorOffset += 1);
const addressAndDataTypes = view.getUint8(headerOffset);
const addressType = (addressAndDataTypes >> 6) & 0x1;
const dataType = (addressAndDataTypes >> 4) & 0x3;
const elementSize = addressAndDataTypes & 0x11;
const addressAndDataType = {
addressType,
dataType,
elementSize
}
const dataOffset = headerOffset + 1;
// NOTE(jwetzell): flags/lengthH + lengthL + lengthX + vector + header
const dataLength = length - (1 + 1 + (lengthFlag ? 1 : 0) + 1 + 1);
const data = decodeData(vector, bytes.subarray(dataOffset, dataOffset + dataLength), addressAndDataType);
console.log('decoded Data', data)
return {
vector,
data
};
}
function decodeData(vector: number, bytes: Uint8Array, addressAndDataType: DMPAddressDataType): DMPGetPropertyData | Uint8Array {
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
console.log('pdu bytes', bytes)
console.log('pdu address data type', addressAndDataType)
switch (vector) {
default:
console.error(`unhandled DMP vector: ${vector}`);
return bytes;
}
}
export default {
decode,
};
+2
View File
@@ -1,6 +1,8 @@
import rlp from './rlp';
import sdt from './sdt';
import dmp from './dmp';
export default {
rlp,
sdt,
dmp,
};
+5 -1
View File
@@ -1,5 +1,7 @@
import pdu from '.';
import { Protocol, SDTVector } from '../enums';
import {
DeviceManagementProtocolPDU,
SDTAckData,
SDTConnectAcceptData,
SDTConnectData,
@@ -113,10 +115,12 @@ function decodeClientBlock(bytes: Uint8Array) {
const dataOffset = headerOffset + 6;
// NOTE(jwetzell): flags/lengthH + lengthL + lengthX + vector + header
const dataLength = length - (1 + 1 + (lengthFlag ? 1 : 0) + 2 + 6);
let data: SessionDataTransportPDU | Uint8Array = bytes.subarray(dataOffset, dataOffset + dataLength);
let data: SessionDataTransportPDU | DeviceManagementProtocolPDU | Uint8Array = bytes.subarray(dataOffset, dataOffset + dataLength);
if (clientProtocol === Protocol.SDT) {
data = decode(data);
} else if (clientProtocol === Protocol.DMP) {
data = pdu.dmp.decode(data)
} else {
console.error(`SDT client block contains unknown protocol: ${clientProtocol}`);
}
+19 -2
View File
@@ -1,4 +1,4 @@
import { TransportLayerAddressType, SDTVector, SDTReasonCode } from './enums';
import { TransportLayerAddressType, SDTVector, SDTReasonCode, DMPVector } from './enums';
export type UDPPreamble = {
preambleSize: number;
@@ -133,9 +133,26 @@ export type SessionDataTransportPDU = {
| Uint8Array;
};
export type DMPAddressDataType = {
addressType: number;
dataType: number;
elementSize: number;
};
export type DMPGetPropertyData = {
address: number
}
export type DMPSubscribePropertyData = DMPGetPropertyData
export type DeviceManagementProtocolPDU = {
vector: DMPVector;
data: DMPGetPropertyData | DMPSubscribePropertyData | Uint8Array;
};
export type SDTClientBlock = {
memberID: number;
clientProtocol: number;
association: number;
data: SessionDataTransportPDU | Uint8Array;
data: SessionDataTransportPDU | DeviceManagementProtocolPDU | Uint8Array;
};