mirror of
https://github.com/jwetzell/acn-js.git
synced 2026-08-22 14:48:59 +00:00
start work towards DMP protocol decoding
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# acn-js
|
# acn-js
|
||||||
not sure how far I will take this but messing around with E1.17 ACN protocol
|
not sure how far I will take this but messing around with E1.17 ACN protocol
|
||||||
|
|
||||||
## areas
|
## packet decoding
|
||||||
- rlp
|
- rlp
|
||||||
- sdt
|
- sdt
|
||||||
- vectors
|
- vectors
|
||||||
@@ -23,4 +23,16 @@ not sure how far I will take this but messing around with E1.17 ACN protocol
|
|||||||
- [x] DISCONNECT
|
- [x] DISCONNECT
|
||||||
- [x] DISCONNECTING
|
- [x] DISCONNECTING
|
||||||
- dmp
|
- 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
|
- ddl
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
export enum Protocol {
|
export enum Protocol {
|
||||||
SDT = 1,
|
SDT = 1,
|
||||||
|
DMP,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SDTVector {
|
export enum SDTVector {
|
||||||
@@ -22,6 +23,26 @@ export enum SDTVector {
|
|||||||
SESSIONS,
|
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 {
|
export enum TransportLayerAddressType {
|
||||||
SDT_ADDR_NULL = 0,
|
SDT_ADDR_NULL = 0,
|
||||||
SDT_ADDR_IPV4,
|
SDT_ADDR_IPV4,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
};
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import rlp from './rlp';
|
import rlp from './rlp';
|
||||||
import sdt from './sdt';
|
import sdt from './sdt';
|
||||||
|
import dmp from './dmp';
|
||||||
export default {
|
export default {
|
||||||
rlp,
|
rlp,
|
||||||
sdt,
|
sdt,
|
||||||
|
dmp,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import pdu from '.';
|
||||||
import { Protocol, SDTVector } from '../enums';
|
import { Protocol, SDTVector } from '../enums';
|
||||||
import {
|
import {
|
||||||
|
DeviceManagementProtocolPDU,
|
||||||
SDTAckData,
|
SDTAckData,
|
||||||
SDTConnectAcceptData,
|
SDTConnectAcceptData,
|
||||||
SDTConnectData,
|
SDTConnectData,
|
||||||
@@ -113,10 +115,12 @@ function decodeClientBlock(bytes: Uint8Array) {
|
|||||||
const dataOffset = headerOffset + 6;
|
const dataOffset = headerOffset + 6;
|
||||||
// NOTE(jwetzell): flags/lengthH + lengthL + lengthX + vector + header
|
// NOTE(jwetzell): flags/lengthH + lengthL + lengthX + vector + header
|
||||||
const dataLength = length - (1 + 1 + (lengthFlag ? 1 : 0) + 2 + 6);
|
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) {
|
if (clientProtocol === Protocol.SDT) {
|
||||||
data = decode(data);
|
data = decode(data);
|
||||||
|
} else if (clientProtocol === Protocol.DMP) {
|
||||||
|
data = pdu.dmp.decode(data)
|
||||||
} else {
|
} else {
|
||||||
console.error(`SDT client block contains unknown protocol: ${clientProtocol}`);
|
console.error(`SDT client block contains unknown protocol: ${clientProtocol}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { TransportLayerAddressType, SDTVector, SDTReasonCode } from './enums';
|
import { TransportLayerAddressType, SDTVector, SDTReasonCode, DMPVector } from './enums';
|
||||||
|
|
||||||
export type UDPPreamble = {
|
export type UDPPreamble = {
|
||||||
preambleSize: number;
|
preambleSize: number;
|
||||||
@@ -133,9 +133,26 @@ export type SessionDataTransportPDU = {
|
|||||||
| Uint8Array;
|
| 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 = {
|
export type SDTClientBlock = {
|
||||||
memberID: number;
|
memberID: number;
|
||||||
clientProtocol: number;
|
clientProtocol: number;
|
||||||
association: number;
|
association: number;
|
||||||
data: SessionDataTransportPDU | Uint8Array;
|
data: SessionDataTransportPDU | DeviceManagementProtocolPDU | Uint8Array;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user