From 5d799cd454b64f221b6ac447fbf18d597338cddf Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Wed, 22 Aug 2018 15:13:18 -0700 Subject: [PATCH] adb: fix spurious usb write failure on Windows. We were accidentally returning 0 instead of the number of bytes written whenever we wrote a USB packet that had a size that was a multiple of the USB packet size, which resulted in the device getting kicked. Bug: http://b/113070258 Test: python test_device.py Change-Id: Ib3d6415545e90e1f4730afc8ad8713d10bb1534a --- adb/client/usb_windows.cpp | 3 ++- adb/test_device.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/adb/client/usb_windows.cpp b/adb/client/usb_windows.cpp index e928377ad..00aeb9b70 100644 --- a/adb/client/usb_windows.cpp +++ b/adb/client/usb_windows.cpp @@ -357,7 +357,8 @@ int usb_write(usb_handle* handle, const void* data, int len) { if (handle->zero_mask && (len & handle->zero_mask) == 0) { // Send a zero length packet - if (!AdbWriteEndpointSync(handle->adb_write_pipe, (void*)data, 0, &written, time_out)) { + unsigned long dummy; + if (!AdbWriteEndpointSync(handle->adb_write_pipe, (void*)data, 0, &dummy, time_out)) { D("AdbWriteEndpointSync of zero length packet failed: %s", android::base::SystemErrorCodeToString(GetLastError()).c_str()); err = EIO; diff --git a/adb/test_device.py b/adb/test_device.py index 42aadc484..20f224a72 100644 --- a/adb/test_device.py +++ b/adb/test_device.py @@ -1302,6 +1302,37 @@ class DeviceOfflineTest(DeviceTest): self.assertEqual(length, len(stdout) - 4) self.assertEqual(stdout, "\0" * length + "foo\n") + def test_zero_packet(self): + """Test for http://b/113070258 + + Make sure that we don't blow up when sending USB transfers that line up + exactly with the USB packet size. + """ + + local_port = int(self.device.forward("tcp:0", "tcp:12345")) + try: + for size in [512, 1024]: + def listener(): + cmd = ["echo foo | nc -l -p 12345; echo done"] + rc, stdout, stderr = self.device.shell_nocheck(cmd) + + thread = threading.Thread(target=listener) + thread.start() + + # Wait a bit to let the shell command start. + time.sleep(0.25) + + sock = socket.create_connection(("localhost", local_port)) + with contextlib.closing(sock): + bytesWritten = sock.send("a" * size) + self.assertEqual(size, bytesWritten) + readBytes = sock.recv(4096) + self.assertEqual("foo\n", readBytes) + + thread.join() + finally: + self.device.forward_remove("tcp:{}".format(local_port)) + def main(): random.seed(0)