1 module simpletest;
2 
3 import base;
4 
5 enum MODEL_REG = 100;
6 
7 struct Model
8 {
9     int value;
10     int[18] arr;
11     bool d1, d2, d3;
12 }
13 
14 class FMaster : Fiber
15 {
16     Model model1, model2;
17 
18     ulong dev;
19     ModbusRTUMaster mb;
20 
21     this(ulong dev, string port, string mode)
22     {
23         this.dev = dev;
24         mb = new ModbusRTUMaster(port, mode);
25         super(&run);
26     }
27 
28     bool complite;
29 
30     void run()
31     {
32         // one big query
33         model1 = (cast(Model[])(mb.readInputRegisters(dev, MODEL_REG, Model.sizeof/2)))[0];
34 
35         // many query by one register
36         foreach (i; 0 .. Model.sizeof/2)
37             (cast(ushort[])((cast(void*)&model2)[0..Model.sizeof]))[i] =
38             (cast(ushort[])(mb.readInputRegisters(dev, cast(ushort)(MODEL_REG+i), ushort(1))))[0];
39 
40         complite = true;
41     }
42 }
43 
44 class FSlave : Fiber
45 {
46     Model model;
47 
48     ModbusRTUSlave mb;
49 
50     ushort[] table() @property
51     { return cast(ushort[])cast(void[])[model]; }
52 
53     this(ulong dev, string port, string mode)
54     {
55         mb = new ModbusRTUSlave(dev, port, mode);
56 
57         mb.func[ModbusRTUSlave.FuncCode.readInputRegisters] = (m)
58         {
59             auto ftus = mb.parseMessageFirstTwoUshorts(m);
60             auto start = ftus[0];
61             auto count = ftus[1];
62 
63             if (count == 0 || count > 125) return mb.illegalDataValue;
64             if (count > table.length) return mb.illegalDataValue;
65             if (start >= MODEL_REG + table.length || start < MODEL_REG)
66                 return mb.illegalDataAddress;
67 
68             return mb.packResult(cast(ubyte)(count*2),
69                     table[start-MODEL_REG..start-MODEL_REG+count]);
70         };
71 
72         model.value = cast(int)uniform(-100, 100);
73         foreach (i, ref v; model.arr)
74             v = cast(int)uniform(-200, 200);
75 
76         super(&run);
77     }
78 
79     void run()
80     {
81         while (1)
82         {
83             mb.iterate;
84             yield;
85         }
86     }
87 }
88 
89 void simpleTest(string[2] ports)
90 {
91     auto dev = 42;
92     auto mode = "9600:8N1";
93 
94     auto slave = new FSlave(dev, ports[0], mode);
95     auto master = new FMaster(dev, ports[1], mode);
96 
97     bool work = true;
98     size_t steps;
99 
100     while (work)
101     {
102         if (master.state != Fiber.State.TERM) master.call;
103         if (slave.state != Fiber.State.TERM) slave.call;
104 
105         Thread.sleep(1.msecs);
106 
107         steps++;
108         if (master.complite)
109         {
110             enforce(master.model1 == slave.model,
111                 format("diff models 1: \nm: %s \ns: %s", master.model1, slave.model));
112             enforce(master.model2 == slave.model,
113                 format("diff models 2: \nm: %s \ns: %s", master.model2, slave.model));
114 
115             work = false;
116             writeln("loop steps: ", steps);
117         }
118     }
119 }