Skip to content

Commit fe30516

Browse files
committed
Add packed struct decoding, shortened the string output of arrays
1 parent 01167f4 commit fe30516

File tree

2 files changed

+73
-39
lines changed

2 files changed

+73
-39
lines changed

src/S7CommPlusDriver/Core/PValue.cs

Lines changed: 67 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ public override string ToString()
336336
string s = "<Value type =\"USIntArray\" size=\"" + Value.Length.ToString() + "\">";
337337
for (int i = 0; i < Value.Length; i++)
338338
{
339-
s += String.Format("<Value index=\"{0}\">{1}</Value>", i, Value[i]);
339+
s += String.Format("<Value>{0}</Value>", Value[i]);
340340
}
341341
s += "</Value>";
342342
return s;
@@ -438,7 +438,7 @@ public override string ToString()
438438
string s = "<Value type =\"UIntArray\" size=\"" + Value.Length.ToString() + "\">";
439439
for (int i = 0; i < Value.Length; i++)
440440
{
441-
s += String.Format("<Value index=\"{0}\">{1}</Value>", i, Value[i]);
441+
s += String.Format("<Value>{0}</Value>", Value[i]);
442442
}
443443
s += "</Value>";
444444
return s;
@@ -540,7 +540,7 @@ public override string ToString()
540540
string s = "<Value type =\"UDIntArray\" size=\"" + Value.Length.ToString() + "\">";
541541
for (int i = 0; i < Value.Length; i++)
542542
{
543-
s += String.Format("<Value index=\"{0}\">{1}</Value>", i, Value[i]);
543+
s += String.Format("<Value>{0}</Value>", Value[i]);
544544
}
545545
s += "</Value>";
546546
return s;
@@ -709,7 +709,7 @@ public override string ToString()
709709
string s = "<Value type =\"ULIntArray\" size=\"" + Value.Length.ToString() + "\">";
710710
for (int i = 0; i < Value.Length; i++)
711711
{
712-
s += String.Format("<Value index=\"{0}\">{1}</Value>", i, Value[i]);
712+
s += String.Format("<Value>{0}</Value>", Value[i]);
713713
}
714714
s += "</Value>";
715715
return s;
@@ -811,7 +811,7 @@ public override string ToString()
811811
string s = "<Value type =\"SIntArray\" size=\"" + Value.Length.ToString() + "\">";
812812
for (int i = 0; i < Value.Length; i++)
813813
{
814-
s += String.Format("<Value index=\"{0}\">{1}</Value>", i, Value[i]);
814+
s += String.Format("<Value>{0}</Value>", Value[i]);
815815
}
816816
s += "</Value>";
817817
return s;
@@ -915,7 +915,7 @@ public override string ToString()
915915
string s = "<Value type =\"IntArray\" size=\"" + Value.Length.ToString() + "\">";
916916
for (int i = 0; i < Value.Length; i++)
917917
{
918-
s += String.Format("<Value index=\"{0}\">{1}</Value>", i, Value[i]);
918+
s += String.Format("<Value>{0}</Value>", Value[i]);
919919
}
920920
s += "</Value>";
921921
return s;
@@ -1017,7 +1017,7 @@ public override string ToString()
10171017
string s = "<Value type =\"DIntArray\" size=\"" + Value.Length.ToString() + "\">";
10181018
for (int i = 0; i < Value.Length; i++)
10191019
{
1020-
s += String.Format("<Value index=\"{0}\">{1}</Value>", i, Value[i]);
1020+
s += String.Format("<Value>{0}</Value>", Value[i]);
10211021
}
10221022
s += "</Value>";
10231023
return s;
@@ -1186,7 +1186,7 @@ public override string ToString()
11861186
string s = "<Value type =\"LIntArray\" size=\"" + Value.Length.ToString() + "\">";
11871187
for (int i = 0; i < Value.Length; i++)
11881188
{
1189-
s += String.Format("<Value index=\"{0}\">{1}</Value>", i, Value[i]);
1189+
s += String.Format("<Value>{0}</Value>", Value[i]);
11901190
}
11911191
s += "</Value>";
11921192
return s;
@@ -1236,7 +1236,7 @@ public override int Serialize(Stream buffer)
12361236

