class Main(object): def __init__(self): self.monitor = None try: # instanciates the config self.config = Config() # exists baboon when receiving a sigint signal signal.signal(signal.SIGINT, self.sigint_handler) # Initialize the scm class to use scm_classes = Diffman.__subclasses__() for cls in scm_classes: tmp_inst = cls() if tmp_inst.scm_name == self.config.scm: self.diffman = tmp_inst # TODO verify self.diffman self.mediator = Mediator(self.diffman) self.transport = Transport(self.mediator) self.transport.open() self.monitor = Monitor(self.transport, self.diffman) self.monitor.watch() # TODO this won't work on windows... signal.pause() except BaboonException, err: sys.stderr.write("%s\n" % err) # Try to close the transport properly. If the transport is # not correctly started, the close() method has no effect. self.transport.close() # Same thing for the monitor if self.monitor: self.monitor.close() # Exits with a fail return code sys.exit(1)
class Player(object): auth_timeout = 5 def __init__(self, socket, address): self.transport = Transport(socket, address) self.host = address[0] self.port = address[1] self.health = 100 def close(self): self.transport.send(Message.exit().pack()) self.transport.close() def auth(self): recv = None with Timeout(Player.auth_timeout, PlayerError("Authentication timed out")): try: msg = self.transport.receive() except PlayerError as e: print("error on receive") print(e) return False try: msg = Message.parse(msg) except MessageError: print("bad message") return False if msg.type == "nick": self.name = msg.payload self.transport.send(Message.auth_success().pack()) return True return False def listen(self): return self.transport.receive() def send(self, msg): self.transport.send(msg)
class Player(object): auth_timeout = 5 def __init__(self, socket, address): self.transport = Transport(socket, address) self.host = address[0] self.port = address[1] self.health = 100 def close(self): self.transport.send(Message.exit().pack()) self.transport.close() def auth(self): recv = None with Timeout(Player.auth_timeout, PlayerError("Authentication timed out")): try: msg = self.transport.receive() except PlayerError as e: print("error on receive") print(e) return False try: msg = Message.parse(msg) except MessageError: print("bad message") return False if msg.type == "nick": self.name = msg.payload self.transport.send(Message.auth_success().pack()) return True return False def listen(self): return self.transport.receive() def send(self, msg): self.transport.send(msg)
class ServerConnection(object): def __init__(self, host, port, key, app, service, topic, lang, format, uuid, inter_utt_silence, cmn_latency, logger=None, punctuation=True, ipv4=False, capitalize=False, expected_num_count=0): self.host = host self.port = port self.key = key self.app = app self.topic = topic self.service = service self.lang = lang self.format = format self.uuid = uuid self.logger = logger self.punctuation = punctuation self.inter_utt_silence = inter_utt_silence self.cmn_latency = cmn_latency self.ipv4 = ipv4 self.capitalize = capitalize self.expected_num_count = expected_num_count self.log("uuid={0}".format(self.uuid)) self.session_id = "not-set" self.connect() def log(self, message): if self.logger is not None: self.logger.info(message) def connect(self): self.t = Transport(self.host, self.port, timeout=None, verbose=False, enable_ssl=(self.port == 443), ipv4=self.ipv4) if not self.upgrade_connection(): raise ServerError('Unable to upgrade connection') self.log("Connected to {0}:{1}.".format(self.host, self.port)) response = self.send_init_request() if response.responseCode != 200: error_text = 'Wrong response from server, status_code={0}'.format( response.responseCode) if response.HasField("message"): error_text += ', message is "{0}"'.format(response.message) raise ServerError(error_text) self.session_id = response.sessionId self.log("session_id={0}".format(self.session_id)) return self.session_id def send_init_request(self): request = ConnectionRequest( speechkitVersion='', serviceName=self.service, uuid=self.uuid, apiKey=self.key, applicationName=self.app, device='desktop', coords='0, 0', topic=self.topic, lang=self.lang, format=self.format, punctuation=self.punctuation, advancedASROptions=AdvancedASROptions( utterance_silence=int(self.inter_utt_silence), cmn_latency=self.cmn_latency, capitalize=self.capitalize, expected_num_count=self.expected_num_count, biometry="children", )) self.t.sendProtobuf(request) return self.t.recvProtobuf(ConnectionResponse) def upgrade_connection(self): logger = logging.getLogger('arslib') request = ('GET /asr_partial_checked HTTP/1.1\r\n' 'User-Agent: {user_agent}\r\n' 'Host: {host}:{port}\r\n' 'Upgrade: {service}\r\n\r\n').format(user_agent=self.app, host=self.host, port=self.port, service=self.service) self.t.send(request) check = 'HTTP/1.1 101 Switching Protocols' buffer = '' # possible infinite loop here? while True: buffer += self.t.recv(1) if buffer.startswith(check) and buffer.endswith('\r\n\r\n'): return True if len(buffer) > 300: logger.warning(buffer) return False def close(self): self.session_id = "" self.t.close() def reconnect(self, delay=None): self.log('Reconnecting!') self.close() if delay is not None: self.log('Going to sleep for {0} seconds'.format(delay)) time.sleep(delay) self.connect() def add_data(self, chunk): if chunk is None: self.t.sendProtobuf(AddData(lastChunk=True)) else: self.t.sendProtobuf(AddData(lastChunk=False, audioData=chunk)) def get_response_if_ready(self): response = self.t.recvProtobufIfAny(AddDataResponse) if response is not None: if response.responseCode != 200: error_text = 'Wrong response from server, status_code={0}'.format( response.responseCode) if response.HasField("message"): error_text += ', message is "{0}"'.format(response.message) raise ServerError(error_text) return response
class ServerConnection(object): def __init__(self, host, port, key, app, service, topic, lang, format, logger=None, punctuation=True): self.host = host self.port = port self.key = key self.app = app self.topic = topic self.service = service self.lang = lang self.format = format self.uuid = randomUuid().hex self.logger = logger self.punctuation = punctuation self.log("uuid={0}".format(self.uuid)) self.session_id = "" self.connect() def log(self, message): if self.logger is not None: self.logger.info(message) def connect(self): self.t = Transport(self.host, self.port, timeout=None, verbose=False) if not self.upgrade_connection(): raise ServerError('Unable to upgrade connection') self.log("Connected to {0}:{1}.".format(self.host, self.port)) response = self.send_init_request() if response.responseCode != 200: error_text = 'Wrong response from server, status_code={0}'.format( response.responseCode) if response.HasField("message"): error_text += ', message is "{0}"'.format(response.message) raise ServerError(error_text) self.session_id = response.sessionId self.log("session_id={0}".format(self.session_id)) return self.session_id def send_init_request(self): request = ConnectionRequest( speechkitVersion='Not Speechkit', serviceName=self.service, uuid=self.uuid, apiKey=self.key, applicationName=self.app, device='desktop', coords='0, 0', topic=self.topic, lang=self.lang, format=self.format, punctuation=self.punctuation) self.t.sendProtobuf(request) return self.t.recvProtobuf(ConnectionResponse) def upgrade_connection(self): logger = logging.getLogger('arslib') request = ('GET /asr_partial_checked HTTP/1.1\r\n' 'User-Agent: {user_agent}\r\n' 'Host: {host}:{port}\r\n' 'Upgrade: {service}\r\n\r\n').format( user_agent=self.app, host=self.host, port=self.port, service=self.service) self.t.send(request) check = 'HTTP/1.1 101 Switching Protocols' buffer = '' # possible infinite loop here? while True: buffer += self.t.recv(1) if buffer.startswith(check) and buffer.endswith('\r\n\r\n'): return True if len(buffer) > 300: logger.warning(buffer) return False def close(self): self.session_id = "" self.t.close() def reconnect(self, delay=None): self.log('Reconnecting!') self.close() if delay is not None: self.log('Going to sleep for {0} seconds'.format(delay)) time.sleep(delay) self.connect() def add_data(self, chunk): if chunk is None: self.t.sendProtobuf(AddData(lastChunk=True)) else: self.t.sendProtobuf(AddData(lastChunk=False, audioData=chunk)) def get_utterance_if_ready(self): response = self.t.recvProtobufIfAny(AddDataResponse) if response is not None: if response.responseCode != 200: error_text = 'Wrong response from server, status_code={0}'.format( response.responseCode) if response.HasField("message"): error_text += ', message is "{0}"'.format(response.message) raise ServerError(error_text) self.log("got response: endOfUtt={0}; len(recognition)={1}".format(response.endOfUtt, len(response.recognition))) if len(response.recognition) == 0: return "", response.messagesCount text = response.recognition[0].normalized.encode('utf-8') merged = response.messagesCount self.log("partial result: {0}; merged={1}".format(text, merged)) if response.endOfUtt: return text, merged else: return "", response.messagesCount return None, 0
class ServerConnection(object): def __init__(self, host, port, key, app, service, topic, lang, format, uuid, inter_utt_silence, cmn_latency, logger=None, punctuation=True, ipv4=False, capitalize=False, expected_num_count=0): self.host = host self.port = port self.key = key self.app = app self.topic = topic self.service = service self.lang = lang self.format = format self.uuid = uuid self.logger = logger self.punctuation = punctuation self.inter_utt_silence = inter_utt_silence self.cmn_latency = cmn_latency self.ipv4 = ipv4 self.capitalize = capitalize self.expected_num_count = expected_num_count self.log("uuid={0}".format(self.uuid)) self.session_id = "not-set" self.connect() def log(self, message): if self.logger is not None: self.logger.info(message) def connect(self): self.t = Transport(self.host, self.port, timeout=None, verbose=False, enable_ssl=(self.port==443), ipv4=self.ipv4) if not self.upgrade_connection(): raise ServerError('Unable to upgrade connection') self.log("Connected to {0}:{1}.".format(self.host, self.port)) response = self.send_init_request() if response.responseCode != 200: error_text = 'Wrong response from server, status_code={0}'.format( response.responseCode) if response.HasField("message"): error_text += ', message is "{0}"'.format(response.message) raise ServerError(error_text) self.session_id = response.sessionId self.log("session_id={0}".format(self.session_id)) return self.session_id def send_init_request(self): request = ConnectionRequest( speechkitVersion='', serviceName=self.service, uuid=self.uuid, apiKey=self.key, applicationName=self.app, device='desktop', coords='0, 0', topic=self.topic, lang=self.lang, format=self.format, punctuation=self.punctuation, advancedASROptions=AdvancedASROptions( utterance_silence=int(self.inter_utt_silence), cmn_latency=self.cmn_latency, capitalize=self.capitalize, expected_num_count=self.expected_num_count, biometry="children", ) ) self.t.sendProtobuf(request) return self.t.recvProtobuf(ConnectionResponse) def upgrade_connection(self): logger = logging.getLogger('arslib') request = ('GET /asr_partial_checked HTTP/1.1\r\n' 'User-Agent: {user_agent}\r\n' 'Host: {host}:{port}\r\n' 'Upgrade: {service}\r\n\r\n').format( user_agent=self.app, host=self.host, port=self.port, service=self.service) self.t.send(request) check = 'HTTP/1.1 101 Switching Protocols' buffer = '' # possible infinite loop here? while True: buffer += self.t.recv(1) if buffer.startswith(check) and buffer.endswith('\r\n\r\n'): return True if len(buffer) > 300: logger.warning(buffer) return False def close(self): self.session_id = "" self.t.close() def reconnect(self, delay=None): self.log('Reconnecting!') self.close() if delay is not None: self.log('Going to sleep for {0} seconds'.format(delay)) time.sleep(delay) self.connect() def add_data(self, chunk): if chunk is None: self.t.sendProtobuf(AddData(lastChunk=True)) else: self.t.sendProtobuf(AddData(lastChunk=False, audioData=chunk)) def get_response_if_ready(self): response = self.t.recvProtobufIfAny(AddDataResponse) if response is not None: if response.responseCode != 200: error_text = 'Wrong response from server, status_code={0}'.format( response.responseCode) if response.HasField("message"): error_text += ', message is "{0}"'.format(response.message) raise ServerError(error_text) return response
class SshEngine: logger = logging.getLogger(__name__) client_version = "SSH-2.0-python_tim&henry_0.1" def __init__(self, user_name, server_name, port=22): self.user_name = user_name self.server_name = server_name self.port = port self.server_version = None self.socket = None self.server_key = None self._session_id = None self._userauth_reply = None @property def session_id(self): """The session identifier. If the session is not currently initialized, None.""" return self._session_id def __enter__(self): # Start transport layer self.socket = Transport() self.socket.connect((self.server_name, self.port)) # Start SSH connection self.version_exchange() self.key_exchange() self.init_authentication() return self def __exit__(self, exc_type, exc_val, exc_tb): self.close() def close(self): self.socket.close() def version_exchange(self): self.server_version = self.socket.exchange_versions( self.client_version) def key_exchange(self): """Do a whole key exchange, as described in RFC 4253""" self.logger.info("Exchange key mechanism activated...") # Generate a dh object for the key exchange and pick a random session cookie self.dh = asym_algos.EcdhSha2Nistp256() cookie = os.urandom(16) # Key Exchange Init: exchange the supported crypto algorithms, first algo in list is preferred one client_kexinit = KexInit(cookie=cookie, kex_algo=("ecdh-sha2-nistp256", ), server_host_key_algo=tuple( AuthenticationKey.known_key_types.keys()), encryption_algo_ctos=("aes128-ctr", ), encryption_algo_stoc=("aes128-ctr", ), mac_algo_ctos=("hmac-sha2-256", ), mac_algo_stoc=("hmac-sha2-256", ), compression_algo_ctos=("none", ), compression_algo_stoc=("none", ), languages_ctos=(), languages_stoc=(), first_kex_packet_follows=False) self.socket.send_ssh_msg(client_kexinit) server_kexinit = self.socket.recv_ssh_msg() if not isinstance(server_kexinit, KexInit): raise Exception("First packet is not a KEI packet") self.logger.info("Key Exchange Init phase: ok") # Key Exchange Diffie-Hellman: create a shared secret client_kex_ecdh = KexDHInit( e=asym_algos.EcdhSha2Nistp256.to_point_encoding( self.dh.client_ephemeral_public_key)) self.socket.send_ssh_msg(client_kex_ecdh) server_kex_ecdh = self.socket.recv_ssh_msg() if not isinstance(server_kex_ecdh, KexDHReply): raise Exception("not a KEXDH_REPLY packet") self.server_key = AuthenticationKey.from_blob( server_kex_ecdh.server_public_key) kex_hash_algo = hash_algos.Sha256( ) # Currently forced. TODO: make it modifiable # construct a 'public key' object from the received server public key self.dh.server_ephemeral_public_key = \ ec.EllipticCurvePublicKey.from_encoded_point(self.dh.curve, server_kex_ecdh.f) # multiply server's ephemeral public key with client's ephemeral private key --> shared secret shared_secret = self.dh.compute_shared_secret() self.logger.info("Key Exchange Diffie-Hellman phase: ok") # Compute exchange hash class ExchangeHash(BinarySshPacket): # Not really a SSH packet, but we use the same method to get the payload. __slots__ = ('client_version', 'server_version', 'client_kexinit', 'server_kexinit', 'host_key', 'client_exchange_value', 'server_exchange_value', 'shared_secret') _field_types = (StringType('ascii'), StringType('ascii'), StringType('octet'), StringType('octet'), StringType('octet'), StringType('octet'), StringType('octet'), MpintType()) client_kexinit_bytes = client_kexinit.msg_type.to_bytes( 1, 'big') + client_kexinit.payload() server_kexinit_bytes = server_kexinit.msg_type.to_bytes( 1, 'big') + server_kexinit.payload() to_be_hashed = ExchangeHash(client_version=self.client_version, server_version=self.server_version, client_kexinit=client_kexinit_bytes, server_kexinit=server_kexinit_bytes, host_key=server_kex_ecdh.server_public_key, client_exchange_value=client_kex_ecdh.e, server_exchange_value=server_kex_ecdh.f, shared_secret=int.from_bytes(shared_secret, 'big', signed=False)) key_exchange_hash = kex_hash_algo.hash(to_be_hashed.payload()) # Set the session ID: # > The exchange hash H from the first key exchange is additionally # > used as the session identifier [...] Once computed, the session # > identifier is not changed, even if keys are later re-exchanged # > [RFC4253] if self._session_id is None: self._session_id = key_exchange_hash # Verify server's signature server_public_key_iterator = server_kex_ecdh.server_public_key.__iter__( ) key_type = fields.StringType('ascii').from_bytes( server_public_key_iterator) # TODO: support other key types. Here, only ssh-rsa keys are supported. assert key_type == 'ssh-rsa' rsa_exponent = fields.MpintType().from_bytes( server_public_key_iterator) rsa_modulus = fields.MpintType().from_bytes(server_public_key_iterator) server_key = rsa.RSAPublicNumbers( e=rsa_exponent, n=rsa_modulus).public_key(default_backend()) server_signature_iterator = server_kex_ecdh.signature.__iter__() key_type = fields.StringType('ascii').from_bytes( server_signature_iterator) # TODO: support other key types. Here, only ssh-rsa keys are supported. assert key_type == 'ssh-rsa' signature = fields.StringType('octet').from_bytes( server_signature_iterator) server_key.verify(signature, key_exchange_hash, padding.PKCS1v15(), hashes.SHA1()) self.logger.info("Server signature verification: ok") # New Keys: switch to the new cyphering method self.socket.send_ssh_msg(NewKeys()) nk = self.socket.recv_ssh_msg() if not isinstance(nk, NewKeys): raise Exception("not a NEWKEYS packet") # Activate the encryption self.socket.change_keys(kex_hash_algo, shared_secret, key_exchange_hash, self.session_id) self.logger.info("Keys and algorithms change: ok") def init_authentication(self): # Request the authentication service service_request = ServiceRequest(service_name=ServiceName.USERAUTH) self.socket.send_ssh_msg(service_request) service_accept = self.socket.recv_ssh_msg() if not isinstance(service_accept, ServiceAccept): raise Exception("not a ServiceAccept message") if service_request.service_name != service_accept.service_name: raise Exception( "The server did not provide the expected service (%s), but provided %s instead." % (service_request.service_name, service_accept.service_name)) self.logger.debug("Service %s accepted by the server" % service_accept.service_name) def authenticate_with_public_key(self, public_key): """Try a fake authentication with a public key, without signing the message. :return True if the an authentication with this key would be accepted by the server (but is currently accepted, as we have not signed the message).""" if not self.is_authentication_method_supported(MethodName.PUBLICKEY): return False userauth_request = UserauthRequestPublicKey( user_name=self.user_name, service_name=ServiceName.CONNECTION, method_name=MethodName.PUBLICKEY, signed=False, algorithm_name=public_key.algo_name, blob=public_key.public_blob()) self.socket.send_ssh_msg(userauth_request) userauth_reply = self.socket.recv_ssh_msg() return userauth_reply.msg_type == SshMsgType.USERAUTH_PK_OK def is_authentication_method_supported(self, method): """Check if the authentication method is supported. If no UserauthFailure is received yet, suppose that this authentication is supported. If we guess wrong, remote server will provide the needed list of supported authentication methods.""" if self._userauth_reply is None: return True # Suppose that yes… return method in self._userauth_reply.authentications_that_can_continue def authenticate(self, password=None, private_key=None): # Compute the correct UserauthRequest if password is not None and \ self.is_authentication_method_supported(MethodName.PASSWORD): userauth_request = UserauthRequestPassword( user_name=self.user_name, service_name=ServiceName.CONNECTION, method_name=MethodName.PASSWORD, change_password=False, password=password) elif private_key is not None and \ self.is_authentication_method_supported(MethodName.PUBLICKEY): userauth_request = UserauthRequestPublicKey( user_name=self.user_name, service_name=ServiceName.CONNECTION, method_name=MethodName.PUBLICKEY, signed=False, algorithm_name=private_key.algo_name, blob=private_key.public_blob()) userauth_request.sign(self._session_id, private_key) else: userauth_request = UserauthRequestNone( user_name=self.user_name, service_name=ServiceName.CONNECTION) # Send & receive authentication messages self.socket.send_ssh_msg(userauth_request) userauth_reply = self.socket.recv_ssh_msg() if not isinstance(userauth_reply, (UserauthFailure, UserauthSuccess)): raise Exception("Unexpected packet type here!") self._userauth_reply = userauth_reply return isinstance(self._userauth_reply, UserauthSuccess) def is_authenticated(self): return isinstance(self._userauth_reply, UserauthSuccess) def _open_channel(self): local_channel_identifier = 1 # Should certainly be fixed later! # Open the channel channel_open = ChannelOpen(channel_type="session", sender_channel=local_channel_identifier, initial_window_size=2**16 - 1, maximum_packet_size=256) self.socket.send_ssh_msg(channel_open) open_confirmation = self.socket.recv_ssh_msg() if isinstance(open_confirmation, ChannelOpenFailure): raise Exception("Unable to open channel") # Request a pseudo-terminal # channel_request = ChannelRequestPTY( # recipient_channel=open_confirmation.sender_channel, # want_reply=False, # TERM="xterm-256color", # terminal_width_ch=80, # terminal_height_ch=24, # terminal_width_px=0, # terminal_height_px=0, # encoded_terminal_modes=((ChannelRequestPTY.EncodedTerminalModes.IMAXBEL, 0),)) # self.socket.send_ssh_msg(channel_request) # Request a shell channel_request = ChannelRequestShell( recipient_channel=open_confirmation.sender_channel, want_reply=False) self.socket.send_ssh_msg(channel_request) print(repr(self.socket.recv_ssh_msg())) # WindowAdjust print(repr(self.socket.recv_ssh_msg())) # ExtendedData # Send a command while True: readable, _, _ = select.select((self.socket, sys.stdin), (), ()) if sys.stdin in readable: command_str = sys.stdin.readline() command = ChannelData( recipient_channel=open_confirmation.sender_channel, data=command_str.encode('ascii')) self.socket.send_ssh_msg(command) if self.socket in readable: msg = self.socket.recv_ssh_msg() print(repr(msg)) if isinstance( msg, ChannelClose ) and msg.recipient_channel == local_channel_identifier: msg = ChannelClose( recipient_channel=open_confirmation.sender_channel) self.socket.send_ssh_msg(msg) break
class ServerConnection(object): def __init__(self, host, port, key, app, service, topic, lang, format, logger=None): self.host = host self.port = port self.key = key self.app = app self.topic = topic self.service = service self.lang = lang self.format = format self.uuid = randomUuid().hex self.logger = logger self.log("uuid={0}".format(self.uuid)) self.session_id = "" self.connect() def log(self, message): if self.logger is not None: self.logger.info(message) def connect(self): self.t = Transport(self.host, self.port, timeout=None, verbose=False) if not self.upgrade_connection(): raise ServerError('Unable to upgrade connection') self.log("Connected to {0}:{1}.".format(self.host, self.port)) response = self.send_init_request() if response.responseCode != 200: error_text = 'Wrong response from server, status_code={0}'.format( response.responseCode) if response.HasField("message"): error_text += ', message is "{0}"'.format(response.message) raise ServerError(error_text) self.session_id = response.sessionId self.log("session_id={0}".format(self.session_id)) return self.session_id def send_init_request(self): request = ConnectionRequest( speechkitVersion='Not Speechkit', serviceName=self.service, uuid=self.uuid, apiKey=self.key, applicationName=self.app, device='desktop', coords='0, 0', topic=self.topic, lang=self.lang, format=self.format) self.t.sendProtobuf(request) return self.t.recvProtobuf(ConnectionResponse) def upgrade_connection(self): logger = logging.getLogger('arslib') request = ('GET /asr_partial_checked HTTP/1.1\r\n' 'User-Agent: {user_agent}\r\n' 'Host: {host}:{port}\r\n' 'Upgrade: {service}\r\n\r\n').format( user_agent=self.app, host=self.host, port=self.port, service=self.service) self.t.send(request) check = 'HTTP/1.1 101 Switching Protocols' buffer = '' # possible infinite loop here? while True: buffer += self.t.recv(1) if buffer.startswith(check) and buffer.endswith('\r\n\r\n'): return True if len(buffer) > 300: logger.warning(buffer) return False def close(self): self.session_id = "" self.t.close() def reconnect(self, delay=None): self.log('Reconnecting!') self.close() if delay is not None: self.log('Going to sleep for {0} seconds'.format(delay)) time.sleep(delay) self.connect() def add_data(self, chunk): if chunk is None: self.t.sendProtobuf(AddData(lastChunk=True)) else: self.t.sendProtobuf(AddData(lastChunk=False, audioData=chunk)) def get_utterance_if_ready(self): response = self.t.recvProtobufIfAny(AddDataResponse) if response is not None: if response.responseCode != 200: error_text = 'Wrong response from server, status_code={0}'.format( response.responseCode) if response.HasField("message"): error_text += ', message is "{0}"'.format(response.message) raise ServerError(error_text) self.log("got response: endOfUtt={0}; len(recognition)={1}".format(response.endOfUtt, len(response.recognition))) if len(response.recognition) == 0: return "", response.messagesCount text = response.recognition[0].normalized.encode('utf-8') merged = response.messagesCount self.log("partial result: {0}; merged={1}".format(text, merged)) if response.endOfUtt: return text, merged else: return "", response.messagesCount return None, 0
class MicroNFCBoard(object): @staticmethod def getBoard(number = 0): a = INTERFACE[usb_backend].getAllConnectedInterface(VID, PID) if((a != None) and (len(a) > number)): return MicroNFCBoard(a[number]) return None @staticmethod def getAllBoards(): return [MicroNFCBoard(i) for i in INTERFACE[usb_backend].getAllConnectedInterface(VID, PID)] def __init__(self, intf): self._intf = intf self._transport = Transport() self._id = None self._version = None self._polling = False self._connected = False self._ndefMessagePresent = False self._ndefRecords = None self._ndefRead = False def open(self): self._transport.open(self._intf) version, revision, self._id = self._transport.info() self._version = (version, revision) def close(self): self._transport.close() @property def id(self): return self._id @property def connected(self): self._updateStatus() return self._connected @property def polling(self): self._updateStatus() return self._polling @property def ndefMessagePresent(self): self._updateStatus() return self._ndefMessagePresent @property def ndefRecords(self): self._updateStatus() if self._ndefMessagePresent and not self._ndefRead: self._ndefRecords = self._getNdefMessageRecords() self._ndefRecordsRead = True return self._ndefRecords @property def version(self): return self._version def getNfcInfo(self): return self._transport.nfcGetInfo() def reset(self): self._transport.reset(False) def startPolling(self): self._transport.nfcPoll(True) def stopPolling(self): self._transport.nfcPoll(True) def setLeds(self, led1, led2): self._transport.leds(led1, led2) def _updateStatus(self): status = self._transport.status() self._polling = (status & STATUS_POLLING) != 0 self._connected = (status & STATUS_CONNECTED) != 0 self._ndefMessagePresent = (status & STATUS_NDEF_PRESENT) != 0 if not self._ndefMessagePresent: self._ndefRecordsRead = False def _getNdefRecords(self, start, count): records = [] for recordNumber in range(start, start+count): #Get records info recordType, recordInfo = self._transport.nfcGetRecordInfo(recordNumber) funcs = { 0 : self._parseUnknownRecord, 1 : self._parseURIRecord, 2 : self._parseTextRecord, 3 : self._parseSmartPosterRecord, 4 : self._parseMIMERecord, } record = funcs[recordType](recordNumber, recordInfo) if record != None: records += [record] return records def _getNdefMessageRecords(self): #Get message count recordsCount = self._transport.nfcGetMessageInfo() return self._getNdefRecords(0, recordsCount) def _parseUnknownRecord(self, recordNumber, recordInfo): return None def _parseURIRecord(self, recordNumber, recordInfo): uriLength = recordInfo[0] uri = unicode(self._getRecordData(recordNumber, 0, uriLength).tostring(), "utf-8") return URIRecord(uri) def _parseTextRecord(self, recordNumber, recordInfo): encoding = TEXT_ENCODING[recordInfo[0]] languageCodeLength = recordInfo[1] textLength = recordInfo[2] languageCode = unicode(self._getRecordData(recordNumber, 0, languageCodeLength).tostring(), "utf-8") text = unicode(self._getRecordData(recordNumber, 1, textLength).tostring(), encoding) return TextRecord(text, languageCode) def _parseSmartPosterRecord(self, recordNumber, recordInfo): recordsStart = recordInfo[0] recordsCount = recordInfo[1] records = self._getNdefRecords(recordsStart, recordsCount) return SmartPosterRecord(records) def _parseMIMERecord(self, recordNumber, recordInfo): mimeTypeLength = recordInfo[0] dataLength = recordInfo[1] mimeType = unicode(self._getRecordData(recordNumber, 0, mimeTypeLength).tostring(), "utf-8") data = self._getRecordData(recordNumber, 1, dataLength) return MIMERecord(mimeType, data) def _getRecordData(self, recordNumber, item, itemLength): buf = array("B") while len(buf) < itemLength: chunkLength = min(CHUNK_SIZE, itemLength - len(buf)) buf += self._transport.nfcGetRecordData(recordNumber, item, len(buf), chunkLength) return buf
class MicroNFCBoard(object): @staticmethod def getBoard(number = 0): a = INTERFACE[usb_backend].getAllConnectedInterface(VID, PID) if((a != None) and (len(a) > number)): return MicroNFCBoard(a[number]) return None @staticmethod def getAllBoards(): return [MicroNFCBoard(i) for i in INTERFACE[usb_backend].getAllConnectedInterface(VID, PID)] def __init__(self, intf): self._intf = intf self._transport = Transport() self._id = None self._version = None self._polling = False self._connected = False self._type2 = False self._type4 = False self._p2p = False self._initiator = False self._ndefPresent = False self._ndefRecords = None self._ndefRead = False self._ndefReadable = False self._ndefWriteable = False self._ndefBusy = False self._ndefSuccess = False def open(self): self._transport.open(self._intf) version, revision, self._id = self._transport.info() self._version = (version, revision) if( self._version < TARGET_FIRMWARE ): #self._transport.reset(True) raise FirmwareUpgradeRequiredException("Your current firmware (version %d.%d) is outdated; please upgrade it to version %d.%d" % (version, revision, TARGET_FIRMWARE[0], TARGET_FIRMWARE[1])) def close(self): self._transport.close() @property def id(self): return self._id @property def connected(self): self._updateStatus() return self._connected @property def type2Tag(self): self._updateStatus() return self._type2 and self._initiator @property def type4Emulator(self): self._updateStatus() return self._type4 and not self._initiator @property def p2p(self): self._updateStatus() return self._p2p @property def polling(self): self._updateStatus() return self._polling @property def ndefReadable(self): self._updateStatus() return self._ndefReadable @property def ndefWriteable(self): self._updateStatus() return self._ndefWriteable @property def ndefPresent(self): self._updateStatus() return self._ndefPresent @property def ndefBusy(self): self._updateStatus() return self._ndefBusy @property def ndefSuccess(self): self._updateStatus() return self._ndefSuccess @property def ndefRecords(self): self._updateStatus() if self._ndefPresent and not self._ndefRead: self._ndefRecords = self._getNdefMessageRecords() self._ndefRead = True return self._ndefRecords @ndefRecords.setter def ndefRecords(self, records): self._updateStatus() self._ndefRecords = records #Push them to device self._setNdefRecords(self._ndefRecords) @property def version(self): return self._version def getNfcInfo(self): return self._transport.nfcGetInfo() def reset(self): self._transport.reset(False) def startPolling(self, readerWriter, emulator, p2p): self._transport.nfcPoll(readerWriter, emulator, p2p) def stopPolling(self): self._transport.nfcPoll(False, False, False) def ndefRead(self): self._transport.nfcOperation(True, False) def ndefWrite(self): self._transport.nfcOperation(False, True) def setLeds(self, led1, led2): self._transport.leds(led1, led2) def _updateStatus(self): status = self._transport.status() self._polling = (status & STATUS_POLLING) != 0 self._connected = (status & STATUS_CONNECTED) != 0 self._ndefPresent = (status & STATUS_NDEF_PRESENT) != 0 self._ndefReadable = (status & STATUS_NDEF_READABLE) != 0 self._ndefWriteable = (status & STATUS_NDEF_WRITEABLE) != 0 self._ndefBusy = (status & STATUS_NDEF_BUSY) != 0 self._ndefSuccess = (status & STATUS_NDEF_SUCCESS) != 0 self._type2 = (status & STATUS_TYPE_MASK) == STATUS_TYPE2 self._type4 = (status & STATUS_TYPE_MASK) == STATUS_TYPE4 self._p2p = (status & STATUS_TYPE_MASK) == STATUS_P2P self._initiator = (status & STATUS_INITIATOR) != 0 if not self._ndefPresent: self._ndefRead = False self._ndefRecords = None def _getNdefRecords(self, start, count): records = [] for recordNumber in range(start, start+count): #Get records info recordType, recordInfo = self._transport.nfcGetRecordInfo(recordNumber) funcs = { 0 : self._parseUnknownRecord, 1 : self._parseURIRecord, 2 : self._parseTextRecord, 3 : self._parseSmartPosterRecord, 4 : self._parseMIMERecord, } record = funcs[recordType](recordNumber, recordInfo) if record != None: records += [record] return records def _getNdefMessageRecords(self): #Get message count recordsCount = self._transport.nfcGetMessageInfo() return self._getNdefRecords(0, recordsCount) def _parseUnknownRecord(self, recordNumber, recordInfo): return None def _parseURIRecord(self, recordNumber, recordInfo): uriPrefix = recordInfo[0] uriLength = recordInfo[1] uri = unicode(self._decodePrefix(uriPrefix).tostring() + self._getRecordData(recordNumber, 0, uriLength).tostring(), "utf-8") return URIRecord(uri) def _parseTextRecord(self, recordNumber, recordInfo): encoding = TEXT_ENCODING[recordInfo[0]] languageCodeLength = recordInfo[1] textLength = recordInfo[2] languageCode = unicode(self._getRecordData(recordNumber, 0, languageCodeLength).tostring(), "utf-8") text = unicode(self._getRecordData(recordNumber, 1, textLength).tostring(), encoding) return TextRecord(text, languageCode, encoding) def _parseSmartPosterRecord(self, recordNumber, recordInfo): recordsStart = recordInfo[0] recordsCount = recordInfo[1] records = self._getNdefRecords(recordsStart, recordsCount) return SmartPosterRecord(records) def _parseMIMERecord(self, recordNumber, recordInfo): mimeTypeLength = recordInfo[0] dataLength = recordInfo[1] mimeType = unicode(self._getRecordData(recordNumber, 0, mimeTypeLength).tostring(), "utf-8") data = self._getRecordData(recordNumber, 1, dataLength) return MIMERecord(mimeType, data) def _decodePrefix(self, prefix): return self._transport.nfcDecodePrefix(prefix) def _getRecordData(self, recordNumber, item, itemLength): buf = array("B") while len(buf) < itemLength: chunkLength = min(CHUNK_SIZE, itemLength - len(buf)) buf += self._transport.nfcGetRecordData(recordNumber, item, len(buf), chunkLength) return buf def _setNdefRecords(self, records): self._transport.nfcPrepareMessage(True, False) recordNumber = 0 spRecordNumber = len(records) #Smart poster records after main records for record in records: spRecordNumber = self._addNdefRecord(recordNumber, record, spRecordNumber) recordNumber += 1 self._transport.nfcSetMessageInfo(recordNumber) self._transport.nfcPrepareMessage(False, True) recordNumber = 0 spRecordNumber = len(records) for record in records: spRecordNumber = self._setNdefRecord(recordNumber, record, spRecordNumber) recordNumber += 1 #self._transport.nfcSetMessageInfo(recordNumber) def _addNdefRecord(self, recordNumber, record, recordsStart, spAllowed = True): funcs = { URIRecord : self._generateURIRecord, TextRecord : self._generateTextRecord, SmartPosterRecord : self._generateSmartPosterRecord, MIMERecord : self._generateMIMERecord, } if( not spAllowed and type(record) == SmartPosterRecord ): raise SmartPosterNestingException() return funcs[type(record)](recordNumber, record, recordsStart) def _generateURIRecord(self, recordNumber, record, spRecordNumber): #Try to get prefix buf = array("B") buf.fromstring(record.uri) prefix, length = self._encodePrefix(buf[0:36]) self._transport.nfcSetRecordInfo(recordNumber, 1, [prefix, len(buf[length:])]) return spRecordNumber def _generateTextRecord(self, recordNumber, record, spRecordNumber): languageCodeBuf = array("B") languageCodeBuf.fromstring(record.language) textBuf = array("B") textBuf.fromstring(record.text) self._transport.nfcSetRecordInfo(recordNumber, 2, [{v: k for k, v in TEXT_ENCODING.items()}[record.encoding], len(languageCodeBuf), len(textBuf)]) return spRecordNumber def _generateSmartPosterRecord(self, recordNumber, record, recordsStart): self._transport.nfcSetRecordInfo(recordNumber, 3, [recordsStart, len(record.records)]) spRecordNumber = recordsStart for spRecord in record.records: self._addNdefRecord(spRecordNumber, spRecord, 0, False) #No sub records spRecordNumber += 1 return spRecordNumber def _generateMIMERecord(self, recordNumber, record, spRecordNumber): mimeTypeBuf = array("B") mimeTypeBuf.fromstring(record.mimeType) dataBuf = array("B", record.data) self._transport.nfcSetRecordInfo(recordNumber, 4, [len(mimeTypeBuf), len(dataBuf)]) return spRecordNumber def _setNdefRecord(self, recordNumber, record, recordsStart, spAllowed = True): funcs = { URIRecord : self._setURIRecord, TextRecord : self._setTextRecord, SmartPosterRecord : self._setSmartPosterRecord, MIMERecord : self._setMIMERecord, } if( not spAllowed and type(record) == SmartPosterRecord ): raise SmartPosterNestingException() return funcs[type(record)](recordNumber, record, recordsStart) def _setURIRecord(self, recordNumber, record, spRecordNumber): #Try to get prefix buf = array("B") buf.fromstring(record.uri) prefix, length = self._encodePrefix(buf[0:36]) self._setRecordData(recordNumber, 0, buf[length:]) return spRecordNumber def _setTextRecord(self, recordNumber, record, spRecordNumber): languageCodeBuf = array("B") languageCodeBuf.fromstring(record.language) textBuf = array("B") textBuf.fromstring(record.text) self._setRecordData(recordNumber, 0, languageCodeBuf) self._setRecordData(recordNumber, 1, textBuf) return spRecordNumber def _setSmartPosterRecord(self, recordNumber, record, recordsStart): spRecordNumber = recordsStart for spRecord in record.records: self._setNdefRecord(spRecordNumber, spRecord, 0, False) #No sub records spRecordNumber += 1 return spRecordNumber def _setMIMERecord(self, recordNumber, record, spRecordNumber): mimeTypeBuf = array("B") mimeTypeBuf.fromstring(record.mimeType) dataBuf = array("B", record.data) self._setRecordData(recordNumber, 0, mimeTypeBuf) self._setRecordData(recordNumber, 1, dataBuf) return spRecordNumber def _encodePrefix(self, uri): prefix, length = self._transport.nfcEncodePrefix(uri) return prefix, length def _setRecordData(self, recordNumber, item, itemData): itemLength = len(itemData) itemOff = 0 while itemOff < itemLength: chunkLength = min(CHUNK_SIZE, itemLength - itemOff) buf = array("B", itemData[itemOff:itemOff+chunkLength]) self._transport.nfcSetRecordData(recordNumber, item, itemOff, buf) itemOff += chunkLength
print('Транспорт открыт:', t.opened, sep ='\n', end = '\n\n') t.open() print('Открыть.','Транспорт открыт:', t.opened, sep ='\n', end = '\n\n') print('Сесть и поехать, разгоняясь до скорости 6 м/с.') t.get_in() t.go(6) print('Состояние:', t.check_condition(), sep ='\n', end = '\n\n') time.sleep(2) print('Состояние через 2 секунды:', t.check_condition(), sep ='\n', end = '\n\n') time.sleep(3) print('Состояние через 5 секунд:', t.check_condition(), sep ='\n', end = '\n\n') t.stop() print('Состояние после остановки:', t.check_condition(), sep ='\n', end = '\n\n') print('Покинуть транспорт и закрыть.') t.get_out() t.close() print('Водитель внутри:', t.driver_inside, sep ='\n', end = '\n\n') print('Создать экземпляр Car.') t = Car(170, 32, 4, 'black', 100, 30, 2) print(t, end = '\n\n') print('Состояние автомобиля\n'\ '(едет, сколько проехал, топливо):', t.check_condition(), sep ='\n', end = '\n\n') t.tank_up(10) print('Заправить 10 л.\n'\ 'Состояние после заправки:', t.check_condition(), sep ='\n', end = '\n\n') print('Машина открыта:', t.opened, sep ='\n', end = '\n\n') t.open() print('Открыть.','Машина открыта:', t.opened, sep ='\n', end = '\n\n')