def process(self, header, body): if header.MessageType == ua.MessageType.Hello: hello = ua.Hello.from_binary(body) hdr = ua.Header(ua.MessageType.Acknowledge, ua.ChunkType.Single) ack = ua.Acknowledge() ack.ReceiveBufferSize = hello.ReceiveBufferSize ack.SendBufferSize = hello.SendBufferSize self._write_socket(hdr, ack) elif header.MessageType == ua.MessageType.Error: self.logger.warning("Received an error message type") elif header.MessageType == ua.MessageType.SecureOpen: self.open_secure_channel(body) elif header.MessageType == ua.MessageType.SecureClose: if not self.channel or header.ChannelId != self.channel.SecurityToken.ChannelId: self.logger.warning("Request to close channel %s which was not issued, current channel is %s", header.ChannelId, self.channel) return False elif header.MessageType == ua.MessageType.SecureMessage: algohdr = ua.SymmetricAlgorithmHeader.from_binary(body) seqhdr = ua.SequenceHeader.from_binary(body) return self.process_message(algohdr, seqhdr, body) else: self.logger.warning("Unsupported message type: %s", header.MessageType) return True
def uatcp_to_binary(message_type, message): """ Convert OPC UA TCP message (see OPC UA specs Part 6, 7.1) to binary. The only supported types are Hello, Acknowledge and ErrorMessage """ header = ua.Header(message_type, ua.ChunkType.Single) binmsg = struct_to_binary(message) header.body_size = len(binmsg) return header_to_binary(header) + binmsg
def send_response(self, requesthandle, algohdr, seqhdr, response, msgtype=ua.MessageType.SecureMessage): with self._socketlock: response.ResponseHeader.RequestHandle = requesthandle seqhdr.SequenceNumber = self._seq_number self._seq_number += 1 hdr = ua.Header(msgtype, ua.ChunkType.Single, self.channel.SecurityToken.ChannelId) if isinstance(algohdr, ua.SymmetricAlgorithmHeader): algohdr.TokenId = self.channel.SecurityToken.TokenId self._write_socket(hdr, algohdr, seqhdr, response)
def header_from_binary(data): hdr = ua.Header() hdr.MessageType, hdr.ChunkType, hdr.packet_size = struct.unpack( "<3scI", data.read(8)) hdr.body_size = hdr.packet_size - 8 if hdr.MessageType in (ua.MessageType.SecureOpen, ua.MessageType.SecureClose, ua.MessageType.SecureMessage): hdr.body_size -= 4 hdr.ChannelId = Primitives.UInt32.unpack(data) return hdr
def __init__(self, security_policy, body=b'', msg_type=ua.MessageType.SecureMessage, chunk_type=ua.ChunkType.Single): self.MessageHeader = ua.Header(msg_type, chunk_type) if msg_type in (ua.MessageType.SecureMessage, ua.MessageType.SecureClose): self.SecurityHeader = ua.SymmetricAlgorithmHeader() elif msg_type == ua.MessageType.SecureOpen: self.SecurityHeader = ua.AsymmetricAlgorithmHeader() else: raise ua.UaError("Unsupported message type: {0}".format(msg_type)) self.SequenceHeader = ua.SequenceHeader() self.Body = body self.security_policy = security_policy
def error_message_to_binary(message): header = ua.Header(ua.MessageType.Error, ua.ChunkType.Single) body = struct_to_binary(message) header.body_size = len(body) return header_to_binary(header) + body