1 /// 2 module modbus.backend.specrules; 3 4 version (modbus_verbose) 5 import std.experimental.logger; 6 7 /// 8 interface SpecRules 9 { 10 pure: 11 /// 12 @property size_t deviceTypeSize(); 13 14 /// 15 const(void)[] packDF(ulong dev, ubyte fnc); 16 /// 17 void peekDF(const(void)[] buf, ref ulong dev, ref ubyte fnc); 18 19 /// 20 const(void)[] pack(byte); 21 /// 22 const(void)[] pack(short); 23 /// 24 const(void)[] pack(int); 25 /// 26 const(void)[] pack(long); 27 /// 28 const(void)[] pack(float); 29 /// 30 const(void)[] pack(double); 31 } 32 33 /// 34 class BasicSpecRules : SpecRules 35 { 36 protected: 37 ubyte[16] buffer; 38 39 public: 40 41 pure: 42 43 override 44 { 45 @property size_t deviceTypeSize() { return 1; } 46 47 const(void)[] packDF(ulong dev, ubyte fnc) 48 { 49 import std.bitmanip : write; 50 assert(dev <= 255, "device number can't be more 255"); 51 buffer[].write(cast(ubyte)dev, 0); 52 buffer[].write(fnc, 1); 53 return buffer[0..2]; 54 } 55 56 void peekDF(const(void)[] vbuf, ref ulong dev, ref ubyte fnc) 57 { 58 import std.bitmanip : peek; 59 auto buf = cast(const(ubyte)[])vbuf; 60 if (buf.length >= 1) dev = buf.peek!ubyte(0); 61 else version (modbus_verbose) debug 62 .error("short readed message: can't read device number"); 63 if (buf.length >= 2) fnc = buf.peek!ubyte(1); 64 else version (modbus_verbose) debug 65 .error("short readed message: can't read function number"); 66 } 67 68 const(void)[] pack(byte v) { return tpack(v); } 69 const(void)[] pack(short v) { return tpack(v); } 70 const(void)[] pack(int v) { return tpack(v); } 71 const(void)[] pack(long v) { return tpack(v); } 72 const(void)[] pack(float v) { return tpack(v); } 73 const(void)[] pack(double v) { return tpack(v); } 74 } 75 76 private: 77 78 const(void)[] tpack(T)(T v) 79 { 80 import std.bitmanip : write; 81 buffer[].write(v, 0); 82 return buffer[0..T.sizeof]; 83 } 84 } 85 86 /// 87 class PilotBMSSpecRules : BasicSpecRules 88 { 89 public pure override: 90 @property size_t deviceTypeSize() { return 4; } 91 92 const(void)[] packDF(ulong dev, ubyte fnc) 93 { 94 import std.bitmanip : write; 95 size_t idx = 0; 96 buffer[].write(cast(ushort)(dev), &idx); 97 buffer[].write(cast(ushort)(dev>>16), &idx); 98 buffer[].write(fnc, &idx); 99 return buffer[0..idx]; 100 } 101 102 void peekDF(const(void)[] vbuf, ref ulong dev, ref ubyte fnc) 103 { 104 import std.bitmanip : peek; 105 size_t idx = 0; 106 auto buf = cast(const(ubyte)[])vbuf; 107 if (buf.length >= 4) 108 { 109 const a = buf.peek!ushort(&idx); 110 const b = buf.peek!ushort(&idx); 111 dev = (b << 16) | a; 112 } 113 else version (modbus_verbose) debug 114 .error("short readed message: can't read device number"); 115 if (buf.length >= idx) fnc = buf.peek!ubyte(idx); 116 else version (modbus_verbose) debug 117 .error("short readed message: can't read function number"); 118 } 119 }