12371237
public override string ToString()
12381238
{
1239-
return String.Format("<Value type=\"Byte\">0x{0:X2}</Value>", Value);
1239+
return String.Format("<Value type=\"Byte\">{0}</Value>", Value);
12401240
}
12411241

12421242
public static ValueByte Deserialize(Stream buffer, byte flags)
@@ -1288,7 +1288,7 @@ public override string ToString()
12881288
string s = "<Value type =\"ByteArray\" size=\"" + Value.Length.ToString() + "\">";
12891289
for (int i = 0; i < Value.Length; i++)
12901290
{
1291-
s += String.Format("<Value index=\"{0}\">0x{1:X2}</Value>", i, Value[i]);
1291+
s += String.Format("<Value>{0}</Value>", Value[i]);
12921292
}
12931293
s += "</Value>";
12941294
return s;
@@ -1338,7 +1338,7 @@ public override int Serialize(Stream buffer)
13381338

13391339
public override string ToString()
13401340
{
1341-
return String.Format("<Value type=\"Word\">0x{0:X4}</Value>", Value);
1341+
return String.Format("<Value type=\"Word\">{0}</Value>", Value);
13421342
}
13431343

13441344
public static ValueWord Deserialize(Stream buffer, byte flags)
@@ -1390,7 +1390,7 @@ public override string ToString()
13901390
string s = "<Value type =\"WordArray\" size=\"" + Value.Length.ToString() + "\">";
13911391
for (int i = 0; i < Value.Length; i++)
13921392
{
1393-
s += String.Format("<Value index=\"{0}\">0x{1:X4}</Value>", i, Value[i]);
1393+
s += String.Format("<Value>{0}</Value>", Value[i]);
13941394
}
13951395
s += "</Value>";
13961396
return s;
@@ -1440,7 +1440,7 @@ public override int Serialize(Stream buffer)
14401440

14411441
public override string ToString()
14421442
{
1443-
return String.Format("<Value type=\"DWord\">0x{0:X8}</Value>", Value);
1443+
return String.Format("<Value type=\"DWord\">{0}</Value>", Value);
14441444
}
14451445

14461446
public static ValueDWord Deserialize(Stream buffer, byte flags)
@@ -1492,7 +1492,7 @@ public override string ToString()
14921492
string s = "<Value type =\"DWordArray\" size=\"" + Value.Length.ToString() + "\">";
14931493
for (int i = 0; i < Value.Length; i++)
14941494
{
1495-
s += String.Format("<Value index=\"{0}\">0x{1:X8}</Value>", i, Value[i]);
1495+
s += String.Format("<Value>{0}</Value>", Value[i]);
14961496
}
14971497
s += "</Value>";
14981498
return s;
@@ -1542,7 +1542,7 @@ public override int Serialize(Stream buffer)
15421542

15431543
public override string ToString()
15441544
{
1545-
return String.Format("<Value type=\"LWord\">0x{0:X16}</Value>", Value);
1545+
return String.Format("<Value type=\"LWord\">{0}</Value>", Value);
15461546
}
15471547

