1 ///
2 module modbus.backend.tcp;
3 
4 import std.bitmanip;
5 
6 import modbus.backend.base;
7 
8 ///
9 class TCP : BaseBackend
10 {
11 protected:
12     // transaction id size + protocol id size + packet length size
13     enum packetServiceData = ushort.sizeof * 3;
14     enum packetLengthOffset = ushort.sizeof * 2;
15 public:
16     ///
17     this(Connection con, SpecRules s=null)
18     { super(con, s, packetServiceData, packetServiceData); }
19 
20 protected override:
21     void startMessage(void[] buf, ref size_t idx, ulong dev, ubyte fnc)
22     {
23         const ushort zero;
24         // transaction id
25         append(buf, idx, zero);
26         // protocol id
27         append(buf, idx, zero);
28         // packet length (change in completeMessage)
29         append(buf, idx, zero);
30         appendDF(buf, idx, dev, fnc);
31     }
32 
33     void completeMessage(void[] buf, ref size_t idx)
34     {
35         auto dsize = cast(ushort)(idx - packetServiceData);
36         size_t plo = packetLengthOffset;
37         append(buf, plo, dsize);
38     }
39 
40     bool check(const(void)[] data)
41     {
42         enum plo = packetLengthOffset;
43         auto lenbytes = cast(ubyte[2])data[plo..plo+ushort.sizeof];
44         auto len = bigEndianToNative!ushort(lenbytes);
45         return len == (data.length - packetServiceData);
46     }
47     size_t endDataSplit() @property { return 0; }
48 }
49 
50 unittest
51 {
52     import std.array : appender;
53     void[100] data = void;
54     auto tcp = new TCP(nullConnection);
55     int xx = 123;
56     auto res = cast(ubyte[])tcp.buildMessage(data, 1, 2, xx);
57     assert (res == [0,0, 0,0, 0,6, 1, 2, 0,123,0,0]);
58 }