11//
22// DMPLayer.swift
33//
4- // Copyright (c) 2022 Daniel Murfin
4+ // Copyright (c) 2023 Daniel Murfin
55//
66// Permission is hereby granted, free of charge, to any person obtaining a copy
77// of this software and associated documentation files (the "Software"), to deal
@@ -27,16 +27,17 @@ import Foundation
2727/// DMP Layer
2828///
2929/// Implements the DMP Layer and handles creation and parsing.
30- ///
3130struct DMPLayer {
3231
3332 /// The flags and length. 0x720b: 20b = 523 (starting octet 115) = 638
33+ /// This must only be used for constructing packets as received packets may have differing lengths.
3434 private static let flagsAndLength = Data ( [ 0x72 , 0x0b ] )
3535
3636 /// The address type and data type, first property address (DMX512-A START Code is at DMP address 0), and address increment.
3737 private static let addressPropertyBlock = Data ( [ 0xa1 , 0x00 , 0x00 , 0x00 , 0x01 ] )
3838
3939 /// The number of slots in the message (plus the START Code).
40+ /// This must only be used for constructing packets as received packets may have differing lengths.
4041 private static let propertyValueCount = Data ( [ 0x02 , 0x01 ] )
4142
4243 /// DMP Layer Vectors
@@ -62,19 +63,8 @@ struct DMPLayer {
6263 case propertyValues = 10
6364 }
6465
65- /// DMP Layer DMX512-A START Codes
66- ///
67- /// Enumerates the data offset for each field in this layer.
68- ///
69- enum STARTCode : UInt8 {
70- /// Contains dmx level data.
71- case null = 0x00
72- /// Contains per-slot priority data.
73- case perAddressPriority = 0xdd
74- }
75-
7666 /// The start code for this message.
77- var startCode : STARTCode
67+ var startCode : DMX . STARTCode
7868
7969 /// The values for this message.
8070 var values : [ UInt8 ]
@@ -87,7 +77,7 @@ struct DMPLayer {
8777 ///
8878 /// - Returns: A `DMPLayer` as a `Data` object.
8979 ///
90- static func createAsData( startCode: STARTCode , values: [ UInt8 ] ) -> Data {
80+ static func createAsData( startCode: DMX . STARTCode , values: [ UInt8 ] ) -> Data {
9181 var data = Data ( )
9282 data. append ( contentsOf: DMPLayer . flagsAndLength)
9383 data. append ( Vector . setProperty. rawValue. data)
@@ -111,8 +101,8 @@ struct DMPLayer {
111101 guard data. count > Offset . propertyValues. rawValue+ 1 else { throw DMPLayerValidationError . lengthOutOfRange }
112102
113103 // the flags and length
114- guard data [ Offset . flagsAndLength. rawValue..< Offset . vector . rawValue ] == Self . flagsAndLength else {
115- throw DMPLayerValidationError . invalidFlagsAndLength
104+ guard let flagsAndLength = data. toFlagsAndLength ( atOffset : Offset . flagsAndLength. rawValue) , flagsAndLength . length == data . count - Offset . flagsAndLength. rawValue else {
105+ throw DataFramingLayerValidationError . invalidFlagsAndLength
116106 }
117107 // the vector for this layer
118108 guard let vector: UInt8 = data. toUInt8 ( atOffset: Offset . vector. rawValue) else {
@@ -129,15 +119,15 @@ struct DMPLayer {
129119 guard let propertyValueCount: UInt16 = data. toUInt16 ( atOffset: Offset . propertyValueCount. rawValue) else {
130120 throw DMPLayerValidationError . unableToParse ( field: " Property Value Count " )
131121 }
132- guard propertyValueCount < 513 else {
122+ guard propertyValueCount <= 513 && data . count >= Offset . propertyValues . rawValue + Int ( propertyValueCount ) else {
133123 throw DMPLayerValidationError . invalidPropertyValueCount ( propertyValueCount)
134124 }
135125 // the START Code
136- guard let code: UInt8 = data. toUInt8 ( atOffset: Offset . propertyValues. rawValue) , let STARTCode = STARTCode ( rawValue: code) else {
126+ guard let code: UInt8 = data. toUInt8 ( atOffset: Offset . propertyValues. rawValue) , let STARTCode = DMX . STARTCode ( rawValue: code) else {
137127 throw DMPLayerValidationError . unableToParse ( field: " START Code " )
138128 }
139129 let propertyValuesOffset = Offset . propertyValues. rawValue+ 1
140- let values = data. subdata ( in: propertyValuesOffset..< propertyValuesOffset+ Int( propertyValueCount) ) . bytes
130+ let values = data. subdata ( in: propertyValuesOffset..< propertyValuesOffset+ Int( propertyValueCount- 1 ) ) . bytes
141131
142132 return Self ( startCode: STARTCode, values: values)
143133 }
0 commit comments