Thursday, November 26, 2009

adb for remote connections

The adb tool in android sdk is convenient utility for debugging and control android emulators. One of its powerful features is it can forward a tcp port on local machine to an emulator running on the same machine.
After you run the adb forward tcp:hostport tcp:emuport command, your android running in emulator can listen on emuport and communicate with external applications running on host machine. From the external application's point of view, it's connecting to hostport rather than emuport. The adb is responsible for forwarding messages between the two.
But adb has a limitation of only accepting connections from the same machine, you can't connect from a machine that adb isn't running on. This limitation makes it a little bit inconvenient to do network programming. Especially on windows, if you want to use wireshark to capture the packages between emulator and external app. By default, wireshark isn't able to capture loopback packages on windows. So, we change the behavior of adb to accept remote connections.
(Another way to overcome this is instead of capturing network package on host side, we can use tcpdump on emulator side. For example, use "/data/tcpdump -s 1500 -vv -w /data/net.pcap udp port 5060" to capture all packages for udp port 5060 and save them in /data/net.pcap file. The -s parameter specifies the size of each packet whose default value is 68, too small to get some useful information truncated. The /data/net.pcap file can also be examined with wireshark.)

How to modify adb behavior
If we run netstat command on host side, we can find out that adb server process binds to the loopback address. So it can't be accessed via external address.
The adb register a port forwarding information through install_listener function. And install_listener calls local_name_to_fd function to bind to a local address. Inside local_name_to_fd, it starts a tcp server through socket_loopback_server. To change this, we can use socket_inaddr_any_server which binds to all ipaddresses. In this way, the adb server can forward a request from remote machine to emulator.

How to compile
In order to get the modified adb, we need to compile it. To do so, we first need to download all of anroid's source code. Then, at the root of andoird source directory, run ./build/envsetup.sh. Finally, run make adb.

Downloads
http://rxwen-blog-stuff.googlecode.com/files/tcpdump.zip
http://rxwen-blog-stuff.googlecode.com/files/adb-linux.zip
http://rxwen-blog-stuff.googlecode.com/files/adb-windows.zip

Reference
howto build SDK

Update:
Modified adb v1.0.31 can be downloaded at: https://drive.google.com/#folders/0B9fylkYUFfYTTGJKN0tURzJFelE

15 comments:

conockrad said...

Is this adb in archive was already recompiled by you? Or it's just simple executable from android sdk?

rxwen said...

This is a modified version compiled by me.

Anonymous said...

please can you update your modified version with a newer one?

rxwen said...
This comment has been removed by the author.
rxwen said...

updated adb for linux is available here:
http://code.google.com/p/rxwen-blog-stuff/downloads/detail?name=adb-linux

Anonymous said...

Hello! Do you have a chance to update your adb-fix for the latest sources for Windows? Thanks.

rx wen said...

Modified adb v1.0.31 can be downloaded at: https://drive.google.com/#folders/0B9fylkYUFfYTTGJKN0tURzJFelE

Anonymous said...

Thanks a lot! I'll try it and let you know the result.

Anonymous said...

great job!
do you have mac version ? thx!

Anonymous said...

Remote adb has solved my problem with selenium grid. Now I can separate hub / nodes and use not only localhost. Remote tests execution on real devices works perfect. Thanks again!

Anonymous said...

Hello! Could you please add some info how to make adb on Windows?

rx wen said...

For build instructions, check the reference in my post.

Anonymous said...

Thanks for the reference!

EdvardsMC said...

Hi,

can you please modify and build an ADB version that uses more (or different) way to identify connected devices? UDID is useless when I have connected multiple devices with the same UDID. Devices are not root'ed so I can't change that.

As stated here -> http://stackoverflow.com/questions/13986155/adb-got-two-same-serial-numbers-when-connected-to-two-smart-phones/22824288#22824288

It's possible to change the way it identifies the devices, but I wasn't able to recompile the ADB on my windows 7 machine. Can you please help me? :)

Thanks!

Aditya Sureka said...

any updated version ? or github commit link to the changes made by you?