Dreamine.PLC.Mitsubishi.MC 1.0.1
Dreamine.PLC.Mitsubishi.MC 산업 자동화 및 I/O 기능을 제공합니다.
로딩중...
검색중...
일치하는것 없음
MitsubishiMcBinary3EResponseParser.cs
이 파일의 문서화 페이지로 가기
1using Dreamine.PLC.Abstractions.Results;
2
4
14{
23 private const int MinimumResponseLength = 11;
24
48 public PlcResult<MitsubishiMcBinary3EResponse> Parse(ReadOnlySpan<byte> frame)
49 {
50 if (frame.Length < MinimumResponseLength)
51 {
52 return PlcResult<MitsubishiMcBinary3EResponse>.Failure(
53 $"The Mitsubishi MC response frame is too short. Length: {frame.Length}");
54 }
55
56 var subHeader = ReadUInt16LittleEndian(frame, 0);
57 if (subHeader != 0xD000)
58 {
59 return PlcResult<MitsubishiMcBinary3EResponse>.Failure(
60 $"Invalid Mitsubishi MC response sub-header: 0x{subHeader:X4}");
61 }
62
63 var responseDataLength = ReadUInt16LittleEndian(frame, 7);
64 var expectedFrameLength = 9 + responseDataLength;
65
66 if (frame.Length < expectedFrameLength)
67 {
68 return PlcResult<MitsubishiMcBinary3EResponse>.Failure(
69 $"The Mitsubishi MC response frame is incomplete. Expected: {expectedFrameLength}, Actual: {frame.Length}");
70 }
71
72 var endCode = ReadUInt16LittleEndian(frame, 9);
73 var dataLength = responseDataLength - 2;
74
75 var data = new byte[dataLength];
76 if (dataLength > 0)
77 {
78 frame.Slice(11, dataLength).CopyTo(data);
79 }
80
81 var response = new MitsubishiMcBinary3EResponse(endCode, data);
82
83 if (!response.IsSuccess)
84 {
85 return PlcResult<MitsubishiMcBinary3EResponse>.Failure(
86 $"Mitsubishi MC response returned error end code: 0x{endCode:X4}",
87 endCode);
88 }
89
90 return PlcResult<MitsubishiMcBinary3EResponse>.Success(response);
91 }
92
123 public PlcResult<short[]> ParseReadWords(ReadOnlySpan<byte> frame, int count)
124 {
125 if (count <= 0)
126 {
127 return PlcResult<short[]>.Failure("The word count must be greater than zero.");
128 }
129
130 var responseResult = Parse(frame);
131 if (!responseResult.IsSuccess || responseResult.Value is null)
132 {
133 return PlcResult<short[]>.Failure(
134 responseResult.Message ?? "Failed to parse Mitsubishi MC read word response.",
135 responseResult.ErrorCode);
136 }
137
138 var data = responseResult.Value.Data;
139 var expectedDataLength = count * 2;
140
141 if (data.Length < expectedDataLength)
142 {
143 return PlcResult<short[]>.Failure(
144 $"The Mitsubishi MC word response data is incomplete. Expected: {expectedDataLength}, Actual: {data.Length}");
145 }
146
147 var values = new short[count];
148
149 for (var i = 0; i < count; i++)
150 {
151 values[i] = unchecked((short)ReadUInt16LittleEndian(data, i * 2));
152 }
153
154 return PlcResult<short[]>.Success(values);
155 }
156
187 public PlcResult<bool[]> ParseReadBits(ReadOnlySpan<byte> frame, int count)
188 {
189 if (count <= 0)
190 {
191 return PlcResult<bool[]>.Failure("The bit count must be greater than zero.");
192 }
193
194 var responseResult = Parse(frame);
195 if (!responseResult.IsSuccess || responseResult.Value is null)
196 {
197 return PlcResult<bool[]>.Failure(
198 responseResult.Message ?? "Failed to parse Mitsubishi MC read bit response.",
199 responseResult.ErrorCode);
200 }
201
202 var data = responseResult.Value.Data;
203 var expectedDataLength = (count + 1) / 2;
204
205 if (data.Length < expectedDataLength)
206 {
207 return PlcResult<bool[]>.Failure(
208 $"The Mitsubishi MC bit response data is incomplete. Expected: {expectedDataLength}, Actual: {data.Length}");
209 }
210
211 var values = new bool[count];
212
213 for (var i = 0; i < count; i++)
214 {
215 var packed = data[i / 2];
216
217 values[i] = i % 2 == 0
218 ? (packed & 0x10) != 0
219 : (packed & 0x01) != 0;
220 }
221
222 return PlcResult<bool[]>.Success(values);
223 }
224
254 private static ushort ReadUInt16LittleEndian(ReadOnlySpan<byte> buffer, int offset)
255 {
256 return (ushort)(buffer[offset] | (buffer[offset + 1] << 8));
257 }
258}
PlcResult< MitsubishiMcBinary3EResponse > Parse(ReadOnlySpan< byte > frame)
PlcResult< short[]> ParseReadWords(ReadOnlySpan< byte > frame, int count)