Commit 3db3b0f6 authored by ORD's avatar ORD

Merge pull request #77 from huazh/master

performance enhancement 2
parents b98292a3 7a814487
......@@ -11,6 +11,14 @@ import opcua.uaprotocol as ua
import opcua.utils as utils
class CachedRequest(object):
def __init__(self, binary):
self.binary = binary
def to_binary(self):
return self.binary
class UASocketClient(object):
"""
handle socket connection and send ua messages
......@@ -44,11 +52,15 @@ class UASocketClient(object):
send request to server.
timeout is the timeout written in ua header
"""
# HACK to make sure we can convert our request to binary before increasing request counter etc ...
request.to_binary()
# END HACK
with self._lock:
request.RequestHeader = self._create_request_header(timeout)
try:
cachedreq = CachedRequest(request.to_binary())
except:
# reset reqeust handle if any error
# see self._create_request_header
self._request_handle -= 1
raise
hdr = ua.Header(ua.MessageType.SecureMessage, ua.ChunkType.Single, self._security_token.ChannelId)
symhdr = self._create_sym_algo_header()
seqhdr = self._create_sequence_header()
......@@ -56,7 +68,7 @@ class UASocketClient(object):
if callback:
future.add_done_callback(callback)
self._callbackmap[seqhdr.RequestId] = future
self._write_socket(hdr, symhdr, seqhdr, request)
self._write_socket(hdr, symhdr, seqhdr, cachedreq)
if not callback:
data = future.result(self.timeout)
self.check_answer(data, " in response to " + request.__class__.__name__)
......
#AUTOGENERATED!!!
class StatusCodes:
class StatusCodes(object):
Good = 0
Uncertain = 0x40000000
Bad = 0x80000000
......@@ -234,466 +234,242 @@ class StatusCodes:
BadMaxConnectionsReached = 0x80B70000
code_to_name_doc = {
0: ('Good', 'The operation completed successfully.'),
0x40000000: ('Uncertain', 'The operation completed however its outputs may not be usable.'),
0x80000000: ('Bad', 'The operation failed.'),
0x80010000: ('BadUnexpectedError', 'An unexpected error occurred.'),
0x80020000: ('BadInternalError', 'An internal error occurred as a result of a programming or configuration error.'),
0x80030000: ('BadOutOfMemory', 'Not enough memory to complete the operation.'),
0x80040000: ('BadResourceUnavailable', 'An operating system resource is not available.'),
0x80050000: ('BadCommunicationError', 'A low level communication error occurred.'),
0x80060000: ('BadEncodingError', 'Encoding halted because of invalid data in the objects being serialized.'),
0x80070000: ('BadDecodingError', 'Decoding halted because of invalid data in the stream.'),
0x80080000: ('BadEncodingLimitsExceeded', 'The message encoding/decoding limits imposed by the stack have been exceeded.'),
0x80B80000: ('BadRequestTooLarge', 'The request message size exceeds limits set by the server.'),
0x80B90000: ('BadResponseTooLarge', 'The response message size exceeds limits set by the client.'),
0x80090000: ('BadUnknownResponse', 'An unrecognized response was received from the server.'),
0x800A0000: ('BadTimeout', 'The operation timed out.'),
0x800B0000: ('BadServiceUnsupported', 'The server does not support the requested service.'),
0x800C0000: ('BadShutdown', 'The operation was cancelled because the application is shutting down.'),
0x800D0000: ('BadServerNotConnected', 'The operation could not complete because the client is not connected to the server.'),
0x800E0000: ('BadServerHalted', 'The server has stopped and cannot process any requests.'),
0x800F0000: ('BadNothingToDo', 'There was nothing to do because the client passed a list of operations with no elements.'),
0x80100000: ('BadTooManyOperations', 'The request could not be processed because it specified too many operations.'),
0x80DB0000: ('BadTooManyMonitoredItems', 'The request could not be processed because there are too many monitored items in the subscription.'),
0x80110000: ('BadDataTypeIdUnknown', 'The extension object cannot be (de)serialized because the data type id is not recognized.'),
0x80120000: ('BadCertificateInvalid', 'The certificate provided as a parameter is not valid.'),
0x80130000: ('BadSecurityChecksFailed', 'An error occurred verifying security.'),
0x80140000: ('BadCertificateTimeInvalid', 'The Certificate has expired or is not yet valid.'),
0x80150000: ('BadCertificateIssuerTimeInvalid', 'An Issuer Certificate has expired or is not yet valid.'),
0x80160000: ('BadCertificateHostNameInvalid', 'The HostName used to connect to a Server does not match a HostName in the Certificate.'),
0x80170000: ('BadCertificateUriInvalid', 'The URI specified in the ApplicationDescription does not match the URI in the Certificate.'),
0x80180000: ('BadCertificateUseNotAllowed', 'The Certificate may not be used for the requested operation.'),
0x80190000: ('BadCertificateIssuerUseNotAllowed', 'The Issuer Certificate may not be used for the requested operation.'),
0x801A0000: ('BadCertificateUntrusted', 'The Certificate is not trusted.'),
0x801B0000: ('BadCertificateRevocationUnknown', 'It was not possible to determine if the Certificate has been revoked.'),
0x801C0000: ('BadCertificateIssuerRevocationUnknown', 'It was not possible to determine if the Issuer Certificate has been revoked.'),
0x801D0000: ('BadCertificateRevoked', 'The certificate has been revoked.'),
0x801E0000: ('BadCertificateIssuerRevoked', 'The issuer certificate has been revoked.'),
0x810D0000: ('BadCertificateChainIncomplete', 'The certificate chain is incomplete.'),
0x801F0000: ('BadUserAccessDenied', 'User does not have permission to perform the requested operation.'),
0x80200000: ('BadIdentityTokenInvalid', 'The user identity token is not valid.'),
0x80210000: ('BadIdentityTokenRejected', 'The user identity token is valid but the server has rejected it.'),
0x80220000: ('BadSecureChannelIdInvalid', 'The specified secure channel is no longer valid.'),
0x80230000: ('BadInvalidTimestamp', 'The timestamp is outside the range allowed by the server.'),
0x80240000: ('BadNonceInvalid', 'The nonce does appear to be not a random value or it is not the correct length.'),
0x80250000: ('BadSessionIdInvalid', 'The session id is not valid.'),
0x80260000: ('BadSessionClosed', 'The session was closed by the client.'),
0x80270000: ('BadSessionNotActivated', 'The session cannot be used because ActivateSession has not been called.'),
0x80280000: ('BadSubscriptionIdInvalid', 'The subscription id is not valid.'),
0x802A0000: ('BadRequestHeaderInvalid', 'The header for the request is missing or invalid.'),
0x802B0000: ('BadTimestampsToReturnInvalid', 'The timestamps to return parameter is invalid.'),
0x802C0000: ('BadRequestCancelledByClient', 'The request was cancelled by the client.'),
0x80E50000: ('BadTooManyArguments', 'Too many arguments were provided.'),
0x002D0000: ('GoodSubscriptionTransferred', 'The subscription was transferred to another session.'),
0x002E0000: ('GoodCompletesAsynchronously', 'The processing will complete asynchronously.'),
0x002F0000: ('GoodOverload', 'Sampling has slowed down due to resource limitations.'),
0x00300000: ('GoodClamped', 'The value written was accepted but was clamped.'),
0x80310000: ('BadNoCommunication', 'Communication with the data source is defined, but not established, and there is no last known value available.'),
0x80320000: ('BadWaitingForInitialData', 'Waiting for the server to obtain values from the underlying data source.'),
0x80330000: ('BadNodeIdInvalid', 'The syntax of the node id is not valid.'),
0x80340000: ('BadNodeIdUnknown', 'The node id refers to a node that does not exist in the server address space.'),
0x80350000: ('BadAttributeIdInvalid', 'The attribute is not supported for the specified Node.'),
0x80360000: ('BadIndexRangeInvalid', 'The syntax of the index range parameter is invalid.'),
0x80370000: ('BadIndexRangeNoData', 'No data exists within the range of indexes specified.'),
0x80380000: ('BadDataEncodingInvalid', 'The data encoding is invalid.'),
0x80390000: ('BadDataEncodingUnsupported', 'The server does not support the requested data encoding for the node.'),
0x803A0000: ('BadNotReadable', 'The access level does not allow reading or subscribing to the Node.'),
0x803B0000: ('BadNotWritable', 'The access level does not allow writing to the Node.'),
0x803C0000: ('BadOutOfRange', 'The value was out of range.'),
0x803D0000: ('BadNotSupported', 'The requested operation is not supported.'),
0x803E0000: ('BadNotFound', 'A requested item was not found or a search operation ended without success.'),
0x803F0000: ('BadObjectDeleted', 'The object cannot be used because it has been deleted.'),
0x80400000: ('BadNotImplemented', 'Requested operation is not implemented.'),
0x80410000: ('BadMonitoringModeInvalid', 'The monitoring mode is invalid.'),
0x80420000: ('BadMonitoredItemIdInvalid', 'The monitoring item id does not refer to a valid monitored item.'),
0x80430000: ('BadMonitoredItemFilterInvalid', 'The monitored item filter parameter is not valid.'),
0x80440000: ('BadMonitoredItemFilterUnsupported', 'The server does not support the requested monitored item filter.'),
0x80450000: ('BadFilterNotAllowed', 'A monitoring filter cannot be used in combination with the attribute specified.'),
0x80460000: ('BadStructureMissing', 'A mandatory structured parameter was missing or null.'),
0x80470000: ('BadEventFilterInvalid', 'The event filter is not valid.'),
0x80480000: ('BadContentFilterInvalid', 'The content filter is not valid.'),
0x80C10000: ('BadFilterOperatorInvalid', 'An unregognized operator was provided in a filter.'),
0x80C20000: ('BadFilterOperatorUnsupported', 'A valid operator was provided, but the server does not provide support for this filter operator.'),
0x80C30000: ('BadFilterOperandCountMismatch', 'The number of operands provided for the filter operator was less then expected for the operand provided.'),
0x80490000: ('BadFilterOperandInvalid', 'The operand used in a content filter is not valid.'),
0x80C40000: ('BadFilterElementInvalid', 'The referenced element is not a valid element in the content filter.'),
0x80C50000: ('BadFilterLiteralInvalid', 'The referenced literal is not a valid value.'),
0x804A0000: ('BadContinuationPointInvalid', 'The continuation point provide is longer valid.'),
0x804B0000: ('BadNoContinuationPoints', 'The operation could not be processed because all continuation points have been allocated.'),
0x804C0000: ('BadReferenceTypeIdInvalid', 'The operation could not be processed because all continuation points have been allocated.'),
0x804D0000: ('BadBrowseDirectionInvalid', 'The browse direction is not valid.'),
0x804E0000: ('BadNodeNotInView', 'The node is not part of the view.'),
0x804F0000: ('BadServerUriInvalid', 'The ServerUri is not a valid URI.'),
0x80500000: ('BadServerNameMissing', 'No ServerName was specified.'),
0x80510000: ('BadDiscoveryUrlMissing', 'No DiscoveryUrl was specified.'),
0x80520000: ('BadSempahoreFileMissing', 'The semaphore file specified by the client is not valid.'),
0x80530000: ('BadRequestTypeInvalid', 'The security token request type is not valid.'),
0x80540000: ('BadSecurityModeRejected', 'The security mode does not meet the requirements set by the Server.'),
0x80550000: ('BadSecurityPolicyRejected', 'The security policy does not meet the requirements set by the Server.'),
0x80560000: ('BadTooManySessions', 'The server has reached its maximum number of sessions.'),
0x80570000: ('BadUserSignatureInvalid', 'The user token signature is missing or invalid.'),
0x80580000: ('BadApplicationSignatureInvalid', 'The signature generated with the client certificate is missing or invalid.'),
0x80590000: ('BadNoValidCertificates', 'The client did not provide at least one software certificate that is valid and meets the profile requirements for the server.'),
0x80C60000: ('BadIdentityChangeNotSupported', 'The Server does not support changing the user identity assigned to the session.'),
0x805A0000: ('BadRequestCancelledByRequest', 'The request was cancelled by the client with the Cancel service.'),
0x805B0000: ('BadParentNodeIdInvalid', 'The parent node id does not to refer to a valid node.'),
0x805C0000: ('BadReferenceNotAllowed', 'The reference could not be created because it violates constraints imposed by the data model.'),
0x805D0000: ('BadNodeIdRejected', 'The requested node id was reject because it was either invalid or server does not allow node ids to be specified by the client.'),
0x805E0000: ('BadNodeIdExists', 'The requested node id is already used by another node.'),
0x805F0000: ('BadNodeClassInvalid', 'The node class is not valid.'),
0x80600000: ('BadBrowseNameInvalid', 'The browse name is invalid.'),
0x80610000: ('BadBrowseNameDuplicated', 'The browse name is not unique among nodes that share the same relationship with the parent.'),
0x80620000: ('BadNodeAttributesInvalid', 'The node attributes are not valid for the node class.'),
0x80630000: ('BadTypeDefinitionInvalid', 'The type definition node id does not reference an appropriate type node.'),
0x80640000: ('BadSourceNodeIdInvalid', 'The source node id does not reference a valid node.'),
0x80650000: ('BadTargetNodeIdInvalid', 'The target node id does not reference a valid node.'),
0x80660000: ('BadDuplicateReferenceNotAllowed', 'The reference type between the nodes is already defined.'),
0x80670000: ('BadInvalidSelfReference', 'The server does not allow this type of self reference on this node.'),
0x80680000: ('BadReferenceLocalOnly', 'The reference type is not valid for a reference to a remote server.'),
0x80690000: ('BadNoDeleteRights', 'The server will not allow the node to be deleted.'),
0x40BC0000: ('UncertainReferenceNotDeleted', 'The server was not able to delete all target references.'),
0x806A0000: ('BadServerIndexInvalid', 'The server index is not valid.'),
0x806B0000: ('BadViewIdUnknown', 'The view id does not refer to a valid view node.'),
0x80C90000: ('BadViewTimestampInvalid', 'The view timestamp is not available or not supported.'),
0x80CA0000: ('BadViewParameterMismatch', 'The view parameters are not consistent with each other.'),
0x80CB0000: ('BadViewVersionInvalid', 'The view version is not available or not supported.'),
0x40C00000: ('UncertainNotAllNodesAvailable', 'The list of references may not be complete because the underlying system is not available.'),
0x00BA0000: ('GoodResultsMayBeIncomplete', 'The server should have followed a reference to a node in a remote server but did not. The result set may be incomplete.'),
0x80C80000: ('BadNotTypeDefinition', 'The provided Nodeid was not a type definition nodeid.'),
0x406C0000: ('UncertainReferenceOutOfServer', 'One of the references to follow in the relative path references to a node in the address space in another server.'),
0x806D0000: ('BadTooManyMatches', 'The requested operation has too many matches to return.'),
0x806E0000: ('BadQueryTooComplex', 'The requested operation requires too many resources in the server.'),
0x806F0000: ('BadNoMatch', 'The requested operation has no match to return.'),
0x80700000: ('BadMaxAgeInvalid', 'The max age parameter is invalid.'),
0x80E60000: ('BadSecurityModeInsufficient', 'The operation is not permitted over the current secure channel.'),
0x80710000: ('BadHistoryOperationInvalid', 'The history details parameter is not valid.'),
0x80720000: ('BadHistoryOperationUnsupported', 'The server does not support the requested operation.'),
0x80BD0000: ('BadInvalidTimestampArgument', 'The defined timestamp to return was invalid.'),
0x80730000: ('BadWriteNotSupported', 'The server not does support writing the combination of value, status and timestamps provided.'),
0x80740000: ('BadTypeMismatch', 'The value supplied for the attribute is not of the same type as the attribute"s value.'),
0x80750000: ('BadMethodInvalid', 'The method id does not refer to a method for the specified object.'),
0x80760000: ('BadArgumentsMissing', 'The client did not specify all of the input arguments for the method.'),
0x80770000: ('BadTooManySubscriptions', 'The server has reached its maximum number of subscriptions.'),
0x80780000: ('BadTooManyPublishRequests', 'The server has reached the maximum number of queued publish requests.'),
0x80790000: ('BadNoSubscription', 'There is no subscription available for this session.'),
0x807A0000: ('BadSequenceNumberUnknown', 'The sequence number is unknown to the server.'),
0x807B0000: ('BadMessageNotAvailable', 'The requested notification message is no longer available.'),
0x807C0000: ('BadInsufficientClientProfile', 'The Client of the current Session does not support one or more Profiles that are necessary for the Subscription.'),
0x80BF0000: ('BadStateNotActive', 'The sub-state machine is not currently active.'),
0x807D0000: ('BadTcpServerTooBusy', 'The server cannot process the request because it is too busy.'),
0x807E0000: ('BadTcpMessageTypeInvalid', 'The type of the message specified in the header invalid.'),
0x807F0000: ('BadTcpSecureChannelUnknown', 'The SecureChannelId and/or TokenId are not currently in use.'),
0x80800000: ('BadTcpMessageTooLarge', 'The size of the message specified in the header is too large.'),
0x80810000: ('BadTcpNotEnoughResources', 'There are not enough resources to process the request.'),
0x80820000: ('BadTcpInternalError', 'An internal error occurred.'),
0x80830000: ('BadTcpEndpointUrlInvalid', 'The Server does not recognize the QueryString specified.'),
0x80840000: ('BadRequestInterrupted', 'The request could not be sent because of a network interruption.'),
0x80850000: ('BadRequestTimeout', 'Timeout occurred while processing the request.'),
0x80860000: ('BadSecureChannelClosed', 'The secure channel has been closed.'),
0x80870000: ('BadSecureChannelTokenUnknown', 'The token has expired or is not recognized.'),
0x80880000: ('BadSequenceNumberInvalid', 'The sequence number is not valid.'),
0x80BE0000: ('BadProtocolVersionUnsupported', 'The applications do not have compatible protocol versions.'),
0x80890000: ('BadConfigurationError', 'There is a problem with the configuration that affects the usefulness of the value.'),
0x808A0000: ('BadNotConnected', 'The variable should receive its value from another variable, but has never been configured to do so.'),
0x808B0000: ('BadDeviceFailure', 'There has been a failure in the device/data source that generates the value that has affected the value.'),
0x808C0000: ('BadSensorFailure', 'There has been a failure in the sensor from which the value is derived by the device/data source.'),
0x808D0000: ('BadOutOfService', 'The source of the data is not operational.'),
0x808E0000: ('BadDeadbandFilterInvalid', 'The deadband filter is not valid.'),
0x408F0000: ('UncertainNoCommunicationLastUsableValue', 'Communication to the data source has failed. The variable value is the last value that had a good quality.'),
0x40900000: ('UncertainLastUsableValue', 'Whatever was updating this value has stopped doing so.'),
0x40910000: ('UncertainSubstituteValue', 'The value is an operational value that was manually overwritten.'),
0x40920000: ('UncertainInitialValue', 'The value is an initial value for a variable that normally receives its value from another variable.'),
0x40930000: ('UncertainSensorNotAccurate', 'The value is at one of the sensor limits.'),
0x40940000: ('UncertainEngineeringUnitsExceeded', 'The value is outside of the range of values defined for this parameter.'),
0x40950000: ('UncertainSubNormal', 'The value is derived from multiple sources and has less than the required number of Good sources.'),
0x00960000: ('GoodLocalOverride', 'The value has been overridden.'),
0x80970000: ('BadRefreshInProgress', 'This Condition refresh failed, a Condition refresh operation is already in progress.'),
0x80980000: ('BadConditionAlreadyDisabled', 'This condition has already been disabled.'),
0x80CC0000: ('BadConditionAlreadyEnabled', 'This condition has already been enabled.'),
0x80990000: ('BadConditionDisabled', 'Property not available, this condition is disabled.'),
0x809A0000: ('BadEventIdUnknown', 'The specified event id is not recognized.'),
0x80BB0000: ('BadEventNotAcknowledgeable', 'The event cannot be acknowledged.'),
0x80CD0000: ('BadDialogNotActive', 'The dialog condition is not active.'),
0x80CE0000: ('BadDialogResponseInvalid', 'The response is not valid for the dialog.'),
0x80CF0000: ('BadConditionBranchAlreadyAcked', 'The condition branch has already been acknowledged.'),
0x80D00000: ('BadConditionBranchAlreadyConfirmed', 'The condition branch has already been confirmed.'),
0x80D10000: ('BadConditionAlreadyShelved', 'The condition has already been shelved.'),
0x80D20000: ('BadConditionNotShelved', 'The condition is not currently shelved.'),
0x80D30000: ('BadShelvingTimeOutOfRange', 'The shelving time not within an acceptable range.'),
0x809B0000: ('BadNoData', 'No data exists for the requested time range or event filter.'),
0x80D70000: ('BadBoundNotFound', 'No data found to provide upper or lower bound value.'),
0x80D80000: ('BadBoundNotSupported', 'The server cannot retrieve a bound for the variable.'),
0x809D0000: ('BadDataLost', 'Data is missing due to collection started/stopped/lost.'),
0x809E0000: ('BadDataUnavailable', 'Expected data is unavailable for the requested time range due to an un-mounted volume, an off-line archive or tape, or similar reason for temporary unavailability.'),
0x809F0000: ('BadEntryExists', 'The data or event was not successfully inserted because a matching entry exists.'),
0x80A00000: ('BadNoEntryExists', 'The data or event was not successfully updated because no matching entry exists.'),
0x80A10000: ('BadTimestampNotSupported', 'The client requested history using a timestamp format the server does not support (i.e requested ServerTimestamp when server only supports SourceTimestamp).'),
0x00A20000: ('GoodEntryInserted', 'The data or event was successfully inserted into the historical database.'),
0x00A30000: ('GoodEntryReplaced', 'The data or event field was successfully replaced in the historical database.'),
0x40A40000: ('UncertainDataSubNormal', 'The value is derived from multiple values and has less than the required number of Good values.'),
0x00A50000: ('GoodNoData', 'No data exists for the requested time range or event filter.'),
0x00A60000: ('GoodMoreData', 'The data or event field was successfully replaced in the historical database.'),
0x80D40000: ('BadAggregateListMismatch', 'The requested number of Aggregates does not match the requested number of NodeIds.'),
0x80D50000: ('BadAggregateNotSupported', 'The requested Aggregate is not support by the server.'),
0x80D60000: ('BadAggregateInvalidInputs', 'The aggregate value could not be derived due to invalid data inputs.'),
0x80DA0000: ('BadAggregateConfigurationRejected', 'The aggregate configuration is not valid for specified node.'),
0x00D90000: ('GoodDataIgnored', 'The request pecifies fields which are not valid for the EventType or cannot be saved by the historian.'),
0x80E40000: ('BadRequestNotAllowed', 'The request was rejected by the server because it did not meet the criteria set by the server.'),
0x00DC0000: ('GoodEdited', 'The value does not come from the real source and has been edited by the server.'),
0x00DD0000: ('GoodPostActionFailed', 'There was an error in execution of these post-actions.'),
0x40DE0000: ('UncertainDominantValueChanged', 'The related EngineeringUnit has been changed but the Variable Value is still provided based on the previous unit.'),
0x00E00000: ('GoodDependentValueChanged', 'A dependent value has been changed but the change has not been applied to the device.'),
0x80E10000: ('BadDominantValueChanged', 'The related EngineeringUnit has been changed but this change has not been applied to the device. The Variable Value is still dependent on the previous unit but its status is currently Bad.'),
0x40E20000: ('UncertainDependentValueChanged', 'A dependent value has been changed but the change has not been applied to the device. The quality of the dominant variable is uncertain.'),
0x80E30000: ('BadDependentValueChanged', 'A dependent value has been changed but the change has not been applied to the device. The quality of the dominant variable is Bad.'),
0x00A70000: ('GoodCommunicationEvent', 'The communication layer has raised an event.'),
0x00A80000: ('GoodShutdownEvent', 'The system is shutting down.'),
0x00A90000: ('GoodCallAgain', 'The operation is not finished and needs to be called again.'),
0x00AA0000: ('GoodNonCriticalTimeout', 'A non-critical timeout occurred.'),
0x80AB0000: ('BadInvalidArgument', 'One or more arguments are invalid.'),
0x80AC0000: ('BadConnectionRejected', 'Could not establish a network connection to remote server.'),
0x80AD0000: ('BadDisconnect', 'The server has disconnected from the client.'),
0x80AE0000: ('BadConnectionClosed', 'The network connection has been closed.'),
0x80AF0000: ('BadInvalidState', 'The operation cannot be completed because the object is closed, uninitialized or in some other invalid state.'),
0x80B00000: ('BadEndOfStream', 'Cannot move beyond end of the stream.'),
0x80B10000: ('BadNoDataAvailable', 'No data is currently available for reading from a non-blocking stream.'),
0x80B20000: ('BadWaitingForResponse', 'The asynchronous operation is waiting for a response.'),
0x80B30000: ('BadOperationAbandoned', 'The asynchronous operation was abandoned by the caller.'),
0x80B40000: ('BadExpectedStreamToBlock', 'The stream did not return all data requested (possibly because it is a non-blocking stream).'),
0x80B50000: ('BadWouldBlock', 'Non blocking behaviour is required and the operation would block.'),
0x80B60000: ('BadSyntaxError', 'A value had an invalid syntax.'),
0x80B70000: ('BadMaxConnectionsReached', 'The operation could not be finished because all available connections are in use.'),
}
def get_name_and_doc(val):
if val == 0:
return 'Good', 'The operation completed successfully.'
elif val == 0x40000000:
return 'Uncertain', 'The operation completed however its outputs may not be usable.'
elif val == 0x80000000:
return 'Bad', 'The operation failed.'
elif val == 0x80010000:
return 'BadUnexpectedError', 'An unexpected error occurred.'
elif val == 0x80020000:
return 'BadInternalError', 'An internal error occurred as a result of a programming or configuration error.'
elif val == 0x80030000:
return 'BadOutOfMemory', 'Not enough memory to complete the operation.'
elif val == 0x80040000:
return 'BadResourceUnavailable', 'An operating system resource is not available.'
elif val == 0x80050000:
return 'BadCommunicationError', 'A low level communication error occurred.'
elif val == 0x80060000:
return 'BadEncodingError', 'Encoding halted because of invalid data in the objects being serialized.'
elif val == 0x80070000:
return 'BadDecodingError', 'Decoding halted because of invalid data in the stream.'
elif val == 0x80080000:
return 'BadEncodingLimitsExceeded', 'The message encoding/decoding limits imposed by the stack have been exceeded.'
elif val == 0x80B80000:
return 'BadRequestTooLarge', 'The request message size exceeds limits set by the server.'
elif val == 0x80B90000:
return 'BadResponseTooLarge', 'The response message size exceeds limits set by the client.'
elif val == 0x80090000:
return 'BadUnknownResponse', 'An unrecognized response was received from the server.'
elif val == 0x800A0000:
return 'BadTimeout', 'The operation timed out.'
elif val == 0x800B0000:
return 'BadServiceUnsupported', 'The server does not support the requested service.'
elif val == 0x800C0000:
return 'BadShutdown', 'The operation was cancelled because the application is shutting down.'
elif val == 0x800D0000:
return 'BadServerNotConnected', 'The operation could not complete because the client is not connected to the server.'
elif val == 0x800E0000:
return 'BadServerHalted', 'The server has stopped and cannot process any requests.'
elif val == 0x800F0000:
return 'BadNothingToDo', 'There was nothing to do because the client passed a list of operations with no elements.'
elif val == 0x80100000:
return 'BadTooManyOperations', 'The request could not be processed because it specified too many operations.'
elif val == 0x80DB0000:
return 'BadTooManyMonitoredItems', 'The request could not be processed because there are too many monitored items in the subscription.'
elif val == 0x80110000:
return 'BadDataTypeIdUnknown', 'The extension object cannot be (de)serialized because the data type id is not recognized.'
elif val == 0x80120000:
return 'BadCertificateInvalid', 'The certificate provided as a parameter is not valid.'
elif val == 0x80130000:
return 'BadSecurityChecksFailed', 'An error occurred verifying security.'
elif val == 0x80140000:
return 'BadCertificateTimeInvalid', 'The Certificate has expired or is not yet valid.'
elif val == 0x80150000:
return 'BadCertificateIssuerTimeInvalid', 'An Issuer Certificate has expired or is not yet valid.'
elif val == 0x80160000:
return 'BadCertificateHostNameInvalid', 'The HostName used to connect to a Server does not match a HostName in the Certificate.'
elif val == 0x80170000:
return 'BadCertificateUriInvalid', 'The URI specified in the ApplicationDescription does not match the URI in the Certificate.'
elif val == 0x80180000:
return 'BadCertificateUseNotAllowed', 'The Certificate may not be used for the requested operation.'
elif val == 0x80190000:
return 'BadCertificateIssuerUseNotAllowed', 'The Issuer Certificate may not be used for the requested operation.'
elif val == 0x801A0000:
return 'BadCertificateUntrusted', 'The Certificate is not trusted.'
elif val == 0x801B0000:
return 'BadCertificateRevocationUnknown', 'It was not possible to determine if the Certificate has been revoked.'
elif val == 0x801C0000:
return 'BadCertificateIssuerRevocationUnknown', 'It was not possible to determine if the Issuer Certificate has been revoked.'
elif val == 0x801D0000:
return 'BadCertificateRevoked', 'The certificate has been revoked.'
elif val == 0x801E0000:
return 'BadCertificateIssuerRevoked', 'The issuer certificate has been revoked.'
elif val == 0x810D0000:
return 'BadCertificateChainIncomplete', 'The certificate chain is incomplete.'
elif val == 0x801F0000:
return 'BadUserAccessDenied', 'User does not have permission to perform the requested operation.'
elif val == 0x80200000:
return 'BadIdentityTokenInvalid', 'The user identity token is not valid.'
elif val == 0x80210000:
return 'BadIdentityTokenRejected', 'The user identity token is valid but the server has rejected it.'
elif val == 0x80220000:
return 'BadSecureChannelIdInvalid', 'The specified secure channel is no longer valid.'
elif val == 0x80230000:
return 'BadInvalidTimestamp', 'The timestamp is outside the range allowed by the server.'
elif val == 0x80240000:
return 'BadNonceInvalid', 'The nonce does appear to be not a random value or it is not the correct length.'
elif val == 0x80250000:
return 'BadSessionIdInvalid', 'The session id is not valid.'
elif val == 0x80260000:
return 'BadSessionClosed', 'The session was closed by the client.'
elif val == 0x80270000:
return 'BadSessionNotActivated', 'The session cannot be used because ActivateSession has not been called.'
elif val == 0x80280000:
return 'BadSubscriptionIdInvalid', 'The subscription id is not valid.'
elif val == 0x802A0000:
return 'BadRequestHeaderInvalid', 'The header for the request is missing or invalid.'
elif val == 0x802B0000:
return 'BadTimestampsToReturnInvalid', 'The timestamps to return parameter is invalid.'
elif val == 0x802C0000:
return 'BadRequestCancelledByClient', 'The request was cancelled by the client.'
elif val == 0x80E50000:
return 'BadTooManyArguments', 'Too many arguments were provided.'
elif val == 0x002D0000:
return 'GoodSubscriptionTransferred', 'The subscription was transferred to another session.'
elif val == 0x002E0000:
return 'GoodCompletesAsynchronously', 'The processing will complete asynchronously.'
elif val == 0x002F0000:
return 'GoodOverload', 'Sampling has slowed down due to resource limitations.'
elif val == 0x00300000:
return 'GoodClamped', 'The value written was accepted but was clamped.'
elif val == 0x80310000:
return 'BadNoCommunication', 'Communication with the data source is defined, but not established, and there is no last known value available.'
elif val == 0x80320000:
return 'BadWaitingForInitialData', 'Waiting for the server to obtain values from the underlying data source.'
elif val == 0x80330000:
return 'BadNodeIdInvalid', 'The syntax of the node id is not valid.'
elif val == 0x80340000:
return 'BadNodeIdUnknown', 'The node id refers to a node that does not exist in the server address space.'
elif val == 0x80350000:
return 'BadAttributeIdInvalid', 'The attribute is not supported for the specified Node.'
elif val == 0x80360000:
return 'BadIndexRangeInvalid', 'The syntax of the index range parameter is invalid.'
elif val == 0x80370000:
return 'BadIndexRangeNoData', 'No data exists within the range of indexes specified.'
elif val == 0x80380000:
return 'BadDataEncodingInvalid', 'The data encoding is invalid.'
elif val == 0x80390000:
return 'BadDataEncodingUnsupported', 'The server does not support the requested data encoding for the node.'
elif val == 0x803A0000:
return 'BadNotReadable', 'The access level does not allow reading or subscribing to the Node.'
elif val == 0x803B0000:
return 'BadNotWritable', 'The access level does not allow writing to the Node.'
elif val == 0x803C0000:
return 'BadOutOfRange', 'The value was out of range.'
elif val == 0x803D0000:
return 'BadNotSupported', 'The requested operation is not supported.'
elif val == 0x803E0000:
return 'BadNotFound', 'A requested item was not found or a search operation ended without success.'
elif val == 0x803F0000:
return 'BadObjectDeleted', 'The object cannot be used because it has been deleted.'
elif val == 0x80400000:
return 'BadNotImplemented', 'Requested operation is not implemented.'
elif val == 0x80410000:
return 'BadMonitoringModeInvalid', 'The monitoring mode is invalid.'
elif val == 0x80420000:
return 'BadMonitoredItemIdInvalid', 'The monitoring item id does not refer to a valid monitored item.'
elif val == 0x80430000:
return 'BadMonitoredItemFilterInvalid', 'The monitored item filter parameter is not valid.'
elif val == 0x80440000:
return 'BadMonitoredItemFilterUnsupported', 'The server does not support the requested monitored item filter.'
elif val == 0x80450000:
return 'BadFilterNotAllowed', 'A monitoring filter cannot be used in combination with the attribute specified.'
elif val == 0x80460000:
return 'BadStructureMissing', 'A mandatory structured parameter was missing or null.'
elif val == 0x80470000:
return 'BadEventFilterInvalid', 'The event filter is not valid.'
elif val == 0x80480000:
return 'BadContentFilterInvalid', 'The content filter is not valid.'
elif val == 0x80C10000:
return 'BadFilterOperatorInvalid', 'An unregognized operator was provided in a filter.'
elif val == 0x80C20000:
return 'BadFilterOperatorUnsupported', 'A valid operator was provided, but the server does not provide support for this filter operator.'
elif val == 0x80C30000:
return 'BadFilterOperandCountMismatch', 'The number of operands provided for the filter operator was less then expected for the operand provided.'
elif val == 0x80490000:
return 'BadFilterOperandInvalid', 'The operand used in a content filter is not valid.'
elif val == 0x80C40000:
return 'BadFilterElementInvalid', 'The referenced element is not a valid element in the content filter.'
elif val == 0x80C50000:
return 'BadFilterLiteralInvalid', 'The referenced literal is not a valid value.'
elif val == 0x804A0000:
return 'BadContinuationPointInvalid', 'The continuation point provide is longer valid.'
elif val == 0x804B0000:
return 'BadNoContinuationPoints', 'The operation could not be processed because all continuation points have been allocated.'
elif val == 0x804C0000:
return 'BadReferenceTypeIdInvalid', 'The operation could not be processed because all continuation points have been allocated.'
elif val == 0x804D0000:
return 'BadBrowseDirectionInvalid', 'The browse direction is not valid.'
elif val == 0x804E0000:
return 'BadNodeNotInView', 'The node is not part of the view.'
elif val == 0x804F0000:
return 'BadServerUriInvalid', 'The ServerUri is not a valid URI.'
elif val == 0x80500000:
return 'BadServerNameMissing', 'No ServerName was specified.'
elif val == 0x80510000:
return 'BadDiscoveryUrlMissing', 'No DiscoveryUrl was specified.'
elif val == 0x80520000:
return 'BadSempahoreFileMissing', 'The semaphore file specified by the client is not valid.'
elif val == 0x80530000:
return 'BadRequestTypeInvalid', 'The security token request type is not valid.'
elif val == 0x80540000:
return 'BadSecurityModeRejected', 'The security mode does not meet the requirements set by the Server.'
elif val == 0x80550000:
return 'BadSecurityPolicyRejected', 'The security policy does not meet the requirements set by the Server.'
elif val == 0x80560000:
return 'BadTooManySessions', 'The server has reached its maximum number of sessions.'
elif val == 0x80570000:
return 'BadUserSignatureInvalid', 'The user token signature is missing or invalid.'
elif val == 0x80580000:
return 'BadApplicationSignatureInvalid', 'The signature generated with the client certificate is missing or invalid.'
elif val == 0x80590000:
return 'BadNoValidCertificates', 'The client did not provide at least one software certificate that is valid and meets the profile requirements for the server.'
elif val == 0x80C60000:
return 'BadIdentityChangeNotSupported', 'The Server does not support changing the user identity assigned to the session.'
elif val == 0x805A0000:
return 'BadRequestCancelledByRequest', 'The request was cancelled by the client with the Cancel service.'
elif val == 0x805B0000:
return 'BadParentNodeIdInvalid', 'The parent node id does not to refer to a valid node.'
elif val == 0x805C0000:
return 'BadReferenceNotAllowed', 'The reference could not be created because it violates constraints imposed by the data model.'
elif val == 0x805D0000:
return 'BadNodeIdRejected', 'The requested node id was reject because it was either invalid or server does not allow node ids to be specified by the client.'
elif val == 0x805E0000:
return 'BadNodeIdExists', 'The requested node id is already used by another node.'
elif val == 0x805F0000:
return 'BadNodeClassInvalid', 'The node class is not valid.'
elif val == 0x80600000:
return 'BadBrowseNameInvalid', 'The browse name is invalid.'
elif val == 0x80610000:
return 'BadBrowseNameDuplicated', 'The browse name is not unique among nodes that share the same relationship with the parent.'
elif val == 0x80620000:
return 'BadNodeAttributesInvalid', 'The node attributes are not valid for the node class.'
elif val == 0x80630000:
return 'BadTypeDefinitionInvalid', 'The type definition node id does not reference an appropriate type node.'
elif val == 0x80640000:
return 'BadSourceNodeIdInvalid', 'The source node id does not reference a valid node.'
elif val == 0x80650000:
return 'BadTargetNodeIdInvalid', 'The target node id does not reference a valid node.'
elif val == 0x80660000:
return 'BadDuplicateReferenceNotAllowed', 'The reference type between the nodes is already defined.'
elif val == 0x80670000:
return 'BadInvalidSelfReference', 'The server does not allow this type of self reference on this node.'
elif val == 0x80680000:
return 'BadReferenceLocalOnly', 'The reference type is not valid for a reference to a remote server.'
elif val == 0x80690000:
return 'BadNoDeleteRights', 'The server will not allow the node to be deleted.'
elif val == 0x40BC0000:
return 'UncertainReferenceNotDeleted', 'The server was not able to delete all target references.'
elif val == 0x806A0000:
return 'BadServerIndexInvalid', 'The server index is not valid.'
elif val == 0x806B0000:
return 'BadViewIdUnknown', 'The view id does not refer to a valid view node.'
elif val == 0x80C90000:
return 'BadViewTimestampInvalid', 'The view timestamp is not available or not supported.'
elif val == 0x80CA0000:
return 'BadViewParameterMismatch', 'The view parameters are not consistent with each other.'
elif val == 0x80CB0000:
return 'BadViewVersionInvalid', 'The view version is not available or not supported.'
elif val == 0x40C00000:
return 'UncertainNotAllNodesAvailable', 'The list of references may not be complete because the underlying system is not available.'
elif val == 0x00BA0000:
return 'GoodResultsMayBeIncomplete', 'The server should have followed a reference to a node in a remote server but did not. The result set may be incomplete.'
elif val == 0x80C80000:
return 'BadNotTypeDefinition', 'The provided Nodeid was not a type definition nodeid.'
elif val == 0x406C0000:
return 'UncertainReferenceOutOfServer', 'One of the references to follow in the relative path references to a node in the address space in another server.'
elif val == 0x806D0000:
return 'BadTooManyMatches', 'The requested operation has too many matches to return.'
elif val == 0x806E0000:
return 'BadQueryTooComplex', 'The requested operation requires too many resources in the server.'
elif val == 0x806F0000:
return 'BadNoMatch', 'The requested operation has no match to return.'
elif val == 0x80700000:
return 'BadMaxAgeInvalid', 'The max age parameter is invalid.'
elif val == 0x80E60000:
return 'BadSecurityModeInsufficient', 'The operation is not permitted over the current secure channel.'
elif val == 0x80710000:
return 'BadHistoryOperationInvalid', 'The history details parameter is not valid.'
elif val == 0x80720000:
return 'BadHistoryOperationUnsupported', 'The server does not support the requested operation.'
elif val == 0x80BD0000:
return 'BadInvalidTimestampArgument', 'The defined timestamp to return was invalid.'
elif val == 0x80730000:
return 'BadWriteNotSupported', 'The server not does support writing the combination of value, status and timestamps provided.'
elif val == 0x80740000:
return 'BadTypeMismatch', 'The value supplied for the attribute is not of the same type as the attribute"s value.'
elif val == 0x80750000:
return 'BadMethodInvalid', 'The method id does not refer to a method for the specified object.'
elif val == 0x80760000:
return 'BadArgumentsMissing', 'The client did not specify all of the input arguments for the method.'
elif val == 0x80770000:
return 'BadTooManySubscriptions', 'The server has reached its maximum number of subscriptions.'
elif val == 0x80780000:
return 'BadTooManyPublishRequests', 'The server has reached the maximum number of queued publish requests.'
elif val == 0x80790000:
return 'BadNoSubscription', 'There is no subscription available for this session.'
elif val == 0x807A0000:
return 'BadSequenceNumberUnknown', 'The sequence number is unknown to the server.'
elif val == 0x807B0000:
return 'BadMessageNotAvailable', 'The requested notification message is no longer available.'
elif val == 0x807C0000:
return 'BadInsufficientClientProfile', 'The Client of the current Session does not support one or more Profiles that are necessary for the Subscription.'
elif val == 0x80BF0000:
return 'BadStateNotActive', 'The sub-state machine is not currently active.'
elif val == 0x807D0000:
return 'BadTcpServerTooBusy', 'The server cannot process the request because it is too busy.'
elif val == 0x807E0000:
return 'BadTcpMessageTypeInvalid', 'The type of the message specified in the header invalid.'
elif val == 0x807F0000:
return 'BadTcpSecureChannelUnknown', 'The SecureChannelId and/or TokenId are not currently in use.'
elif val == 0x80800000:
return 'BadTcpMessageTooLarge', 'The size of the message specified in the header is too large.'
elif val == 0x80810000:
return 'BadTcpNotEnoughResources', 'There are not enough resources to process the request.'
elif val == 0x80820000:
return 'BadTcpInternalError', 'An internal error occurred.'
elif val == 0x80830000:
return 'BadTcpEndpointUrlInvalid', 'The Server does not recognize the QueryString specified.'
elif val == 0x80840000:
return 'BadRequestInterrupted', 'The request could not be sent because of a network interruption.'
elif val == 0x80850000:
return 'BadRequestTimeout', 'Timeout occurred while processing the request.'
elif val == 0x80860000:
return 'BadSecureChannelClosed', 'The secure channel has been closed.'
elif val == 0x80870000:
return 'BadSecureChannelTokenUnknown', 'The token has expired or is not recognized.'
elif val == 0x80880000:
return 'BadSequenceNumberInvalid', 'The sequence number is not valid.'
elif val == 0x80BE0000:
return 'BadProtocolVersionUnsupported', 'The applications do not have compatible protocol versions.'
elif val == 0x80890000:
return 'BadConfigurationError', 'There is a problem with the configuration that affects the usefulness of the value.'
elif val == 0x808A0000:
return 'BadNotConnected', 'The variable should receive its value from another variable, but has never been configured to do so.'
elif val == 0x808B0000:
return 'BadDeviceFailure', 'There has been a failure in the device/data source that generates the value that has affected the value.'
elif val == 0x808C0000:
return 'BadSensorFailure', 'There has been a failure in the sensor from which the value is derived by the device/data source.'
elif val == 0x808D0000:
return 'BadOutOfService', 'The source of the data is not operational.'
elif val == 0x808E0000:
return 'BadDeadbandFilterInvalid', 'The deadband filter is not valid.'
elif val == 0x408F0000:
return 'UncertainNoCommunicationLastUsableValue', 'Communication to the data source has failed. The variable value is the last value that had a good quality.'
elif val == 0x40900000:
return 'UncertainLastUsableValue', 'Whatever was updating this value has stopped doing so.'
elif val == 0x40910000:
return 'UncertainSubstituteValue', 'The value is an operational value that was manually overwritten.'
elif val == 0x40920000:
return 'UncertainInitialValue', 'The value is an initial value for a variable that normally receives its value from another variable.'
elif val == 0x40930000:
return 'UncertainSensorNotAccurate', 'The value is at one of the sensor limits.'
elif val == 0x40940000:
return 'UncertainEngineeringUnitsExceeded', 'The value is outside of the range of values defined for this parameter.'
elif val == 0x40950000:
return 'UncertainSubNormal', 'The value is derived from multiple sources and has less than the required number of Good sources.'
elif val == 0x00960000:
return 'GoodLocalOverride', 'The value has been overridden.'
elif val == 0x80970000:
return 'BadRefreshInProgress', 'This Condition refresh failed, a Condition refresh operation is already in progress.'
elif val == 0x80980000:
return 'BadConditionAlreadyDisabled', 'This condition has already been disabled.'
elif val == 0x80CC0000:
return 'BadConditionAlreadyEnabled', 'This condition has already been enabled.'
elif val == 0x80990000:
return 'BadConditionDisabled', 'Property not available, this condition is disabled.'
elif val == 0x809A0000:
return 'BadEventIdUnknown', 'The specified event id is not recognized.'
elif val == 0x80BB0000:
return 'BadEventNotAcknowledgeable', 'The event cannot be acknowledged.'
elif val == 0x80CD0000:
return 'BadDialogNotActive', 'The dialog condition is not active.'
elif val == 0x80CE0000:
return 'BadDialogResponseInvalid', 'The response is not valid for the dialog.'
elif val == 0x80CF0000:
return 'BadConditionBranchAlreadyAcked', 'The condition branch has already been acknowledged.'
elif val == 0x80D00000:
return 'BadConditionBranchAlreadyConfirmed', 'The condition branch has already been confirmed.'
elif val == 0x80D10000:
return 'BadConditionAlreadyShelved', 'The condition has already been shelved.'
elif val == 0x80D20000:
return 'BadConditionNotShelved', 'The condition is not currently shelved.'
elif val == 0x80D30000:
return 'BadShelvingTimeOutOfRange', 'The shelving time not within an acceptable range.'
elif val == 0x809B0000:
return 'BadNoData', 'No data exists for the requested time range or event filter.'
elif val == 0x80D70000:
return 'BadBoundNotFound', 'No data found to provide upper or lower bound value.'
elif val == 0x80D80000:
return 'BadBoundNotSupported', 'The server cannot retrieve a bound for the variable.'
elif val == 0x809D0000:
return 'BadDataLost', 'Data is missing due to collection started/stopped/lost.'
elif val == 0x809E0000:
return 'BadDataUnavailable', 'Expected data is unavailable for the requested time range due to an un-mounted volume, an off-line archive or tape, or similar reason for temporary unavailability.'
elif val == 0x809F0000:
return 'BadEntryExists', 'The data or event was not successfully inserted because a matching entry exists.'
elif val == 0x80A00000:
return 'BadNoEntryExists', 'The data or event was not successfully updated because no matching entry exists.'
elif val == 0x80A10000:
return 'BadTimestampNotSupported', 'The client requested history using a timestamp format the server does not support (i.e requested ServerTimestamp when server only supports SourceTimestamp).'
elif val == 0x00A20000:
return 'GoodEntryInserted', 'The data or event was successfully inserted into the historical database.'
elif val == 0x00A30000:
return 'GoodEntryReplaced', 'The data or event field was successfully replaced in the historical database.'
elif val == 0x40A40000:
return 'UncertainDataSubNormal', 'The value is derived from multiple values and has less than the required number of Good values.'
elif val == 0x00A50000:
return 'GoodNoData', 'No data exists for the requested time range or event filter.'
elif val == 0x00A60000:
return 'GoodMoreData', 'The data or event field was successfully replaced in the historical database.'
elif val == 0x80D40000:
return 'BadAggregateListMismatch', 'The requested number of Aggregates does not match the requested number of NodeIds.'
elif val == 0x80D50000:
return 'BadAggregateNotSupported', 'The requested Aggregate is not support by the server.'
elif val == 0x80D60000:
return 'BadAggregateInvalidInputs', 'The aggregate value could not be derived due to invalid data inputs.'
elif val == 0x80DA0000:
return 'BadAggregateConfigurationRejected', 'The aggregate configuration is not valid for specified node.'
elif val == 0x00D90000:
return 'GoodDataIgnored', 'The request pecifies fields which are not valid for the EventType or cannot be saved by the historian.'
elif val == 0x80E40000:
return 'BadRequestNotAllowed', 'The request was rejected by the server because it did not meet the criteria set by the server.'
elif val == 0x00DC0000:
return 'GoodEdited', 'The value does not come from the real source and has been edited by the server.'
elif val == 0x00DD0000:
return 'GoodPostActionFailed', 'There was an error in execution of these post-actions.'
elif val == 0x40DE0000:
return 'UncertainDominantValueChanged', 'The related EngineeringUnit has been changed but the Variable Value is still provided based on the previous unit.'
elif val == 0x00E00000:
return 'GoodDependentValueChanged', 'A dependent value has been changed but the change has not been applied to the device.'
elif val == 0x80E10000:
return 'BadDominantValueChanged', 'The related EngineeringUnit has been changed but this change has not been applied to the device. The Variable Value is still dependent on the previous unit but its status is currently Bad.'
elif val == 0x40E20000:
return 'UncertainDependentValueChanged', 'A dependent value has been changed but the change has not been applied to the device. The quality of the dominant variable is uncertain.'
elif val == 0x80E30000:
return 'BadDependentValueChanged', 'A dependent value has been changed but the change has not been applied to the device. The quality of the dominant variable is Bad.'
elif val == 0x00A70000:
return 'GoodCommunicationEvent', 'The communication layer has raised an event.'
elif val == 0x00A80000:
return 'GoodShutdownEvent', 'The system is shutting down.'
elif val == 0x00A90000:
return 'GoodCallAgain', 'The operation is not finished and needs to be called again.'
elif val == 0x00AA0000:
return 'GoodNonCriticalTimeout', 'A non-critical timeout occurred.'
elif val == 0x80AB0000:
return 'BadInvalidArgument', 'One or more arguments are invalid.'
elif val == 0x80AC0000:
return 'BadConnectionRejected', 'Could not establish a network connection to remote server.'
elif val == 0x80AD0000:
return 'BadDisconnect', 'The server has disconnected from the client.'
elif val == 0x80AE0000:
return 'BadConnectionClosed', 'The network connection has been closed.'
elif val == 0x80AF0000:
return 'BadInvalidState', 'The operation cannot be completed because the object is closed, uninitialized or in some other invalid state.'
elif val == 0x80B00000:
return 'BadEndOfStream', 'Cannot move beyond end of the stream.'
elif val == 0x80B10000:
return 'BadNoDataAvailable', 'No data is currently available for reading from a non-blocking stream.'
elif val == 0x80B20000:
return 'BadWaitingForResponse', 'The asynchronous operation is waiting for a response.'
elif val == 0x80B30000:
return 'BadOperationAbandoned', 'The asynchronous operation was abandoned by the caller.'
elif val == 0x80B40000:
return 'BadExpectedStreamToBlock', 'The stream did not return all data requested (possibly because it is a non-blocking stream).'
elif val == 0x80B50000:
return 'BadWouldBlock', 'Non blocking behaviour is required and the operation would block.'
elif val == 0x80B60000:
return 'BadSyntaxError', 'A value had an invalid syntax.'
elif val == 0x80B70000:
return 'BadMaxConnectionsReached', 'The operation could not be finished because all available connections are in use.'
if val in code_to_name_doc:
return code_to_name_doc[val]
else:
return 'UnknownUaError', 'Unknown StatusCode value: {}'.format(val)
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -3,6 +3,7 @@ import logging
import opcua.uaprotocol_auto as auto
import opcua.uatypes as uatypes
from opcua.uatypes import uatype_UInt32
import opcua.utils as utils
from opcua.object_ids import ObjectIds
from opcua.attribute_ids import AttributeIds
......@@ -35,22 +36,22 @@ class Hello(uatypes.FrozenClass):
def to_binary(self):
b = []
b.append(struct.pack("<I", self.ProtocolVersion))
b.append(struct.pack("<I", self.ReceiveBufferSize))
b.append(struct.pack("<I", self.SendBufferSize))
b.append(struct.pack("<I", self.MaxMessageSize))
b.append(struct.pack("<I", self.MaxChunkCount))
b.append(uatype_UInt32.pack(self.ProtocolVersion))
b.append(uatype_UInt32.pack(self.ReceiveBufferSize))
b.append(uatype_UInt32.pack(self.SendBufferSize))
b.append(uatype_UInt32.pack(self.MaxMessageSize))
b.append(uatype_UInt32.pack(self.MaxChunkCount))
b.append(uatypes.pack_string(self.EndpointUrl))
return b"".join(b)
@staticmethod
def from_binary(data):
hello = Hello()
hello.ProtocolVersion = struct.unpack("<I", data.read(4))[0]
hello.ReceiveBufferSize = struct.unpack("<I", data.read(4))[0]
hello.SendBufferSize = struct.unpack("<I", data.read(4))[0]
hello.MaxMessageSize = struct.unpack("<I", data.read(4))[0]
hello.MaxChunkCount = struct.unpack("<I", data.read(4))[0]
hello.ProtocolVersion = uatype_UInt32.unpack(data.read(4))[0]
hello.ReceiveBufferSize = uatype_UInt32.unpack(data.read(4))[0]
hello.SendBufferSize = uatype_UInt32.unpack(data.read(4))[0]
hello.MaxMessageSize = uatype_UInt32.unpack(data.read(4))[0]
hello.MaxChunkCount = uatype_UInt32.unpack(data.read(4))[0]
hello.EndpointUrl = uatypes.unpack_string(data)
return hello
......@@ -87,26 +88,23 @@ class Header(uatypes.FrozenClass):
def to_binary(self):
b = []
b.append(struct.pack("<3s", self.MessageType))
b.append(struct.pack("<s", self.ChunkType))
b.append(struct.pack("<3ss", self.MessageType, self.ChunkType))
size = self.body_size + 8
if self.MessageType in (MessageType.SecureOpen, MessageType.SecureClose, MessageType.SecureMessage):
size += 4
b.append(struct.pack("<I", size))
b.append(uatype_UInt32.pack(size))
if self.MessageType in (MessageType.SecureOpen, MessageType.SecureClose, MessageType.SecureMessage):
b.append(struct.pack("<I", self.ChannelId))
b.append(uatype_UInt32.pack(self.ChannelId))
return b"".join(b)
@staticmethod
def from_string(data):
hdr = Header()
hdr.MessageType = struct.unpack("<3s", data.read(3))[0]
hdr.ChunkType = struct.unpack("<c", data.read(1))[0]
hdr.packet_size = struct.unpack("<I", data.read(4))[0]
hdr.body_size = hdr.packet_size - 8
hdr.MessageType, hdr.ChunkType, hdr.packet_size = struct.unpack("<3scI", data.read(8))
hdr.body_size = hdr.packet_size - 8
if hdr.MessageType in (MessageType.SecureOpen, MessageType.SecureClose, MessageType.SecureMessage):
hdr.body_size -= 4
hdr.ChannelId = struct.unpack("<I", data.read(4))[0]
hdr.ChannelId = uatype_UInt32.unpack(data.read(4))[0]
return hdr
def __str__(self):
......@@ -150,22 +148,19 @@ class Acknowledge(uatypes.FrozenClass):
self._freeze()
def to_binary(self):
b = []
b.append(struct.pack("<I", self.ProtocolVersion))
b.append(struct.pack("<I", self.ReceiveBufferSize))
b.append(struct.pack("<I", self.SendBufferSize))
b.append(struct.pack("<I", self.MaxMessageSize))
b.append(struct.pack("<I", self.MaxChunkCount))
return b"".join(b)
return struct.pack(
"<5I",
self.ProtocolVersion,
self.ReceiveBufferSize,
self.SendBufferSize,
self.MaxMessageSize,
self.MaxChunkCount)
@staticmethod
def from_binary(data):
ack = Acknowledge()
ack.ProtocolVersion = struct.unpack("<I", data.read(4))[0]
ack.ReceiveBufferSize = struct.unpack("<I", data.read(4))[0]
ack.SendBufferSize = struct.unpack("<I", data.read(4))[0]
ack.MaxMessageSize = struct.unpack("<I", data.read(4))[0]
ack.MaxChunkCount = struct.unpack("<I", data.read(4))[0]
ack.ProtocolVersion, ack.ReceiveBufferSize, ack.SendBufferSize, ack.MaxMessageSize, ack.MaxChunkCount \
= struct.unpack("<5I", data.read(20))
return ack
......@@ -206,11 +201,11 @@ class SymmetricAlgorithmHeader(uatypes.FrozenClass):
@staticmethod
def from_binary(data):
obj = SymmetricAlgorithmHeader()
obj.TokenId = struct.unpack("<I", data.read(4))[0]
obj.TokenId = uatype_UInt32.unpack(data.read(4))[0]
return obj
def to_binary(self):
return struct.pack("<I", self.TokenId)
return uatype_UInt32.pack(self.TokenId)
def __str__(self):
return "{}(TokenId:{} )".format(self.__class__.__name__, self.TokenId)
......@@ -227,14 +222,14 @@ class SequenceHeader(uatypes.FrozenClass):
@staticmethod
def from_binary(data):
obj = SequenceHeader()
obj.SequenceNumber = struct.unpack("<I", data.read(4))[0]
obj.RequestId = struct.unpack("<I", data.read(4))[0]
obj.SequenceNumber = uatype_UInt32.unpack(data.read(4))[0]
obj.RequestId = uatype_UInt32.unpack(data.read(4))[0]
return obj
def to_binary(self):
b = []
b.append(struct.pack("<I", self.SequenceNumber))
b.append(struct.pack("<I", self.RequestId))
b.append(uatype_UInt32.pack(self.SequenceNumber))
b.append(uatype_UInt32.pack(self.RequestId))
return b"".join(b)
def __str__(self):
......
......@@ -52,64 +52,53 @@ def win_epoch_to_datetime(epch):
return FILETIME_EPOCH_AS_DATETIME + timedelta(microseconds=epch // 10)
def uatype_to_fmt(uatype):
if uatype == "Char":
return "B"
elif uatype == "SByte":
return "B"
elif uatype == "Int6":
return "b"
elif uatype == "Int8":
return "b"
elif uatype == "Int16":
return "h"
elif uatype == "Int32":
return "i"
elif uatype == "Int64":
return "q"
elif uatype == "UInt8":
return "B"
elif uatype == "UInt16":
return "H"
elif uatype == "UInt32":
return "I"
elif uatype == "UInt64":
return "Q"
elif uatype == "Boolean":
return "?"
elif uatype == "Double":
return "d"
elif uatype == "Float":
return "f"
elif uatype == "Byte":
return "B"
def build_array_format_py2(prefix, length, fmtchar):
return prefix + str(length) + fmtchar
def build_array_format_py3(prefix, length, fmtchar):
return prefix + str(length) + chr(fmtchar)
if sys.version_info.major < 3:
build_array_format = build_array_format_py2
else:
build_array_format = build_array_format_py3
def pack_uatype_array_primitive(st, value, length):
if length == 1:
return b'\x01\x00\x00\x00' + st.pack(value[0])
else:
raise Exception("Error unknown uatype: " + uatype)
return struct.pack(build_array_format("<i", length, st.format[1]), length, *value)
def pack_uatype_array(uatype, value):
if value is None:
return struct.pack("<i", -1)
return b'\xff\xff\xff\xff'
length = len(value)
if length == 0:
return b'\x00\x00\x00\x00'
if uatype in uatype2struct:
return pack_uatype_array_primitive(uatype2struct[uatype], value, length)
b = []
b.append(struct.pack("<i", len(value)))
b.append(uatype_Int32.pack(length))
for val in value:
b.append(pack_uatype(uatype, val))
return b"".join(b)
def pack_uatype(uatype, value):
if uatype == "Null":
if uatype in uatype2struct:
return uatype2struct[uatype].pack(value)
elif uatype == "Null":
return b''
elif uatype == "String":
return pack_string(value)
elif uatype in ("CharArray", "ByteString"):
return pack_bytes(value)
elif uatype == "DateTime":
epch = datetime_to_win_epoch(value)
return struct.pack('<q', epch)
elif uatype in UaTypes:
fmt = '<' + uatype_to_fmt(uatype)
return struct.pack(fmt, value)
return pack_datetime(value)
elif uatype == "ExtensionObject":
# dependency loop: classes in uaprotocol_auto use Variant defined in this file,
# but Variant can contain any object from uaprotocol_auto as ExtensionObject.
......@@ -119,19 +108,49 @@ def pack_uatype(uatype, value):
else:
return value.to_binary()
uatype_Int8 = struct.Struct("<b")
uatype_SByte = uatype_Int8
uatype_Int16 = struct.Struct("<h")
uatype_Int32 = struct.Struct("<i")
uatype_Int64 = struct.Struct("<q")
uatype_UInt8 = struct.Struct("<B")
uatype_Char = uatype_UInt8
uatype_Byte = uatype_UInt8
uatype_UInt16 = struct.Struct("<H")
uatype_UInt32 = struct.Struct("<I")
uatype_UInt64 = struct.Struct("<Q")
uatype_Boolean = struct.Struct("<?")
uatype_Double = struct.Struct("<d")
uatype_Float = struct.Struct("<f")
uatype2struct = {
"Int8": uatype_Int8,
"SByte": uatype_SByte,
"Int16": uatype_Int16,
"Int32": uatype_Int32,
"Int64": uatype_Int64,
"UInt8": uatype_UInt8,
"Char": uatype_Char,
"Byte": uatype_Byte,
"UInt16": uatype_UInt16,
"UInt32": uatype_UInt32,
"UInt64": uatype_UInt64,
"Boolean": uatype_Boolean,
"Double": uatype_Double,
"Float": uatype_Float,
}
def unpack_uatype(uatype, data):
if uatype == "String":
if uatype in uatype2struct:
st = uatype2struct[uatype]
return st.unpack(data.read(st.size))[0]
elif uatype == "String":
return unpack_string(data)
elif uatype in ("CharArray", "ByteString"):
return unpack_bytes(data)
elif uatype == "DateTime":
epch = struct.unpack('<q', data.read(8))[0]
return win_epoch_to_datetime(epch)
elif uatype in UaTypes:
fmt = '<' + uatype_to_fmt(uatype)
size = struct.calcsize(fmt)
return struct.unpack(fmt, data.read(size))[0]
return unpack_datetime(data)
elif uatype == "ExtensionObject":
# dependency loop: classes in uaprotocol_auto use Variant defined in this file,
# but Variant can contain any object from uaprotocol_auto as ExtensionObject.
......@@ -139,15 +158,27 @@ def unpack_uatype(uatype, data):
from opcua.uaprotocol_auto import extensionobject_from_binary
return extensionobject_from_binary(data)
else:
code = "{}.from_binary(data)".format(uatype)
tmp = eval(code)
return tmp
glbs = globals()
if uatype in glbs:
klass = glbs[uatype]
if hasattr(klass, 'from_binary'):
return klass.from_binary(data)
raise Exception("can not unpack unknown uatype %s" % uatype)
def unpack_uatype_array(uatype, data):
length = struct.unpack('<i', data.read(4))[0]
length = uatype_Int32.unpack(data.read(4))[0]
if length == -1:
return None
elif length == 0:
return []
elif uatype in uatype2struct:
st = uatype2struct[uatype]
if length == 1:
return list(st.unpack(data.read(st.size)))
else:
arrst = struct.Struct(build_array_format("<", length, st.format[1]))
return list(arrst.unpack(data.read(arrst.size)))
else:
result = []
for _ in range(0, length):
......@@ -155,31 +186,45 @@ def unpack_uatype_array(uatype, data):
return result
def pack_datetime(value):
epch = datetime_to_win_epoch(value)
return uatype_Int64.pack(epch)
def unpack_datetime(data):
epch = uatype_Int64.unpack(data.read(8))[0]
return win_epoch_to_datetime(epch)
def pack_string(string):
if type(string) is unicode:
string = string.encode('utf-8')
length = len(string)
if length == 0:
return struct.pack("<i", -1)
return struct.pack("<i", length) + string
return b'\xff\xff\xff\xff'
return uatype_Int32.pack(length) + string
pack_bytes = pack_string
def unpack_bytes(data):
length = struct.unpack("<i", data.read(4))[0]
length = uatype_Int32.unpack(data.read(4))[0]
if length == -1:
return b''
return data.read(length)
def unpack_string(data):
def py3_unpack_string(data):
b = unpack_bytes(data)
if sys.version_info.major < 3:
return str(b)
return b.decode("utf-8")
if sys.version_info.major < 3:
unpack_string = unpack_bytes
else:
unpack_string = py3_unpack_string
def test_bit(data, offset):
mask = 1 << offset
return data & mask
......@@ -207,10 +252,11 @@ class FrozenClass(object):
self.__isfrozen = True
class Guid(object):
class Guid(FrozenClass):
def __init__(self):
self.uuid = uuid.uuid4()
self._freeze()
def to_binary(self):
return self.uuid.bytes
......@@ -239,13 +285,14 @@ class StatusCode(FrozenClass):
def __init__(self, value=0):
self.value = value
self.name, self.doc = status_code.get_name_and_doc(value)
self._freeze()
def to_binary(self):
return struct.pack("<I", self.value)
return uatype_UInt32.pack(self.value)
@staticmethod
def from_binary(data):
val = struct.unpack("<I", data.read(4))[0]
val = uatype_UInt32.unpack(data.read(4))[0]
sc = StatusCode(val)
return sc
......@@ -306,6 +353,7 @@ class NodeId(FrozenClass):
self.NodeIdType = nodeidtype
self.NamespaceUri = ""
self.ServerIndex = 0
self._freeze()
if self.Identifier is None:
self.Identifier = 0
self.NodeIdType = NodeIdType.TwoByte
......@@ -400,45 +448,42 @@ class NodeId(FrozenClass):
__repr__ = __str__
def to_binary(self):
b = []
b.append(struct.pack("<B", self.NodeIdType))
if self.NodeIdType == NodeIdType.TwoByte:
b.append(struct.pack("<B", self.Identifier))
return struct.pack("<BB", self.NodeIdType, self.Identifier)
elif self.NodeIdType == NodeIdType.FourByte:
b.append(struct.pack("<BH", self.NamespaceIndex, self.Identifier))
return struct.pack("<BBH", self.NodeIdType, self.NamespaceIndex, self.Identifier)
elif self.NodeIdType == NodeIdType.Numeric:
b.append(struct.pack("<HI", self.NamespaceIndex, self.Identifier))
return struct.pack("<BHI", self.NodeIdType, self.NamespaceIndex, self.Identifier)
elif self.NodeIdType == NodeIdType.String:
b.append(struct.pack("<H", self.NamespaceIndex))
b.append(pack_string(self.Identifier))
return struct.pack("<BH", self.NodeIdType, self.NamespaceIndex) + \
pack_string(self.Identifier)
elif self.NodeIdType == NodeIdType.ByteString:
b.append(struct.pack("<H", self.NamespaceIndex))
b.append(pack_bytes(self.Identifier))
return struct.pack("<BH", self.NodeIdType, self.NamespaceIndex) + \
pack_bytes(self.Identifier)
else:
b.append(struct.pack("<H", self.NamespaceIndex))
b.append(self.Identifier.to_binary())
return b"".join(b)
return struct.pack("<BH", self.NodeIdType, self.NamespaceIndex) + \
self.Identifier.to_binary()
@staticmethod
def from_binary(data):
nid = NodeId()
encoding = struct.unpack("<B", data.read(1))[0]
encoding = ord(data.read(1))
nid.NodeIdType = encoding & 0b00111111
if nid.NodeIdType == NodeIdType.TwoByte:
nid.Identifier = struct.unpack("<B", data.read(1))[0]
nid.Identifier = ord(data.read(1))
elif nid.NodeIdType == NodeIdType.FourByte:
nid.NamespaceIndex, nid.Identifier = struct.unpack("<BH", data.read(3))
elif nid.NodeIdType == NodeIdType.Numeric:
nid.NamespaceIndex, nid.Identifier = struct.unpack("<HI", data.read(6))
elif nid.NodeIdType == NodeIdType.String:
nid.NamespaceIndex = struct.unpack("<H", data.read(2))[0]
nid.NamespaceIndex = uatype_UInt16.unpack(data.read(2))[0]
nid.Identifier = unpack_string(data)
elif nid.NodeIdType == NodeIdType.ByteString:
nid.NamespaceIndex = struct.unpack("<H", data.read(2))[0]
nid.NamespaceIndex = uatype_UInt16.unpack(data.read(2))[0]
nid.Identifier = unpack_bytes(data)
elif nid.NodeIdType == NodeIdType.Guid:
nid.NamespaceIndex = struct.unpack("<H", data.read(2))[0]
nid.NamespaceIndex = uatype_UInt16.unpack(data.read(2))[0]
nid.Identifier = Guid.from_binary(data)
else:
raise Exception("Unknown NodeId encoding: " + str(nid.NodeIdType))
......@@ -446,7 +491,7 @@ class NodeId(FrozenClass):
if test_bit(encoding, 6):
nid.NamespaceUri = unpack_string(data)
if test_bit(encoding, 7):
nid.ServerIndex = struct.unpack("<I", data.read(4))[0]
nid.ServerIndex = uatype_UInt32.unpack(data.read(4))[0]
return nid
......@@ -499,6 +544,7 @@ class QualifiedName(FrozenClass):
def __init__(self, name="", namespaceidx=0):
self.NamespaceIndex = namespaceidx
self.Name = name
self._freeze()
def to_string(self):
return "{}:{}".format(self.NamespaceIndex, self.Name)
......@@ -514,16 +560,14 @@ class QualifiedName(FrozenClass):
def to_binary(self):
packet = []
fmt = '<H'
packet.append(struct.pack(fmt, self.NamespaceIndex))
packet.append(uatype_UInt16.pack(self.NamespaceIndex))
packet.append(pack_string(self.Name))
return b''.join(packet)
@staticmethod
def from_binary(data):
obj = QualifiedName()
fmt = '<H'
obj.NamespaceIndex = struct.unpack(fmt, data.read(2))[0]
obj.NamespaceIndex = uatype_UInt16.unpack(data.read(2))[0]
obj.Name = unpack_string(data)
return obj
......@@ -558,21 +602,21 @@ class LocalizedText(FrozenClass):
self.Encoding |= (1 << 0)
if self.Text:
self.Encoding |= (1 << 1)
packet.append(pack_uatype('UInt8', self.Encoding))
packet.append(uatype_UInt8.pack(self.Encoding))
if self.Locale:
packet.append(pack_uatype('CharArray', self.Locale))
packet.append(pack_bytes(self.Locale))
if self.Text:
packet.append(pack_uatype('CharArray', self.Text))
packet.append(pack_bytes(self.Text))
return b''.join(packet)
@staticmethod
def from_binary(data):
obj = LocalizedText()
obj.Encoding = unpack_uatype('UInt8', data)
obj.Encoding = ord(data.read(1))
if obj.Encoding & (1 << 0):
obj.Locale = unpack_uatype('CharArray', data)
obj.Locale = unpack_bytes(data)
if obj.Encoding & (1 << 1):
obj.Text = unpack_uatype('CharArray', data)
obj.Text = unpack_bytes(data)
return obj
def to_string(self):
......@@ -591,7 +635,6 @@ class LocalizedText(FrozenClass):
return False
class VariantType(Enum):
'''
......@@ -669,8 +712,8 @@ class Variant(FrozenClass):
:vartype VariantType: VariantType
"""
def __init__(self, value=None, varianttype=None):
self.Encoding = 0
def __init__(self, value=None, varianttype=None, encoding=0):
self.Encoding = encoding
self.Value = value
self.VariantType = varianttype
if isinstance(value, Variant):
......@@ -683,6 +726,7 @@ class Variant(FrozenClass):
self.VariantType = self._guess_type(self.Value[0])
else:
self.VariantType = self._guess_type(self.Value)
self._freeze()
def __eq__(self, other):
if isinstance(other, Variant) and self.VariantType == other.VariantType and self.Value == other.Value:
......@@ -723,25 +767,24 @@ class Variant(FrozenClass):
self.Encoding = (self.VariantType.value | mask)
if type(self.Value) in (list, tuple):
self.Encoding |= (1 << 7)
b.append(uatype_UInt8.pack(self.Encoding))
b.append(pack_uatype_array(self.VariantType.name, self.Value))
else:
b.append(uatype_UInt8.pack(self.Encoding))
b.append(pack_uatype(self.VariantType.name, self.Value))
b.insert(0, struct.pack("<B", self.Encoding))
return b"".join(b)
@staticmethod
def from_binary(data):
obj = Variant()
obj.Encoding = unpack_uatype('UInt8', data)
val = obj.Encoding & 0b01111111
obj.VariantType = VariantType(val)
if obj.VariantType == VariantType.Null:
return obj
if obj.Encoding & (1 << 7):
obj.Value = unpack_uatype_array(obj.VariantType.name, data)
encoding = ord(data.read(1))
vtype = VariantType(encoding & 0b01111111)
if vtype == VariantType.Null:
return Variant(None, vtype, encoding)
if encoding & (1 << 7):
value = unpack_uatype_array(vtype.name, data)
else:
obj.Value = unpack_uatype(obj.VariantType.name, data)
return obj
value = unpack_uatype(vtype.name, data)
return Variant(value, vtype, encoding)
class DataValue(FrozenClass):
......@@ -765,16 +808,20 @@ class DataValue(FrozenClass):
'''
def __init__(self, variant=None):
def __init__(self, variant=None, status=None):
self.Encoding = 0
if not isinstance(variant, Variant):
variant = Variant(variant)
self.Value = variant
self.StatusCode = StatusCode()
if status is None:
self.StatusCode = StatusCode()
else:
self.StatusCode = status
self.SourceTimestamp = None # DateTime()
self.SourcePicoseconds = None
self.ServerTimestamp = None # DateTime()
self.ServerPicoseconds = None
self._freeze()
def to_binary(self):
packet = []
......@@ -790,37 +837,42 @@ class DataValue(FrozenClass):
self.Encoding |= (1 << 4)
if self.ServerPicoseconds:
self.Encoding |= (1 << 5)
packet.append(pack_uatype('UInt8', self.Encoding))
packet.append(uatype_UInt8.pack(self.Encoding))
if self.Value:
packet.append(self.Value.to_binary())
if self.StatusCode:
packet.append(self.StatusCode.to_binary())
if self.SourceTimestamp:
packet.append(pack_uatype('DateTime', self.SourceTimestamp)) # self.SourceTimestamp.to_binary())
packet.append(pack_datetime(self.SourceTimestamp)) # self.SourceTimestamp.to_binary())
if self.ServerTimestamp:
packet.append(pack_uatype('DateTime', self.ServerTimestamp)) # self.ServerTimestamp.to_binary())
packet.append(pack_datetime(self.ServerTimestamp)) # self.ServerTimestamp.to_binary())
if self.SourcePicoseconds:
packet.append(pack_uatype('UInt16', self.SourcePicoseconds))
packet.append(uatype_UInt16.pack(self.SourcePicoseconds))
if self.ServerPicoseconds:
packet.append(pack_uatype('UInt16', self.ServerPicoseconds))
packet.append(uatype_UInt16.pack(self.ServerPicoseconds))
return b''.join(packet)
@staticmethod
def from_binary(data):
obj = DataValue()
obj.Encoding = unpack_uatype('UInt8', data)
if obj.Encoding & (1 << 0):
obj.Value = Variant.from_binary(data)
if obj.Encoding & (1 << 1):
obj.StatusCode = StatusCode.from_binary(data)
encoding = ord(data.read(1))
if encoding & (1 << 0):
value = Variant.from_binary(data)
else:
value = None
if encoding & (1 << 1):
status = StatusCode.from_binary(data)
else:
status = None
obj = DataValue(value, status)
obj.Encoding = encoding
if obj.Encoding & (1 << 2):
obj.SourceTimestamp = unpack_uatype('DateTime', data) # DateTime.from_binary(data)
obj.SourceTimestamp = unpack_datetime(data) # DateTime.from_binary(data)
if obj.Encoding & (1 << 3):
obj.ServerTimestamp = unpack_uatype('DateTime', data) # DateTime.from_binary(data)
obj.ServerTimestamp = unpack_datetime(data) # DateTime.from_binary(data)
if obj.Encoding & (1 << 4):
obj.SourcePicoseconds = unpack_uatype('UInt16', data)
obj.SourcePicoseconds = uatype_UInt16.unpack(data.read(2))[0]
if obj.Encoding & (1 << 5):
obj.ServerPicoseconds = unpack_uatype('UInt16', data)
obj.ServerPicoseconds = uatype_UInt16.unpack(data.read(2))[0]
return obj
def __str__(self):
......@@ -848,5 +900,3 @@ def generate_nodeid(idx):
global __nodeid_counter
__nodeid_counter += 1
return NodeId(__nodeid_counter, idx)
......@@ -26,25 +26,29 @@ class Buffer(object):
"""
def __init__(self, data):
self.logger = logging.getLogger(__name__)
self.data = data
# self.logger = logging.getLogger(__name__)
self._data = data
self.rsize = 0
def __str__(self):
return "Buffer(size:{}, data:{})".format(len(self.data), self.data)
return "Buffer(size:{}, data:{})".format(len(self), self.data)
__repr__ = __str__
def __len__(self):
return len(self.data)
return len(self._data) - self.rsize
def read(self, size):
"""
read and pop number of bytes for buffer
"""
if size > len(self.data):
rsize = self.rsize
nrsize = rsize + size
mydata = self._data
if nrsize > len(mydata):
raise Exception("Not enough data left in buffer, request for {}, we have {}".format(size, self))
#self.logger.debug("Request for %s bytes, from %s", size, self)
data = self.data[:size]
self.data = self.data[size:]
data = mydata[rsize:nrsize]
self.rsize = nrsize
#self.logger.debug("Returning: %s ", data)
return data
......@@ -53,17 +57,27 @@ class Buffer(object):
return a copy, optionnaly only copy 'size' bytes
"""
if size is None:
return Buffer(self.data)
return Buffer(self._data[self.rsize:])
else:
return Buffer(self.data[:size])
return Buffer(self._data[self.rsize:self.rsize + size])
def test_read(self, size):
"""
read 'size' bytes from buffer, without removing them from buffer
"""
if size > len(self.data):
if self.rsize + size > len(self._data):
raise Exception("Not enough data left in buffer, request for {}, we have {}".format(size, self))
return self.data[:size]
return self._data[self.rsize:self.rsize + size]
def get_data(self):
return self._data[self.rsize:]
def set_data(self, v):
self._data = v
self.rsize = 0
data = property(get_data, set_data)
class SocketClosedException(Exception):
pass
......
......@@ -6,7 +6,7 @@ from copy import copy
import xml.etree.ElementTree as ET
from IPython import embed
# from IPython import embed
NeedOverride = []
NeedConstructor = []#["RelativePathElement", "ReadValueId", "OpenSecureChannelParameters", "UserIdentityToken", "RequestHeader", "ResponseHeader", "ReadParameters", "UserIdentityToken", "BrowseDescription", "ReferenceDescription", "CreateSubscriptionParameters", "PublishResult", "NotificationMessage", "SetPublishingModeParameters"]
......
......@@ -91,8 +91,15 @@ class CodeGenerator(object):
self.write(":ivar {}:".format(field.name))
self.write(":vartype {}: {}".format(field.name, field.uatype))
self.write("'''")
self.write("def __init__(self):")
self.write("def __init__(self, binary=None):")
self.iidx += 1
self.write("if binary is not None:")
self.iidx += 1
self.write("self._binary_init(binary)")
self.write("self._freeze()")
self.write("return")
self.iidx -= 1
# hack extension object stuff
extobj_hack = False
......@@ -151,15 +158,15 @@ class CodeGenerator(object):
self.write("if self.{}: ".format(field.name))
self.iidx += 1
if field.length:
self.write("{}.append(struct.pack('<i', len(self.{})))".format(listname, field.name))
self.write("{}.append(uatype_Int32.pack(len(self.{})))".format(listname, field.name))
self.write("for fieldname in self.{}:".format(field.name))
fname = "fieldname"
self.iidx += 1
if field.is_native_type():
self.write("{}.append(pack_uatype('{}', {}))".format(listname, field.uatype, fname))
self.write_pack_uatype(listname, fname, field.uatype)
elif field.uatype in self.model.enum_list:
uatype = self.model.get_enum(field.uatype).uatype
self.write("{}.append(pack_uatype('{}', {}))".format(listname, uatype, fname))
self.write_pack_uatype(listname, fname, uatype)
elif field.uatype in ("ExtensionObject"):
self.write("{}.append(extensionobject_to_binary({}))".format(listname, fname))
else:
......@@ -179,8 +186,13 @@ class CodeGenerator(object):
self.write("@staticmethod")
self.write("def from_binary(data):")
self.iidx += 1
self.write("return {}(data)".format(obj.name))
self.iidx -= 1
self.write("")
self.write("def _binary_init(self, data):")
self.iidx += 1
iidx = self.iidx
self.write("obj = {}()".format(obj.name))
for idx, field in enumerate(obj.fields):
self.iidx = iidx
# if field.name == "Body" and idx <= (len(obj.fields)-1):
......@@ -190,37 +202,53 @@ class CodeGenerator(object):
bit = obj.bits[field.switchfield]
if field.switchvalue:
mask = '0b' + '0' * (8 - bit.length) + '1' * bit.length
self.write("val = obj.{} & {}".format(bit.container, mask))
self.write("val = self.{} & {}".format(bit.container, mask))
self.write("if val == {}:".format(bit.idx))
else:
self.write("if obj.{} & (1 << {}):".format(bit.container, bit.idx))
self.write("if self.{} & (1 << {}):".format(bit.container, bit.idx))
self.iidx += 1
array = False
if field.is_native_type():
if field.length:
self.write("obj.{} = unpack_uatype_array('{}', data)".format(field.name, field.uatype))
self.write("self.{} = unpack_uatype_array('{}', data)".format(field.name, field.uatype))
else:
self.write("obj.{} = unpack_uatype('{}', data)".format(field.name, field.uatype))
self.write_unpack_uatype(field.name, field.uatype)
elif field.uatype in self.model.enum_list:
uatype = self.model.get_enum(field.uatype).uatype
self.write("obj.{} = unpack_uatype('{}', data)".format(field.name, uatype))
self.write_unpack_uatype(field.name, uatype)
else:
if field.uatype in ("ExtensionObject"):
frombinary = "extensionobject_from_binary(data)"
else:
frombinary = "{}.from_binary(data)".format(field.uatype)
if field.length:
self.write("length = struct.unpack('<i', data.read(4))[0]")
self.write("length = uatype_Int32.unpack(data.read(4))[0]")
self.write("array = []")
self.write("if length != -1:")
self.iidx += 1
self.write("for _ in range(0, length):")
self.iidx += 1
self.write("obj.{}.append({})".format(field.name, frombinary))
self.write("array.append({})".format(frombinary))
self.iidx -= 2
self.write("self.{} = array".format(field.name))
else:
self.write("obj.{} = {}".format(field.name, frombinary))
self.write("self.{} = {}".format(field.name, frombinary))
if field.switchfield:
self.iidx -= 1
self.write("else:")
self.iidx += 1
if extobj_hack and field.name == "Encoding":
self.write("self.Encoding = 1")
elif field.uatype == obj.name: # help!!! selv referencing class
self.write("self.{} = None".format(field.name))
elif not obj.name in ("ExtensionObject") and field.name == "TypeId": # and ( obj.name.endswith("Request") or obj.name.endswith("Response")):
self.write("self.TypeId = FourByteNodeId(ObjectIds.{}_Encoding_DefaultBinary)".format(obj.name))
else:
self.write("self.{} = {}".format(field.name, "[]" if field.length else self.get_default_value(field)))
if len(obj.fields) == 0:
self.write("pass")
self.iidx = 2
self.write("return obj")
#__str__
self.iidx = 1
......@@ -236,6 +264,51 @@ class CodeGenerator(object):
self.iix = 0
def write_unpack_uatype(self, name, uatype):
if uatype in ("Int8", "UInt8", "Sbyte", "Byte", "Char", "Boolean"):
size = 1
elif uatype in ("Int16", "UInt16"):
size = 2
elif uatype in ("Int32", "UInt32", "Float"):
size = 4
elif uatype in ("Int64", "UInt64", "Double"):
size = 8
elif uatype == "String":
self.write("self.{} = unpack_string(data)".format(name))
return
elif uatype in ("CharArray", "ByteString"):
self.write("self.{} = unpack_bytes(data)".format(name))
return
elif uatype == "DateTime":
self.write("self.{} = unpack_datetime(data)".format(name))
return
else:
self.write("self.{} = unpack_uatype('{}', data)".format(name, uatype))
return
self.write("self.{} = uatype_{}.unpack(data.read({}))[0]".format(name, uatype, size))
def write_pack_uatype(self, listname, name, uatype):
if uatype in (
"Int8", "UInt8", "Sbyte", "Byte", "Char", "Boolean",
"Int16", "UInt16",
"Int32", "UInt32", "Float",
"Int64", "UInt64", "Double"
):
self.write("{}.append(uatype_{}.pack({}))".format(listname, uatype, name))
return
elif uatype == "String":
self.write("{}.append(pack_string({}))".format(listname, name))
return
elif uatype in ("CharArray", "ByteString"):
self.write("{}.append(pack_bytes({}))".format(listname, name))
return
elif uatype == "DateTime":
self.write("{}.append(pack_datetime({}))".format(listname, name))
return
else:
self.write("{}.append(pack_uatype('{}', {}))".format(listname, uatype, name))
return
def get_default_value(self, field):
if field.uatype in self.model.enum_list:
return 0
......
......@@ -5,13 +5,13 @@ def status_codes():
inputfile = open("StatusCodes_add.csv")
additional = {}
for line in inputfile:
name, val, doc = line.split(",", maxsplit=2)
name, val, doc = line.split(",", 2)
additional[int(val, 0)] = (name, val, doc)
inputfile = open("StatusCodes.csv")
result = []
for line in inputfile:
name, val, doc = line.split(",", maxsplit=2)
name, val, doc = line.split(",", 2)
result.append((name, val, doc))
additional.pop(int(val, 0), None)
add = [ additional[k] for k in sorted(additional.keys()) ]
......@@ -25,23 +25,28 @@ if __name__ == "__main__":
#outputfile.write("from enum import Enum\n")
outputfile.write("\n")
outputfile.write("class StatusCodes:\n")
outputfile.write("class StatusCodes(object):\n")
for name, val, doc in codes:
doc = doc.strip()
outputfile.write(" {} = {}\n".format(name, val))
outputfile.write("\n")
outputfile.write("\n")
outputfile.write("def get_name_and_doc(val):\n")
kword = "if"
outputfile.write("code_to_name_doc = {\n")
for name, val, doc in codes:
doc = doc.strip()
doc = doc.replace("'", '"')
outputfile.write(" {} val == {}:\n".format(kword, val))
outputfile.write(" return '{}', '{}'\n".format(name, doc))
kword = "elif"
outputfile.write(" else:\n".format(val))
outputfile.write(" return 'UnknownUaError', 'Unknown StatusCode value: {}'.format(val)\n")
outputfile.write(" {}: ('{}', '{}'),\n".format(val, name, doc))
outputfile.write("}\n")
outputfile.write("\n")
outputfile.write("\n")
outputfile.write("""def get_name_and_doc(val):
if val in code_to_name_doc:
return code_to_name_doc[val]
else:
return 'UnknownUaError', 'Unknown StatusCode value: {}'.format(val)
""")
'''
outputfile.write("class StatusCode(Enum):\n")
outputfile.write(" Good = 0\n")
......
......@@ -5,9 +5,9 @@ def extensionobject_from_binary(data):
Returns an object, or None if TypeId is zero
"""
TypeId = NodeId.from_binary(data)
Encoding = unpack_uatype('UInt8', data)
Encoding = ord(data.read(1))
if Encoding & (1 << 0):
Body = unpack_uatype('ByteString', data)
Body = unpack_bytes(data)
if TypeId.Identifier == 0:
return None
klass = ExtensionClasses[TypeId.Identifier]
......@@ -29,7 +29,7 @@ def extensionobject_to_binary(obj):
Body = obj.to_binary()
packet = []
packet.append(TypeId.to_binary())
packet.append(pack_uatype('UInt8', Encoding))
packet.append(uatype_UInt8.pack(Encoding))
if Body:
packet.append(pack_uatype('ByteString', Body))
packet.append(pack_bytes(Body))
return b''.join(packet)
......@@ -225,7 +225,7 @@ class Unit(unittest.TestCase):
dv = ua.DataValue('abc')
self.assertEqual(dv.Value, ua.Variant('abc'))
now = datetime.now()
dv.source_timestamp = now
dv.SourceTimestamp = now
def test_variant(self):
dv = ua.Variant(True, ua.VariantType.Boolean)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment