Skip to content

Commit 676c95a

Browse files
committed
Use DeleteObject for the session-id before disconnect the socket.
Before disconnecting, the object for the session-id should be deleted. Also save the 2nd session-id we get at the connection setup, for further usage (e.g. alarms, subscriptions). The DeleteObject response has no integrity-id in the response, if we delete our own session. It gives a warning (I suspect) in the return value, but no fatal error.
1 parent 9b8d996 commit 676c95a

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

src/S7CommPlusDriver/Core/DeleteObjectRequest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class DeleteObjectRequest : IS7pRequest
3333
public DeleteObjectRequest(byte protocolVersion)
3434
{
3535
ProtocolVersion = protocolVersion;
36+
WithIntegrityId = true;
3637
}
3738

3839
public byte GetProtocolVersion()

src/S7CommPlusDriver/S7CommPlusConnection.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ public partial class S7CommPlusConnection
3030
private bool m_ReceivedNeedMorePdus;
3131
private bool m_NewS7CommPlusReceived;
3232
private UInt32 m_SessionId;
33+
private UInt32 m_SessionId2;
34+
public UInt32 SessionId2
35+
{
36+
get { return m_SessionId2; }
37+
private set { m_SessionId2 = value; }
38+
}
39+
3340
private int m_ReadTimeout = 5000;
3441
private UInt16 m_SequenceNumber = 0;
3542
private UInt32 m_IntegrityId = 0;
@@ -72,6 +79,7 @@ private UInt32 GetNextIntegrityId(ushort functioncode)
7279
case Functioncode.SetMultiVariables:
7380
case Functioncode.SetVariable:
7481
case Functioncode.SetVarSubStreamed:
82+
case Functioncode.DeleteObject:
7583
if (m_IntegrityId_Set == UInt32.MaxValue)
7684
{
7785
m_IntegrityId_Set = 0;
@@ -450,7 +458,10 @@ public int Connect(string address)
450458
m_client.Disconnect();
451459
return S7Consts.errIsoInvalidPDU;
452460
}
461+
// There are (always?) at least two IDs in the response.
462+
// Usually the first is used for polling data, and the 2nd for jobs which use notifications, e.g. alarming, subscriptions.
453463
m_SessionId = createObjectResponse.ObjectIds[0];
464+
m_SessionId2 = createObjectResponse.ObjectIds[1];
454465
Console.WriteLine("S7CommPlusConnection - Connect: Using SessionId=0x" + String.Format("{0:X04}", m_SessionId));
455466

456467
// Evaluate Struct 314
@@ -504,9 +515,54 @@ public int Connect(string address)
504515

505516
public void Disconnect()
506517
{
518+
DeleteObject(m_SessionId);
507519
m_client.Disconnect();
508520
}
509521

522+
/// <summary>
523+
/// Deletes the object with the given Id.
524+
/// </summary>
525+
/// <param name="deleteObjectId">The object Id to delete</param>
526+
/// <returns>0 on success</returns>
527+
private int DeleteObject(uint deleteObjectId)
528+
{
529+
int res;
530+
var delReq = new DeleteObjectRequest(ProtocolVersion.V2);
531+
delReq.DeleteObjectId = deleteObjectId;
532+
res = SendS7plusFunctionObject(delReq);
533+
m_LastError = 0;
534+
WaitForNewS7plusReceived(m_ReadTimeout);
535+
if (m_LastError != 0)
536+
{
537+
return m_LastError;
538+
}
539+
// If we delete our own session id, then there's no IntegrityId in the response.
540+
// And the error code gives an error, but not a fatal one.
541+
// If we delete another object, there should be an IntegrityId in the response, and
542+
// the response gives no error.
543+
var delRes = DeleteObjectResponse.DeserializeFromPdu(m_ReceivedStream);
544+
if (deleteObjectId == m_SessionId)
545+
{
546+
Console.WriteLine("S7CommPlusConnection - DeleteSession: Deleted our own Session Id object, not checking the response.");
547+
m_SessionId = 0; // not valid anymore
548+
m_SessionId2 = 0;
549+
}
550+
else
551+
{
552+
res = checkResponseWithIntegrity(delReq, delRes);
553+
if (res != 0)
554+
{
555+
return res;
556+
}
557+
if (delRes.ReturnValue != 0)
558+
{
559+
Console.WriteLine("S7CommPlusConnection - DeleteSession: Executed with Error! ReturnValue=" + delRes.ReturnValue);
560+
res = -1;
561+
}
562+
}
563+
return res;
564+
}
565+
510566
public int ReadValues(List<ItemAddress> addresslist, out List<object> values, out List<UInt64> errors)
511567
{
512568
// The requester must pass the internal type with the request, otherwise not all return values can be converted automatically.

0 commit comments

Comments
 (0)