Android ADK - USB Host Mode


제가 소개하고 싶은 내용은 Android에서 제공하는 
Android ADK 중 USB Host Mode에 대해서 알아보려고 합니다.

내용 구성은 아래와 같이 4가지 수순으로 전개됩니다.

  * Android ADK – USB Host and Accessory 알아보기
  * USB Host Mode APIs 알아보기
  * Android Application 개발 시 적용 방법 알아보기
  * Sample Application 스크린 샷


우선은 기본적인 개념부터 소개하겠습니다.


1. Android ADK – USB Host and Accessory 알아보기

Android 운영체제에서 우리가 사용하고 있는 Android Device(Phone, Tablet등)와 수 많은 “USB 주변장치”, “USB 액세서리”라고 하는 하드웨어를 사용할 수 있는 방법을 제공하고 있습니다.

사용 방법에 대해서 아래의 2가지 모드를 정의해 놓았습니다.
Android에서 제공하고 있는 2가지 모드(그림-1)는 아래와 같습니다.
  * USB Host Mode
  * USB Accessory Mode


2가지 모드의 동작 기준은
Android Device의 USB Host로써의 역할 유무로 나누어진다고 생각하면 됩니다.

  < USB Host Mode >
    * Android Device가 USB Host Mode일 경우 USB Host로써의 역할을 수행합니다.
    * 비유를 하자면 Android Phone이 PC와 같은 역할을 하게 되며 연결되는 USB 장치 예로
      USB Mass Storage, Keyboard, Mouse 등을 사용할 수 있게됩니다. .
  < USB Accessory Mode >
    * Android Device가 USB Accessory Mode일 경우 단순 USB Device로써의 역할(Host 기능 없음)로 
      동작하기 때문에 외부 연결된 USB Device가 USB Host로써의 역할을 수행합니다.
    * 위 모드일 경우에는 Open Hardware Project인 Arduino와 같은 
      H/W들과 연동하여 사용되는 경우가 많습니다.
    * Google I/O에서 소개된 ADK Guide에서 추가적인 정보를 얻을 수 있습니다.
    * http://developer.android.com/tools/adk/index.html



[ 그림-1 / USB Host and Accessory Modes ]


전제 조건
    * USB Host & Accessory Mode API를 사용하기 위해서는 Android 3.1(HoneyComb – API Level 12) 이상부터 지원하게 되어있습니다.
    * 다만,  Android 2.3.4(Gingerbread – API Level 10)에서는 별도의 라이브러리를 추가하는 방식으로 지원할 수 있습니다.



2. USB Host Mode APIs 알아보기

