Skip to content

Fix multiple CLSE commands (aka, support for newer devices) #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Oct 2, 2019
23 changes: 18 additions & 5 deletions adb_shell/adb_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,15 +389,28 @@ def _read_until(self, local_id, remote_id, expected_cmds, timeout_s, total_timeo
We don't support multiple streams...
adb_shell.exceptions.InvalidResponseError
Incorrect remote id.
adb_shell.exceptions.InvalidCommandError
Never got one of the expected responses.

"""
cmd, remote_id2, local_id2, data = self._read(expected_cmds, timeout_s, total_timeout_s)
start = time.time()

while True:
cmd, remote_id2, local_id2, data = self._read(expected_cmds, timeout_s, total_timeout_s)

if local_id2 not in (0, local_id):
raise exceptions.InterleavedDataError("We don't support multiple streams...")

if local_id2 not in (0, local_id):
raise exceptions.InterleavedDataError("We don't support multiple streams...")
if remote_id2 in (0, remote_id):
break

if time.time() - start > total_timeout_s:
raise exceptions.InvalidCommandError('Never got one of the expected responses (%s)' % expected_cmds, cmd, (timeout_s, total_timeout_s))

if remote_id2 not in (0, remote_id):
raise exceptions.InvalidResponseError('Incorrect remote id, expected {0} got {1}'.format(remote_id, remote_id2))
# Ignore CLSE responses to previous commands
# https://github.com/JeffLIrion/adb_shell/pull/14
if cmd != constants.CLSE:
raise exceptions.InvalidResponseError('Incorrect remote id, expected {0} got {1}'.format(remote_id, remote_id2))

# Acknowledge write packets
if cmd == constants.WRTE:
Expand Down
2 changes: 1 addition & 1 deletion adb_shell/adb_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def unpack(message):
try:
cmd, arg0, arg1, data_length, data_checksum, _ = struct.unpack(constants.MESSAGE_FORMAT, message)
except struct.error as e:
raise ValueError('Unable to unpack ADB command. ({})'.format(len(message)), constants.MESSAGE_FORMAT, message, e)
raise ValueError('Unable to unpack ADB command. (length={})'.format(len(message)), constants.MESSAGE_FORMAT, message, e)

return cmd, arg0, arg1, data_length, data_checksum

Expand Down
23 changes: 12 additions & 11 deletions tests/patchers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@

class FakeSocket(object):
def __init__(self):
self.recv_list = [b'']
self._recv = b''

def close(self):
pass

def recv(self, bufsize):
return self.recv_list.pop(0)
ret = self._recv[:bufsize]
self._recv = self._recv[bufsize:]
return ret

def send(self, data):
pass
Expand All @@ -39,25 +41,26 @@ def shutdown(self, how):


class FakeTcpHandle(TcpHandle):
def __init__(self, *args, **kwargs):
TcpHandle.__init__(self, *args, **kwargs)
self._bulk_read = b''

def close(self):
self._connection = None

def connect(self, auth_timeout_s=None):
self._connection = True

def bulk_read(self, numbytes, timeout_s=None):
return self.bulk_read_list.pop(0)
num = min(numbytes, constants.MAX_ADB_DATA)
ret = self._bulk_read[:num]
self._bulk_read = self._bulk_read[num:]
return ret

def bulk_write(self, data, timeout_s=None):
return len(data)


class FakeTcpHandleWithAuth(FakeTcpHandle):
def connect(self, auth_timeout_s=None):
self._connection = True
self.bulk_read_list = [MSG_CONNECT_WITH_AUTH.pack(), MSG_CONNECT_WITH_AUTH.data]


# `socket` patches
patch_create_connection = patch('socket.create_connection', return_value=FakeSocket())

Expand All @@ -70,5 +73,3 @@ def connect(self, auth_timeout_s=None):

# `TcpHandle` patches
patch_tcp_handle = patch('adb_shell.adb_device.TcpHandle', FakeTcpHandle)

patch_tcp_handle_with_auth = patch('adb_shell.adb_device.TcpHandle', FakeTcpHandleWithAuth)
Loading