@@ -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