예제 #1
0
 def scan_toys(timeout=5.0):
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     s.connect((host, port))
     try:
         s.sendall(RequestOp.SCAN + struct.pack('!f', timeout))
         code = recvall(s, 1)
         if code == ResponseOp.ERROR:
             size = to_int(recvall(s, 2))
             data = recvall(s, size)
             raise Exception(data.decode('utf_8'))
         elif code != ResponseOp.OK:
             raise SystemError(f'Unexpected response op code {code}')
         num_devices = to_int(recvall(s, 2))
         devices = []
         for _ in range(num_devices):
             name_size = to_int(recvall(s, 2))
             name = recvall(s, name_size).decode('utf_8')
             address_size = to_int(recvall(s, 2))
             addr = recvall(s, address_size).decode('ascii')
             devices.append(MockDevice(name, addr))
         return devices
     finally:
         s.sendall(RequestOp.END)
         s.close()
예제 #2
0
 def __recv(self):
     while True:
         try:
             code = recvall(self.__socket, 1)
         except:
             break
         if code == ResponseOp.OK:
             self.__sequence_wait.pop(recvall(self.__socket,
                                              1)[0]).set_result(None)
             continue
         size = to_int(recvall(self.__socket, 2))
         data = recvall(self.__socket, size)
         if code == ResponseOp.ON_DATA:
             uuid = data.decode('ascii').lower()
             size = recvall(self.__socket, 1)[0]
             data = recvall(self.__socket, size)
             for f in self.__callbacks.get(uuid, []):
                 f(uuid, data)
         elif code == ResponseOp.ERROR:
             err = Exception(data.decode('utf_8'))
             self.__sequence_wait.pop(recvall(self.__socket,
                                              1)[0]).set_exception(err)
예제 #3
0
 def get_core_up_time_in_milliseconds(toy, proc=None):
     return to_int(toy._execute(SystemInfo._encode(toy, 57, proc)).data)
예제 #4
0
 def get_factory_mode_challenge(toy, proc=None):
     return to_int(toy._execute(FactoryTest._encode(toy, 19, proc)).data)
예제 #5
0
 def get_chassis_id(toy, proc=None):
     return to_int(toy._execute(FactoryTest._encode(toy, 39, proc)).data)
예제 #6
0
async def process_connection(reader: asyncio.streams.StreamReader, writer: asyncio.streams.StreamWriter):
    peer = writer.get_extra_info('peername')

    def callback(char, d):
        if writer.is_closing():
            return
        char = char.encode('ascii')
        writer.write(ResponseOp.ON_DATA + to_bytes(len(char), 2) + char + to_bytes(len(d), 1) + d)
        asyncio.ensure_future(writer.drain())

    print('Incoming connection from %s:%d' % peer)
    adapter: Optional[bleak.BleakClient] = None

    try:
        while True:
            cmd = await reader.readexactly(1)
            if cmd == RequestOp.SCAN:
                timeout = struct.unpack('!f', await reader.readexactly(4))[0]
                try:
                    toys = await bleak.discover(timeout)
                except BaseException as e:
                    err = str(e)[:0xffff].encode('utf_8')
                    writer.write(ResponseOp.ERROR + to_bytes(len(err), 2) + err)
                    await writer.drain()
                    continue
                writer.write(ResponseOp.OK + to_bytes(len(toys), 2))
                await writer.drain()
                for toy in toys:
                    name = toy.name.encode('utf_8')
                    addr = toy.address.encode('ascii')
                    writer.write(to_bytes(len(name), 2) + name + to_bytes(len(addr), 2) + addr)
                    await writer.drain()
            elif cmd == RequestOp.END:
                break
            else:
                seq_size = await reader.readexactly(3)
                seq, size = seq_size[0], to_int(seq_size[1:])
                data = (await reader.readexactly(size)).decode('ascii')
                try:
                    if cmd == RequestOp.INIT:
                        adapter = bleak.BleakClient(data, timeout=5.0)
                        await adapter.connect()
                    elif cmd == RequestOp.SET_CALLBACK:
                        await adapter.start_notify(data, callback)
                    elif cmd == RequestOp.WRITE:
                        size = to_int(await reader.readexactly(2))
                        payload = bytearray(await reader.readexactly(size))
                        await adapter.write_gatt_char(data, payload, True)
                except EOFError:
                    raise
                except BaseException as e:
                    err = str(e)[:0xffff].encode('utf_8')
                    writer.write(ResponseOp.ERROR + to_bytes(len(err), 2) + err + bytes([seq]))
                    await writer.drain()
                    continue
                writer.write(ResponseOp.OK + bytes([seq]))
                await writer.drain()
    finally:
        writer.close()
        if adapter and await adapter.is_connected():
            await adapter.disconnect()
        await writer.wait_closed()
        print('Disconnected from %s:%d' % peer)
예제 #7
0
 def save_compressed_frame_player16_bit_frame(toy, i, i2, i3, i4, i5, proc=None):  # unknown names
     return to_int(toy._execute(IO._encode(toy, 77, proc, struct.pack('>5H', i, i2, i3, i4, i5))).data)
예제 #8
0
 def get_battery_voltage(toy, proc=None):
     return to_int(toy._execute(Power._encode(toy, 3, proc)).data) / 100
예제 #9
0
 def get_pending_update_flags(toy, proc=None):
     return PendingUpdateFlags(to_int(toy._execute(Firmware._encode(toy, 13, proc)).data))
예제 #10
0
 def get_factory_config_block_crc(toy, proc=None):
     return to_int(toy._execute(Core._encode(toy, 39, proc)).data)
예제 #11
0
 def get_chassis_id(toy, proc=None):
     return to_int(toy._execute(Sphero._encode(toy, 7, proc)).data)
예제 #12
0
 def get_temporary_options(toy, proc=None):
     data = to_int(toy._execute(Sphero._encode(toy, 56, proc)).data)
     return Options(bool(data & 1), bool(data & 2), bool(data & 4),
                    bool(data & 8), bool(data & 16), bool(data & 256),
                    bool(data & 1024))
예제 #13
0
 def get_persistent_options(toy, proc=None):
     data = to_int(toy._execute(Sphero._encode(toy, 54, proc)).data)
     return Options(bool(data & 1), bool(data & 2), bool(data & 4),
                    bool(data & 8), bool(data & 16), bool(data & 256),
                    bool(data & 1024))