GXDLMSClient.py:
Current code:
if not equals:
raise Exception(
"parseApplicationAssociationResponse failed. "
+ " Server to Client do not match."
)
Should be:
# In GXDLMSClient.py imports:
from .GXDLMSException import GXDLMSException
from .enums import AssociationResult # (add to existing 'from .enums import ...')
# In parseApplicationAssociationResponse():
if not equals:
raise GXDLMSException(
AssociationResult.PERMANENT_REJECTED,
SourceDiagnostic.AUTHENTICATION_FAILURE,
)
Reason:
When HLS authentication fails, parseApplicationAssociationResponse() raises a raw Python Exception instead of a typed GXDLMSException.
This causes several issues:
1. Dead code in GXDLMSReader.initializeConnection():
In GXDLMSReader.py, HLS authentication is wrapped in:
try:
for it in self.client.getApplicationAssociationRequest():
self.readDLMSPacket(it, reply)
self.client.parseApplicationAssociationResponse(reply.data)
except GXDLMSException as ex:
#Invalid password.
raise GXDLMSException(AssociationResult.PERMANENT_REJECTED, SourceDiagnostic.AUTHENTICATION_FAILURE)
Because parseApplicationAssociationResponse() raises a base Exception (which does not inherit from GXDLMSException), the except GXDLMSException handler is never reached.
2. Inconsistency between LLS and HLS:
For Low-Level Security (LLS), authentication failure in parseAareResponse() raises GXDLMSException with:
AssociationResult.PERMANENT_REJECTED
SourceDiagnostic.AUTHENTICATION_FAILURE
HLS authentication failure should produce the same typed exception with the corresponding association error and diagnostic values.
3. Broken error handling for client applications:
Callers cannot inspect structured error attributes (result, diagnostic, errorCode) and are forced to catch generic Exception and parse the error string.