그럼 지금부터 USB Host Mode에서 사용되는APIs(http://developer.android.com/guide/topics/connectivity/usb/host.html) 에 대해서 
간략히 명 드리며 샘플 제작을 통하여 Host 기능이 잘 동작하는지 검증 해보겠습니다.
USB Host APIs는 “android.hardware.usb” Package(표-1)의 정의되어 있습니다.
[ 표-1 USB Host APIs ]

refer to http://developer.android.com/guide/topics/connectivity/usb/host.html

위 표에서 보이는 Class들은 Android Device의 연결된 USB Device와의 통신을 위하여 사용되고 있습니다.
UsbManager Class는 연결된 USB Device를 열거(enumerate)하고, 통신을 위하여 장치 열기(open), 권한 요청 등의 중요한 역할을 수행합니다.
UsbDevice, UsbInterface, UsbEndpointClass들은 연결된 USB Device의 정보를 취득하는 역할을 수행합니다.

<그림-2>는 Usbview 프로그램을 이용하여 단말의 USB Descriptor 정보를 확인한 것입니다.
위 3가지 Class들을 이용하여 단말의 정보들을 취득하여 Android Application에서 사용할 수 있게 되는 것입니다.
Vendor ID, Product ID 등을 취득하여 원하는 Device일 경우만 동작하도록 사용할 수도 있습니다.
Interface와 Endpoint를 취득하여만 실제적으로 USB 통신을 진행할 수 있습니다.

[ 그림-2 UsbView를 통한 USB MassStorage Descriptor ]

UsbDeviceConnection Class는 USB Device에 Control Data 및 Bulk Data를 송/수신하는 하는 역할을 수행합니다.
    * bulkTransfer() : 파라미터로 전달되는 Endpoint 방향에 따라서 Bulk Data의 송/수신 작업을 수행
    * controlTransfer() :  Endpoint Zero(0)로 Control Data의 송/수신 작업을 수행
이제 USB Host APIs들을 확인하였으니 Android Application에서 API를 사용함에 있어서 추가 설정부분 및 사용방법에 대해서 Google Guide(http://developer.android.com/guide/topics/connectivity/usb/host.html)를 토대로 확인해보겠습니다.



3. Android Application 개발 시 적용 방법 알아보기

Android Manifest 파일 수정

제일 먼저 USB Host APIs를 정상적으로 사용하기 위해서 Android Manifest 파일에 대해서 아래와 같은 내용을 추가해야 합니다.

    * <user-feature> element에 “android.hardware.usb.host” 추가
    * 앞에서 설명하였듯이 모든 버전에서 제공하는 것이 아니기 때문에 명시적으로 
      USB Host APIs를 사용한다고 알립니다.
    * 추가 내용 : <uses-feature android:name=”android.hardware.usb.host” />

    * <use-sdk> element에 “android:minSdkVersion=”12″” 추가
    * USB Host APIs를 제공하는 버전은 API Level 12 이상부터입니다.
    * 추가 내용 : <uses-sdk android:minSdkVersion=”12″ android:targetSdkVersion=”18″ />
    * <intent-filter>,<meta-data> element에 “android.hardware.usb.action.USB_DEVICE_ATTACHED” 추가
    * 위 메시지를 등록할 경우, USB Device가 연결될 경우 Application에서 연결 통보를 받을 수 있습니다.
    * Application이 원하는 장치에 대해서만 통보를 받을 수 있습니다.
    * res/xml/device_filter.xml 파일을 생성한 후 Vendor ID, Product ID 등으로 필터링을 할 수 있습니다.

Enumerate Specific USB Device
UsbManager.getDeviceList()를 이용하여 연결된 USB Device 목록을 얻어올 수 있습니다.
<그림-3>은 해당 목록에서 우리가 원하는 USB Device를 찾기 위하여 UsbDevice.getVendorId(), UsbDevice.getProductId() API를 이용합니다.
[ 그림-3 원하는 UsbDevice Find 과정 ]

Send / Receive Data

<그림-4>는 UsbDevice로부터 UsbDevice.getInterface()를 이용하여 원하는 Interface를 얻고, UsbInterface로부터 UsbInterface.getEndpoint()를 이용하여 Endpoint를 얻은 후 Data를 송/수신을 수행합니다.

[ 그림-4 USB Data Send / Receive 과정 ]


4. Sample Application 스크린 샷

마지막으로 USB Host APIs를 이용하여 Android Device와 USB Device간 통신을 수행하는 Sample Application의 스크린샷입니다.

아래의 단말을 가지고 통신 테스트 진행하였습니다.

    * Android Device
       - Product : Vega Iron Smart-Phone
       - Android Version : Jelly Bean 4.1.2

    * USB Device
        - Product : USB Modem Dongle

테스트 순서

1. USB Dongle을 Phone에 연결 합니다.
    a. Phone 연결 시는 USB_OTG 케이블을 이용하였습니다.
    b. Android Manifest 파일에 해당 USB Dongle에 VendorID와 ProductID를 정의하여서 장치 연결 시 실행 팝업이 동작하는 것을 확인하였습니다.

[ 그림-5 Application Run ]

3. Sample Application에서 USB Dongle로 Serial 명령을 송신합니다.
4. Serial 명령을 송신하면 USB Dongle로부터 수신 메시지를 전달 받습니다.
[ 그림-6 Application Send / Receive ]


확인 과정중 Android Device(Phone)에서 USB_OTG 기능을 지원하지 않으면 
사실상 USB Host Mode를 사용할 수 없을 것 같습니다.

    * Phone에서 MassStorage나 Keyboard 장치를 연결해도 인식하지 않기 때문입니다.  
지금까지 USB Host Mode의 개념부터 APIs 설명 및 사용법 
그리고 Sample Application 구동까지 확인해보았습니다.
앞으로 더 추가될 기술들이 어떤것들이 있을지 매우 기대가 됩니다.



post by
유형진 연구원