2011. 2. 21. 22:09

Wireless Adb Debugging (TCP 를 이용한 adb 디버깅) - Rooting Only

일반 개발자들은 주로 USB 를 이용하여 adb 를 사용합니다. 하지만 TCP 를 이용하여 adb 를 이용한 디버깅을 해본 사람들은 많지 않을 것입니다. 그도 그럴 것이 Rooting 또는 Engineering 빌드 버전이 아니면 TCP 설정이 적용되지가 않기 때문에 실 장치를 가지고 테스트를 해보기가 쉽지 않겠죠.

이 글을 읽고 계신 분들은 Rooting 폰 또는 Engineering 빌드 버전의 장치를 가지고 있다고 가정하겠습니다.

TCP 를 이용하여 디버깅을 하면 USB 를 연결하지 않아도 adb 명령을 이용하여 app 을 설치하거나, logcat 의 로그를 모으는 등의 USB 와 연결된 것과 동일한 모든 adb 기능을 사용할 수 있습니다.

시중에 이러한 설정을 편리하게 해주는 (원클릭으로 Wireless 디버깅 on/off를 해주는) 유료 앱을 팔고 있던데, 이 App 은 알고보면 아무것도 아닙니다. Rooting 된 폰에서 TCP 디버깅 설정을 on/off 하는 것은 별로 어렵지 않기 때문이죠.

자 이제 adb 에서 제공하는 TCP 를 이용한 디버깅 설정방법을 알아 보겠습니다. 크게 매뉴얼 설정과 자동 설정 두가지로 나누어 살펴보겠습니다.

1. 매뉴얼 설정

먼저 안드로이드 장치의 디버깅 모드를 활성화 한 후 USB 를 연결합니다. TCP 를 이용한 Adb 를 설정하기 위해서는 adb shell 을 이용해야 하기 때문에 처음에 한번은 연결이 필요합니다. 이글 말미에 Rooting 된 폰에서 이를 자동화하는 방법을 소개하겠습니다. (구현은 제공하지 않고 숙제로 남겨두겠습니다.)

TCP 를 이용한 adb 디버깅을 하기 위해서는 현재 무선공유기등과 같은 Wifi 망이 이용가능해야 합니다.

$ adb devices

를 입력하여 현재 연결된 장치를 확인합니다.

그리고는 다음을 입력하여 adb 데몬(device 에서 adb 를 서비스하는 프로세스, adbd)의 설정을 변경합니다.

$ adb tcpip 5555

뒤의 5555 는 5555번 port 를 사용하겠다는 것을 의미합니다. 위와 같이 입력하면 adbd 데몬 프로세스(장치에서 실행되며 실질적인 adb 기능을 수행함)를 tcpip 모드로 재시작합니다. 이제 장치는 tcpip 를 연결할 수 있는 상태가 되었습니다.

(TCP 연결 성공을 체크하기 위해 기존에 연결된 USB 케이블을 해제하시기 바랍니다.)

PC 와 장치를 연결하기 위해서는 장치에 할당된 IP 를 확인해야 합니다. 이는
"설정 > 무선 및 네트워크 > Wi-Fi 설정" 에서 연결된 Wi-Fi 네트워크를 선택하면 확인할 수 있습니다.


저의 경우 192.168.0.4 입니다. 이제 PC 에서 장치로 연결하는 명령을 줍니다.

$ adb connect 192.168.0.4:5555

를 입력하면 연결 성공 메시지를 볼 수 있으며, 이렇게 연결된 이후에는 adb 명령을 동일하게 사용할 수 있습니다.

2. 자동 설정

원터치 Wireless 설정을 지원하는 방법을 살펴보겠습니다. 키포인트는 위에서 실행했던 "adb tcpip <port>" 명령을 어떻게 장치에서 수행하느냐 입니다.

그 명령은 아래와 같습니다.

$ su
# setprop service.adb.tcp.port 5555
# stop adbd
# start adbd

위 명령을 장치에서 실행하기만 하면 되는 것입니다. 위 예제와 같이 su 명령을 이용하여 root 권한을 얻게 되는데, 바로 이런 권한이 필요하기 때문에 production 장치에서는 수행할 수 가 없는 것입니다.

끝으로 안드로이드 App 에서 su 권한을 체크하는 방법을 소개해 드리며, 이 예제 코드와 tcp 설정 스크립트를 이용하면 시중에 돌고 있는 원터치 Wireless Adb 설정 App 을 개발할 수 있습니다. (이 예제도 당연 Rooting 된 폰에서만 root 권한을 얻습니다.) 
☞ su 명령이 수행된다고 가정을 하겠습니다. 만약 su 가 존재하지 않으면 su 는 검색하면 쉽게 구할 수 있습니다. 약간의 보안 방어막을 가한 super user 라는 app 도 있습니다.

Process p;  
try {  
   // Preform su to get root privledges  
   p = Runtime.getRuntime().exec("su");   
  
   // Attempt to write a file to a root-only  
   DataOutputStream os = new DataOutputStream(p.getOutputStream());  
   os.writeBytes("echo \"Do I have root?\" >/system/sd/temporary.txt\n");  
  
   // Close the terminal  
   os.writeBytes("exit\n");  
   os.flush();  
   try {  
      p.waitFor();  
           if (p.exitValue() != 255) {  
              // TODO Code to run on success  
              toastMessage("root");  
           }  
           else {  
               // TODO Code to run on unsuccessful  
               toastMessage("not root");  
           }  
   } catch (InterruptedException e) {  
      // TODO Code to run in interrupted exception  
       toastMessage("not root");  
   }  
} catch (IOException e) {  
   // TODO Code to run in input/output exception  
    toastMessage("not root");  
}  

이것만 가지고 어떻게 만들어요라고 되묻지 마시고, 한번 시도해 보시기 바랍니다. Just do it!


3. 기타

$ adb shell getprop

을 입력하면 현재 장치의 설정 정보를 볼 수 있습니다. 만약 tcpip 로 설정되어 있다면 getprop 에서도 그 목록이 나와야 합니다.

$ adb shell setprop service.adb.tcp.port -1

은 tcp 설정을 해제합니다.

참고:

su 권한을 크랙하는 방법은 아래 글을 참고하세요.


! 추가 확인 필요

아래 명령은 디폴트 설정을 변경한다고 합니다. (위에 설정은 장치가 리부팅되면 usb 모드로 돌아갑니다.) 이게 제대로 동작하는지 확인이 필요합니다. 안된다는 말도 있구요... 확인 요함.

$ adb shell setprop persist.adb.tcp.port 5555

관련글: