Skip to content

Commit bef6190

Browse files
committed
fix: 멀티쓰기모드 일 때 처리 수정
1 parent 8ac6cef commit bef6190

File tree

3 files changed

+62
-41
lines changed

3 files changed

+62
-41
lines changed

ModBusSimulatorSlave/Data/RequestPacket.cs

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class RequestPacket
77
private byte _functionCode;
88
private byte[] _data;
99
private byte _byteCount;
10-
private byte[] _writeData;
10+
private byte[] _multiWirteData;
1111
private byte[] _crc;
1212

1313
private RequestPacket(byte slaveAddr, byte functionCode, byte[] data)
@@ -22,13 +22,21 @@ private RequestPacket(byte slaveAddr, byte functionCode, byte[] data)
2222
}
2323

2424
// 멀티 코일 & 레지스터 쓰기를 위한 생성자
25-
private RequestPacket(byte slaveAddr, byte functionCode, byte[] data, byte byteCnt, byte[] writeData)
25+
private RequestPacket(byte slaveAddr, byte functionCode, byte[] data, byte[] writeData)
2626
{
2727
_slaveAddr = slaveAddr;
2828
_functionCode = functionCode;
2929
_data = data;
30-
_byteCount = byteCnt;
31-
_writeData = writeData;
30+
31+
ushort quantity = (ushort)(data[2] << 8 | data[3] & 0xFF);
32+
33+
_byteCount = _functionCode switch
34+
{
35+
0x0F => (byte)(quantity / 8 + (quantity % 8 == 0 ? 0 : 1)),
36+
0x10 => (byte)(quantity * 2),
37+
_ => 0
38+
};
39+
_multiWirteData = writeData;
3240

3341
_frame = GetMultiWriteFrame();
3442
_crc = new byte[2];
@@ -39,15 +47,14 @@ private RequestPacket(byte slaveAddr, byte functionCode, byte[] data, byte byteC
3947
public RequestPacket(byte[] frame)
4048
{
4149
_frame = frame;
50+
// 멀티 코일 & 레지스터 쓰기
4251
if (frame[1] == 0x0F || frame[1] == 0x10)
4352
{
4453
_slaveAddr = frame[0];
4554
_functionCode = frame[1];
46-
_data = new byte[frame.Length - 7];
47-
Array.Copy(frame, 2, _data, 0, _data.Length);
48-
_byteCount = frame[frame.Length - 4];
49-
_writeData = new byte[frame.Length - 7 - 1];
50-
Array.Copy(frame, 3 + _data.Length, _writeData, 0, _writeData.Length);
55+
_data = frame.Skip(2).Take(4).ToArray();
56+
_byteCount = frame[6];
57+
_multiWirteData = frame.Skip(6).Take(_byteCount).ToArray();
5158
_crc = new byte[2];
5259
Array.Copy(frame, frame.Length - 2, _crc, 0, 2);
5360
}
@@ -79,14 +86,14 @@ private byte[] GetFrame()
7986

8087
private byte[] GetMultiWriteFrame()
8188
{
82-
byte[] frame = new byte[1 + 1 + _data.Length + 1 + _writeData.Length + 2]; // SlaveAddr + FunctionCode + Data + CRC
89+
byte[] frame = new byte[1 + 1 + _data.Length + 1 + _multiWirteData.Length + 2]; // SlaveAddr + FunctionCode + Data + CRC
8390

8491
frame[0] = _slaveAddr;
8592
frame[1] = _functionCode;
8693
Array.Copy(_data, 0, frame, 2, _data.Length);
8794

8895
frame[2 + _data.Length] = _byteCount;
89-
Array.Copy(_writeData, 0, frame, 3 + _data.Length, _writeData.Length);
96+
Array.Copy(_multiWirteData, 0, frame, 3 + _data.Length, _multiWirteData.Length);
9097

9198
ushort crc = PacketHelpers.CalcCRC(frame, 0, frame.Length - 2);
9299
frame[frame.Length - 2] = (byte)(crc & 0xFF);
@@ -120,6 +127,18 @@ public byte[] Data
120127
set { _data = value; }
121128
}
122129

130+
public byte ByteCount
131+
{
132+
get { return _byteCount; }
133+
set { _byteCount = value; }
134+
}
135+
136+
public byte[] MultiWriteData
137+
{
138+
get { return _multiWirteData; }
139+
set { _multiWirteData = value; }
140+
}
141+
123142
public byte[] Crc
124143
{
125144
get { return _crc; }
@@ -133,7 +152,7 @@ public class RequestPacketBuilder
133152
private byte _functionCode;
134153
private byte[] _data;
135154
private byte _byteCount;
136-
private byte[] _writeData;
155+
private byte[] _multiWriteData;
137156

138157
public RequestPacketBuilder SetSlaveAddr(byte slaveAddr)
139158
{
@@ -153,22 +172,16 @@ public RequestPacketBuilder SetData(byte[] data)
153172
return this;
154173
}
155174

156-
public RequestPacketBuilder SetByteCount(byte byteCount)
157-
{
158-
_byteCount = byteCount;
159-
return this;
160-
}
161-
162-
public RequestPacketBuilder SetWriteData(byte[] writeData)
175+
public RequestPacketBuilder SetWriteData(byte[] multiWriteData)
163176
{
164-
_writeData = writeData;
177+
_multiWriteData = multiWriteData;
165178
return this;
166179
}
167180

168181
public RequestPacket Build()
169182
{
170183
return _functionCode == 0x0F || _functionCode == 0x10 ?
171-
new RequestPacket(_slaveAddr, _functionCode, _data, _byteCount, _writeData) :
184+
new RequestPacket(_slaveAddr, _functionCode, _data, _multiWriteData) :
172185
new RequestPacket(_slaveAddr, _functionCode, _data);
173186
}
174187
}

ModBusSimulatorSlave/Data/ResponsePacket.cs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ class ResponsePacket
55
private byte[] _frame;
66
private byte _slaveAddr;
77
private byte _functionCode;
8-
private byte _dataLength;
8+
private byte _byteCount;
99
private byte[] _data;
1010
private byte[] _crc;
1111

1212
private ResponsePacket(byte slaveArr, byte functionCode, byte dataLength, byte[] data)
1313
{
1414
_slaveAddr = slaveArr;
1515
_functionCode = functionCode;
16-
_dataLength = dataLength;
16+
_byteCount = dataLength;
1717
_data = data;
1818

1919
_frame = GetReadFrame();
@@ -37,11 +37,19 @@ public ResponsePacket(byte[] frame)
3737
_frame = frame;
3838
_slaveAddr = frame[0];
3939
_functionCode = frame[1];
40-
_dataLength = frame[2];
41-
_data = new byte[_dataLength];
42-
Array.Copy(frame, 3, _data, 0, _dataLength);
40+
41+
if (_functionCode is 0x0F or 0x10)
42+
{
43+
_data = frame.Skip(2).Take(4).ToArray();
44+
_crc = frame.Skip(6).Take(2).ToArray();
45+
return;
46+
}
47+
48+
_byteCount = frame[2];
49+
_data = new byte[_byteCount];
50+
Array.Copy(frame, 3, _data, 0, _byteCount);
4351
_crc = new byte[2];
44-
Array.Copy(frame, 3 + _dataLength, _crc, 0, 2);
52+
Array.Copy(frame, 3 + _byteCount, _crc, 0, 2);
4553
}
4654

4755
private byte[] GetReadFrame()
@@ -51,7 +59,7 @@ private byte[] GetReadFrame()
5159

5260
frame[0] = _slaveAddr;
5361
frame[1] = _functionCode;
54-
frame[2] = _dataLength;
62+
frame[2] = _byteCount;
5563
Array.Copy(_data, 0, frame, 3, _data.Length);
5664

5765
ushort crc = PacketHelpers.CalcCRC(frame, 0, frame.Length - 2);
@@ -93,10 +101,10 @@ public byte FunctionCode
93101
set { _functionCode = value; }
94102
}
95103

96-
public byte DataLength
104+
public byte ByteCount
97105
{
98-
get { return _dataLength; }
99-
set { _dataLength = value; }
106+
get { return _byteCount; }
107+
set { _byteCount = value; }
100108
}
101109

102110
public byte[] Data
@@ -115,7 +123,7 @@ public class ResponsePacketBuilder
115123
{
116124
private byte _slaveAddr;
117125
private byte _functionCode;
118-
private byte _dataLength;
126+
private byte _byteCount;
119127
private byte[] _data;
120128

121129
public ResponsePacketBuilder SetSlaveAddr(byte slaveAddr)
@@ -130,9 +138,9 @@ public ResponsePacketBuilder SetFunctionCode(byte functionCode)
130138
return this;
131139
}
132140

133-
public ResponsePacketBuilder SetDataLength(byte dataLength)
141+
public ResponsePacketBuilder SetByteCount(byte byteCount)
134142
{
135-
_dataLength = dataLength;
143+
_byteCount = byteCount;
136144
return this;
137145
}
138146

@@ -146,7 +154,7 @@ public ResponsePacket Build()
146154
{
147155
return _functionCode == 0x05 || _functionCode == 0x06 || _functionCode == 0x0F || _functionCode == 0x10 ?
148156
new ResponsePacket(_slaveAddr, _functionCode, _data) :
149-
new ResponsePacket(_slaveAddr, _functionCode, _dataLength, _data);
157+
new ResponsePacket(_slaveAddr, _functionCode, _byteCount, _data);
150158
}
151159
}
152160
}

ModBusSimulatorSlave/Service.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ private ResponsePacket ReadCoils(RequestPacket packet)
5454
return new ResponsePacket.ResponsePacketBuilder()
5555
.SetSlaveAddr(packet.SlaveAddr)
5656
.SetFunctionCode(packet.FunctionCode)
57-
.SetDataLength(byteCount)
57+
.SetByteCount(byteCount)
5858
.SetData(data)
5959
.Build();
6060
}
@@ -76,7 +76,7 @@ private ResponsePacket ReadDiscreteInputs(RequestPacket packet)
7676
return new ResponsePacket.ResponsePacketBuilder()
7777
.SetSlaveAddr(packet.SlaveAddr)
7878
.SetFunctionCode(packet.FunctionCode)
79-
.SetDataLength(byteCount)
79+
.SetByteCount(byteCount)
8080
.SetData(data)
8181
.Build();
8282
}
@@ -99,7 +99,7 @@ private ResponsePacket ReadHoldingRegisters(RequestPacket packet)
9999
return new ResponsePacket.ResponsePacketBuilder()
100100
.SetSlaveAddr(packet.SlaveAddr)
101101
.SetFunctionCode(packet.FunctionCode)
102-
.SetDataLength(byteCount)
102+
.SetByteCount(byteCount)
103103
.SetData(data)
104104
.Build();
105105
}
@@ -122,7 +122,7 @@ private ResponsePacket ReadInputRegisters(RequestPacket packet)
122122
return new ResponsePacket.ResponsePacketBuilder()
123123
.SetSlaveAddr(packet.SlaveAddr)
124124
.SetFunctionCode(packet.FunctionCode)
125-
.SetDataLength(byteCount)
125+
.SetByteCount(byteCount)
126126
.SetData(data)
127127
.Build();
128128
}
@@ -184,8 +184,8 @@ private ResponsePacket WriteMultipleRegisters(RequestPacket packet)
184184
ushort address = (ushort)((packet.Data[0] << 8) | packet.Data[1] & 0xFF);
185185
ushort quantity = (ushort)((packet.Data[2] << 8) | packet.Data[3] & 0xFF);
186186

187-
byte byteCount = packet.Data[4];
188-
byte[] writeData = packet.Data.Skip(5).ToArray();
187+
byte byteCount = packet.ByteCount;
188+
byte[] writeData = packet.MultiWriteData;
189189

190190
// 쓰기 데이터를 레지스터에 쓰기
191191
for (int i = 0; i < quantity; i++)

0 commit comments

Comments
 (0)