15481548
public static ValueLWord Deserialize(Stream buffer, byte flags)
@@ -1594,7 +1594,7 @@ public override string ToString()
15941594
string s = "<Value type =\"LWordArray\" size=\"" + Value.Length.ToString() + "\">";
15951595
for (int i = 0; i < Value.Length; i++)
15961596
{
1597-
s += String.Format("<Value index=\"{0}\">0x{1:X16}</Value>", i, Value[i]);
1597+
s += String.Format("<Value>{0}</Value>", Value[i]);
15981598
}
15991599
s += "</Value>";
16001600
return s;
@@ -1696,7 +1696,7 @@ public override string ToString()
16961696
string s = "<Value type =\"RealArray\" size=\"" + Value.Length.ToString() + "\">";
16971697
for (int i = 0; i < Value.Length; i++)
16981698
{
1699-
s += String.Format("<Value index=\"{0}\">{1}</Value>", i, Value[i]);
1699+
s += String.Format("<Value>{0}</Value>", Value[i]);
17001700
}
17011701
s += "</Value>";
17021702
return s;
@@ -1798,7 +1798,7 @@ public override string ToString()
17981798
string s = "<Value type =\"LRealArray\" size=\"" + Value.Length.ToString() + "\">";
17991799
for (int i = 0; i < Value.Length; i++)
18001800
{
1801-
s += String.Format("<Value index=\"{0}\">{1}</Value>", i, Value[i]);
1801+
s += String.Format("<Value>{0}</Value>", Value[i]);
18021802
}
18031803
s += "</Value>";
18041804
return s;
@@ -1892,7 +1892,6 @@ public override int Serialize(Stream buffer)
18921892
public override string ToString()
18931893
{
18941894
string str;
1895-
string sval;
18961895
long[] divs = { 86400000000000, 3600000000000, 60000000000, 1000000000, 1000000, 1000, 1 };
18971896
string[] vfmt = { "{0}d", "{0:00}h", "{0:00}m", "{0:00}s", "{0:000}ms", "{0:000}us", "{0:000}ns" };
18981897
long val;
@@ -1920,16 +1919,15 @@ public override string ToString()
19201919
timespan -= val * divs[i];
19211920
if (val > 0)
19221921
{
1923-
sval = String.Format(vfmt[i], (Int32)val);
1924-
str = str + sval;
1922+
str += String.Format(vfmt[i], (Int32)val);
19251923
if (timespan > 0)
19261924
{
1927-
str = str + "_";
1925+
str += "_";
19281926
}
19291927
}
19301928
}
19311929
}
1932-
return ("<Value type=\"Timestamp\">" + str + "</Value>");
1930+
return ("<Value type=\"Timespan\">" + str + "</Value>");
19331931
}
19341932

19351933
public static ValueTimespan Deserialize(Stream buffer, byte flags)
@@ -2022,7 +2020,7 @@ public override string ToString()
20222020
string s = "<Value type =\"RIDArray\" size=\"" + Value.Length.ToString() + "\">";
20232021
for (int i = 0; i < Value.Length; i++)
20242022
{
2025-
s += String.Format("<Value index=\"{0}\">0x{1}</Value>", i, Value[i]);
2023+
s += String.Format("<Value>{0}</Value>", Value[i]);
20262024
}
20272025
s += "</Value>";
20282026
return s;
@@ -2124,7 +2122,7 @@ public override string ToString()
21242122
string s = "<Value type =\"AIDArray\" size=\"" + Value.Length.ToString() + "\">";
21252123
for (int i = 0; i < Value.Length; i++)
21262124
{
2127-
s += String.Format("<Value index=\"{0}\">{1}</Value>", i, Value[i]);
2125+
s += String.Format("<Value>{0}</Value>", Value[i]);
21282126
}
21292127
s += "</Value>";
21302128
return s;
@@ -2368,7 +2366,7 @@ public override string ToString()
23682366
string s = "<Value type =\"WStringArray\" size=\"" + Value.Length.ToString() + "\">";
23692367
for (int i = 0; i < Value.Length; i++)
23702368
{
2371-
s += String.Format("<Value index=\"{0}\">{1}</Value>", i, Value[i]);
2369+
s += String.Format("<Value>{0}</Value>", Value[i]);
23722370
}
23732371
s += "</Value>";
23742372
return s;
@@ -2526,19 +2524,54 @@ public override string ToString()
25262524
public static ValueStruct Deserialize(System.IO.Stream buffer, byte flags)
25272525
{
25282526
UInt32 value;
2529-
PValue elem;
2527+
ValueStruct stru;
2528+
25302529
S7p.DecodeUInt32(buffer, out value);
2531-
ValueStruct stru = new ValueStruct(value);
2532-
S7p.DecodeUInt32Vlq(buffer, out value);
2533-
while (value > 0)
2534-
{
2535-
elem = PValue.Deserialize(buffer);
2530+
// Special handling of datatype struct and some specific ID ranges:
2531+
// Some struct elements aren't transmitted as single elements. Instead they are packed (e.g. DTL-Struct).
2532+
// The ID number range where this is used is only guessed (Type Info).
2533+
if ((value > 0x90000000 && value < 0x9fffffff) || (value > 0x02000000 && value < 0x02ffffff))
2534+
{
2535+
// Packed Struct
2536+
// TODO:
2537+
// Es handelt sich hierbei um System-Datentypen. Entweder es muss der Aufbau online aus der CPU angefragt werden,
2538+
// oder vorher bekannt sein. Erkennung ist anhand value des ValueStruct möglich.
2539+
// Daten vorerst hier als Bytearray abglegen, so werden sie auch übertragen. Interpretation bei Bedarf später.
2540+
stru = new ValueStruct(value);
2541+
2542+
UInt64 interfaceTimestamp;
2543+
S7p.DecodeUInt64(buffer, out interfaceTimestamp);
2544+
UInt32 transp_flags;
2545+
S7p.DecodeUInt32Vlq(buffer, out transp_flags);
2546+
UInt32 elementcount;
2547+
S7p.DecodeUInt32Vlq(buffer, out elementcount);
2548+
if ((transp_flags & 0x400) != 0)
2549+
{
2550+
// Hier gibt es eine zusätzliche Zählung, warum auch immer...
2551+
S7p.DecodeUInt32Vlq(buffer, out elementcount);
2552+
}
2553+
2554+
byte[] barr = new byte[elementcount];
2555+
for (int i = 0; i < elementcount; i++)
2556+
{
2557+
S7p.DecodeByte(buffer, out barr[i]);
2558+
}
2559+
ValueByteArray elem = new ValueByteArray(barr);
25362560
stru.AddStructElement(value, elem);
2561+
}
2562+
else
2563+
{
2564+
PValue elem;
2565+
stru = new ValueStruct(value);
25372566
S7p.DecodeUInt32Vlq(buffer, out value);
2567+
while (value > 0)
2568+
{
2569+
elem = PValue.Deserialize(buffer);
2570+
stru.AddStructElement(value, elem);
2571+
S7p.DecodeUInt32Vlq(buffer, out value);
2572+
}
25382573
}
25392574
return stru;
25402575
}
25412576
}
2542-
2543-
// TODO: S7String
25442577
}

src/S7CommPlusDriver/S7CommPlusConnection.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -333,13 +333,14 @@ private int checkResponseWithIntegrity(object responseObject, UInt16 requestSequ
333333
}
334334
if (requestSequenceNumber != responseSequenceNumber)
335335
{
336-
Console.WriteLine("checkResponseWithIntegrity: FEHLER! SeqenceNumber von Response passt nicht zum Request!");
336+
Console.WriteLine(String.Format("checkResponseWithIntegrity: FEHLER! SeqenceNumber von Response ({0}) passt nicht zum Request ({1})", responseSequenceNumber, requestSequenceNumber));
337337
return S7Consts.errIsoInvalidPDU;
338338
}
339339
// Hier kann ein Overflow vorkommen, ist aber erlaubt und Ergebnis wird akzeptiert.
340-
if (responseIntegrity != (UInt32)requestSequenceNumber + requestIntegrity)
341-
{
342-
Console.WriteLine("checkResponseWithIntegrity: FEHLER! Integrity der Response passt nicht zum Request");
340+
UInt32 reqIntegCheck = (UInt32)requestSequenceNumber + requestIntegrity;
341+
if (responseIntegrity != reqIntegCheck)
342+
{
343+
Console.WriteLine(String.Format("checkResponseWithIntegrity: FEHLER! Integrity der Response ({0}) passt nicht zum Request ({1})", responseIntegrity, reqIntegCheck));
343344
// Vorerst nicht als Fehler zurückgeben
344345
}
345346
return 0;
@@ -354,7 +355,7 @@ private int checkResponse(object responseObject, ushort requestSequenceNumber, u
354355
}
355356
if (requestSequenceNumber != responseSequenceNumber)
356357
{
357-
Console.WriteLine("checkResponse: FEHLER! SeqenceNumber von Response passt nicht zum Request!");
358+
Console.WriteLine(String.Format("checkResponse: FEHLER! SeqenceNumber von Response ({0}) passt nicht zum Request ({1})", responseSequenceNumber, requestSequenceNumber));
358359
return S7Consts.errIsoInvalidPDU;
359360
}
360361
return 0;

0 commit comments

Comments
 (0)