와이파이 다이렉트(Wi-Fi Direct)에 대해 소개한다.
안드로이드 4.0 부터 와이파이 다이렉트를 지원한다. 와이파이 다이렉트를 사용하면 AP 없이 곧장 피어 두 피어(Peer to Peer)로 통신이 가능하다. 아래 그림은 와이파이 다이렉트의 개념을 보여준다.

와이파이 다이렉트를 지원하는 디바이스는 다른 디바이스를 발견하고 연결한 후 데이터를 주고 받는다. 이 와이파이 다이렉트는 블루투스 보다 더 멀리, 그리고 빠르게 데이터를 전송한다. 안드로이드에서는 와이파이 다이렉트 기능에 접근하기 위한 API 를 제공하며, 다중 접속 게임이나 사진 전송을 위한 애플리케이션을 작성할 때 유용하다.

와이파이 다이렉트 개요

엄밀한 의미에서는 와이파이 다이렉트는 마케팅 용어이며, 이에 대한 기술 규격은 Wi-Fi P2P 라 한다. 와이파이 다이렉트를 사용해 데이터를 주고 받을 때 각 단말을 피어라고도 부른다. 기존의 와이파이망에서는 AP 를 통해 접속한 후 인터넷에 접속하는 방법이 일반적인 와이파이의 사용법이다.
Wi-Fi P2P 는 기존의 와이파이 표준 규격의 대부분을 지원하면서 디바이스 간 직접 통신을 지원하는 부분이 추가됐다. NFC 는 페어링 등의 절차가 없어 편리하긴 하지만 거리가 가까워야 하고, 지금까지는 데이터의 양도 소규모 전송에 적합하다. 그러나 와이파이 다이렉트를 사용하면 더 먼거리까지 연결이 가능하며 빠르게 데이터를 주고 받는다. 다만 디바이스에 따라 와이파이 다이렉트를 사용하는 동안에는 기존 와이파이 연결이 사라지기도 한다. 즉, 이 기간 동안에는 기존 와이파이를 사용할 수 없다.
모든 디바이스에서 이런 제약이 있는 것은 아니고 지원 기기별로 다르다.

아래 그림에서 보듯이 기존 와이파이 망에서 AP 역할을 수행하는 디바이스가 존재하는데, 이를 P2P 그룹 오너(GO)라 한다.

P2P 그룹 오너를 중심으로 다양한 P2P 클라이언트가 존재할 수 있다. 한 개의 P2P 그룹 내에서는 한 개의 그룹 오너만 가능하며, 나머지 디바이스는 모두 클라이언트가 된다. 그룹 오너와 P2P 기능을 갖는 디바이스가 직접 연결되거나, 그룹 오너와 P2P 기능이 없는 기존 레거시 클라이언트가 연결 가능하다.
하나의 P2P 디바이스가 P2P 그룹을 형성하는 동시에 WLAN 에도 연결되는 동작을 동시 동작(concurrent mode)라고 한다.

아래 그림과 같이 이러한 동작을 지원하는 디바이스에서는 와이파이 다이렉트와 와이파이를 동시에 사용할 수 있다.

동작 시나리오 설명

Wi-Fi Direct 는 Wi-Fi Alliance 에 의해 개발된 새로운 기술이다. Wi-Fi Direct 는 Wi-Fi 기기들 간의 접속을 위한 하나의 방법이다. 그리고 그것은 현재 인증된 Wi-Fi 기기들과 하위호환성을 가진다.
아래그림은 realtek linux Wi-Fi Direct driver 의 구조에 대한 개요다.

“User Interface App(UI)” 는 제품의 고객에 의해 제작해야 하는 프로그램이다. UI 는 realtek Wi-Fi driver 로부터/로 전체 P2P 정보를 얻거나/설정하기 위해 iwpriv 프로그램을 사용한다. Iwpriv 프로그램은 wpa_supplicant 디렉토리 안에 있고, 또한 document 디렉토리 아래에 porting guide 를 제공한다.

물론 UI 는 이 문서에서 설명하는 Wi-Fi Direct API 를 기반으로 P2P 정보를 제어하기 위해 iwpriv 프로그램을 사용할 수 있다. wpa_cli 과 wpa_supplicant 는 802.11 station 모드 접속 전체를 콘트롤하는 표준 프로그램이다. Hostapd 와 hostapd_cli 는 또한 802.11 AP 모드 접속 전체를 제어하는 표준 프로그램이다.

일반적으로 Wi-Fi Direct 접속 시나리오는 4 단계이다.

  1. Device Discovery
  2. Provision Discovery
  3. Group Formation
  4. Provisioning

아래 그림은 Wi-Fi Direct 기능의 전체 컨셉을 제공할 것이다. 또한 앞서 설명한 4 단계를 포함한다.

위 그림은 기본 Wi-Fi Direct 시나리오를 설명하고, 이 문서에서는 Wi-Fi Direct 기능과 API 들을 설명하는데 위 그림을 사용할 것이다.

이 경우, 2대의 Wi-Fi Direct 기능을 지원하는 기기가 있다고 하자. realtek Wi-Fi driver 의 Wi-Fi Direct 기능을 활성화하기 위해 iwpriv 를 사용할 수 있다.

#iwpriv wlan0 p2p_set enable=n

wlan0 은 시스템 상에서 realtek Wi-Fi 디바이스를 위한 네트워크 인터페이스다. p2p_set 명령어는 드라이버에 설정할 정보를 넘겨줄 때 사용된다. enable 은 프로그램 정보를 설정하기 위해 드라이버에 말을 걸기위한 활성화 명령어이다. n 은 P2P 기능을 설정하기 위한 숫자이다. n=0 이면, P2P 기능을 비활성화 시킨다.

#iwpriv wlan0 p2p_set enable=0

n=1 이면, P2P 기능을 켜고, Wi-Fi driver 는 P2P device 모드가 된다.

#iwpriv wlan0 p2p_set enable=1

n=2 는 P2P 기능을 켜고, Wi-Fi driver 는 P2P client 모드가 된다.

#iwpriv wlan0 p2p_set enable=2

n=3 은 P2P 기능을 켜고, Wi-Fi driver 는 P2P Group Owner 모드가 된다.

#iwpriv wlan0 p2p_set enable=3

n 은 document 디렉토리 의 P2P.h 파일 안에 정의되어 있다. 이 문서는 또한 참조를 위해 여기에 정의(definition)를 복사해왔다.

enum P2P_ENABLEINFO {
P2P_DISABLE = 0,
P2P_ENABLE_WITH_DEVICE = 1,
P2P_ENABLE_WITH_CLIENT = 2,
P2P_ENABLE_WITH_GO = 3,
};

Wi-Fi 드라이버의 P2P 기능을 활성화 시킨 후에, P2P device1 은 현재 환경에서 얼마나 많은 P2P device 가 있는지 찾는다. UI 는 wpa_supplicant 또는 iwlist 명령어로 스캔할 수 있다.
wpa_supplicant 에서는 아래와 같다.

#wpa_cli scan                   // Ask wpa_supplicant to do the scanning
#wpa_cli scan_results        // Get the scanning result

iwlist 에서는 다음과 같다.

#iwlist wlan0 scan          // Issue the scanning request to driver and result the scanning result. 

Wi-Fi 드라이버의 P2P 기능을 활성화 할 때, Wi-Fi 드라이버는 Wi-Fi Direct 를 지원하는 디바이스들의 리스트를 제공할 것이다. 만일 UI 가 스캔할 때 802.11 네트워크의 모든 리스트를 원한다면, iwpriv wlan0 p2p_set enable=0 을 사용할 수 있다. 이것은 P2P 기능을 비활성화하고, 스캔을 다시 하도록 한다.

provision discovery 의 목적은 WPS 동작 동안, WPS Pin Code 또는 WPS push button button 이 눌러졌는지 얻기 위함이다.
prov_disc 는 provision 절차를 시작하기위한 명령이다. WPS 정보를 얻기 원할때, 00:11:22:33:44:55 는 P2P 디바이스의 MAC 주소이다(그림2 의 P2P Device2)
_ 은 연결자이다. display 는 P2P 디바이스가 그것의 화면에 PIN Code 를 출력하고 사용자는 자신의(local) P2P 디바이스(그림1 의 P2P Device1)에 이 PIN Code 를 입력해야 한다.

keypad 는 자신의(local) P2P 디바이스가 그것의 화면에 PIN Code 를 출력해야 하고, 사용자는 P2P 디바이스에 이 PIN Code 를 입력해야 한다.
pbc 는 두 P2P 디바이스가 WPS 동작 동안, WPS Push button 을 사용할 것이다.
label 은 P2P 디바이스의 라벨로부터 PIN Code 를 읽어, 자신의(local) P2P 디바이스 상에 이 PIN Code 를 입력한다. 그리고 지금, 자신의(local) P2P 디바이스와 다른 P2P 디바이스는 PIN Code 또는 PBC 를 가지고 있다. 802.11 network 에 접속하기 위해.

#iwpriv wlan0 p2p_set prov_disc=00:11:22:33:44:55_display
#iwpriv wlan0 p2p_set prov_disc=00:11:22:33:44:55_keypad
#iwpriv wlan0 p2p_set prov_disc=00:11:22:33:44:55_pbc
#iwpriv wlan0 p2p_set prov_disc=00:11:22:33:44:55_label

WPS PIN Code 또는 PBC 를 얻은 이후, UI 는 got_wpsinfo 명령을 사용하여 Wi-Fi 드라이버에 알린다.

got_wpsinfo=1 은 UI 가 P2P 디바이스의 화면 또는 라벨로부터 WPS PIN Code 를 얻고 자신의 P2P 디바이스에 이 PIN Code 를 입력한다.
got_wpsinfo=2 은 자신의(local) P2P 디바이스로부터 PIN Code 가 출력되고 사용자는 P2P 디바이스 상에 PIN Code 를 입력한다.
got_wpsinfo=3 은 UI 가 WPS PBC 를 얻는다.

#iwpriv wlan0 p2p_set got_wpsinfo=1
#iwpriv wlan0 p2p_set got_wpsinfo=2
#iwpriv wlan0 p2p_set got_wpsinfo=3

P2P.h 파일은 got_wpsinfo 명령어를 위해 의미와 값을 정의했다.

enum P2P_WPSINFO {
P2P_NO_WPSINFO                                  = 0,
P2P_GOT_WPSINFO_PEER_DISPLAY_PIN  = 1,
P2P_GOT_WPSINFO_SELF_DISPLAY_PIN   = 2,
P2P_GOT_WPSINFO_PBC                         = 3,
};

그림2 의 P2P 디바이스2 에서, status 명령어를 실행함으로서 현재 P2P state 를 체크할 수 있다. 만일 'Status=08' 라는 상태문자가 출력되었다면, 이것은 확실하게 P2P 디바이스로부터 provision discovery request 를 드라이버가 받았다는 것을 의미한다. 이때, UI 는 P2P 디바이스의 WPS 방법을 알기위해 req_cm 라는 명령을 사용해야 한다.

#iwpriv wlan0 p2p_get req_cm
Return String: CM=dis or CM=lab or CM=pbc or CM=pad

만일 'CM=dis' 라는 문자가 출력되었다면, P2P 디바이스는 자신의 화면 상에 PIN Code 를 보여주기 원하고, 사용자는 P2P 디바이스상에 이 PIN Code 를 입력할 수 있다.
만일 'CM=lab' 이라면, P2P 디바이스들 사이에서 P2P 디바이스의 라벨에 표시된 PIN Code 를 사용하길 원하는 것이고, 사용자는 P2P 디바이스상에 이 PIN Code 를 입력할 수 있다.
만일 'CM=pbc' 라면, P2P 디바이스는 WPS 동작 중에 PBC 를 사용하길 원한다. 만일 'CM=pad' 라면, P2P 디바이스는 P2P 디바이스 쪽에 PIN Code 를 보여줄 것이고 사용자는 자신의(local) P2P 디바이스 상에 이 PIN Code 를 입력해야 한다.

Wi-Fi Direct 시나리오 상에서, P2P 디바이스들 중 하나는 GO(Soft AP)가 될 것이고, 다른 P2P 디바이스들은 Soft AP 에 접속하는 802.11 클라이언트가 될 것이다. 4 단계 “Start Group Negotiation” 은 P2P 디바이스가 group owner/client 가 되는 것을 결정하는 과정이다.

intent 는 0~15 의 값을 가진다. 이 값은 GO 가 되기를 원하는 정도의 정보를 제공할 것이다. intent=15 라면, Wi-Fi 드라이버는 반드시 GO 가 되어야만 한다. 기본 intent 값은 1 이고, 이 기본값은 P2P 기능을 활성화함으로서 설정된다.

#iwpriv wlan0 p2p_set intent=n

intent 값에 비해, UI 는 향후 Soft AP 로서 GO 가 될때 사용할 SSID 를 결정한다. UI 는 SSID 를 결정한 후, ssid 명령어를 사용함으로서 SSID 를 드라이버로 보낸다. 이 정보는 반드시 nego 명령어를 호출하기 전에 드라이버로 전달되어야 한다.

#iwpriv wlan0 p2p_set ssid=SsidString

nego 명령어는 group negotiation 과정을 위해 Wi-Fi 드라이버에 알린다.

#iwpriv wlan0 p2p_set nego=00:11:22:33:44:55

그림 2 에서, P2P 디바이스2 는 P2P state machine 을 모니터하기 위해 status 와 role 명령어를 사용하고 있다. P2P 디바이스2 의 UI 는 단지 P2P 디바이스1 이 어떤 종류의 정보를 보냈는지 알 수 있다.

#iwpriv wlan0 p2p_get status
Return string : Status=02 or Status=10
 
#iwpriv wlan0 p2p_get role
Return string: Role=01

다음 두개의 enum 은 status 와 role 명령어들을 위한 정의다.

enum P2P_STATE {
P2P_STATE_NONE = 0, // P2P disable
P2P_STATE_IDLE = 1, // P2P had enabled and do nothing
P2P_STATE_LISTEN = 2, // In pure listen state
P2P_STATE_SCAN = 3, // In scan phase
P2P_STATE_FIND_PHASE_LISTEN = 4, // In the listen state of find phase
P2P_STATE_FIND_PHASE_SEARCH = 5, // In the search state of find phase
P2P_STATE_TX_PROVISION_DIS_REQ = 6, // In P2P provisioning discovery
P2P_STATE_RX_PROVISION_DIS_RSP = 7,
P2P_STATE_RX_PROVISION_DIS_REQ = 8,
P2P_STATE_GONEGO_ING = 9, // Doing the group owner negoitation handshake
P2P_STATE_GONEGO_OK = 10, // finish the group negoitation handshake with success
P2P_STATE_GONEGO_FAIL = 11,// finish the group negoitation handshake with failure
P2P_STATE_RECV_INVITE_REQ = 12,// receiving the P2P Inviation request
P2P_STATE_PROVISIONING_ING = 13, // Doing the P2P WPS
P2P_STATE_PROVISIONING_DONE = 14, // Finish the P2P WPS
};
...
enum P2P_ROLE {
P2P_ROLE_DISABLE = 0,
P2P_ROLE_DEVICE = 1,
P2P_ROLE_CLIENT = 2,
P2P_ROLE_GO = 3
};

예를 들면, P2P 디바이스2 의 UI 는 P2P 디바이스1 이 Provision Discovery 과정 중 일때, 'Status=08' 을 얻을 것이다. 'Status=10' 은 group negotiation 과정이 성공적으로 끝났을 때를 뜻한다. 'Status=11' 은 group negotiation 과정이 실패했을 때를 뜻한다.

P2P Device1 과 P2P Device2 가 group negotiation 을 끝낸 후에, 그것들은 다음 동작을 하기위한 role 을 알기위해 role 라는 명령어를 사용할 수 있다.

#iwpriv wlan0 p2p_get role
Return string: Role=02

만일 'Role=02' 라는 반환 문자가 나왔다면, P2P 디바이스는 다음 동작에서 802.11 client 로 동작 한다. UI 는 P2P 디바이스와 WPS 동작을 하기위해 wpa_supplicant 를 시작한다.

만일 'Role=03' 라면, P2P 디바이스는 다음 동작에서 802.11 AP 로 동작한다. UI 는 Soft AP 기능을 활성화하기 위해 hostapd 를 시작하고, WPS 동작을 활성화한다.

P2P Device1 과 P2P Device2 둘다 role 이 확정된 후에, 'Role=02' 를 얻은 P2P 디바이스는 wpa_supplicant 를 백그라운드에서 시작하고 wpa_cli 로 PIN Code 또는 PBC 를 WPS 동작을 위해 실행한다.

같은 말로, 'Role=03' 의 P2P 디바이스는 백그라운드로 hostapd 를 실행하고, WPS 동작을 위해 hostapd_cli 를 PIN Code 또는 PBC 로 실행한다.

Wi-Fi Direct 명세는 P2P 디바이스가 GO 가 되어 그것의 시스템 상에 DHCP 서버 프로그램을 제공되어야 한다. DHCP 서버를 시작하고 DHCP client 에 IP 주소를 제공할 준비가 되어야 한다.
명세는 또한 P2P client 가 된 P2P 디바이스가 DHCP client 프로그램을 시작하여 wpa_supplicant 로 AP 에 성공적으로 802.11 접속이 성립된 후에 P2P GO 로부터 IP 주소를 요청하여야 한다.

API 및 Test Program(Realtek)

realtek 드라이버에서는 기본적으로 P2P, 즉 Wi-Fi Direct 를 지원한다. 해당 참조 문서는 다음과 같다.

API 정의 문서에서 언급한 것은 모두 iwpriv 명령어를 사용한 방법이다. 이후 P2P 동작을 위한 API 구현 시, 시스템 함수를 사용해야 할 것이다.

여기서 설명하는 예제 프로그램은 realtek 드라이버에 포함된 것이다. 먼저 드라이버의 압축을 풀고, 아래와 같이 빌드해야 하는데, 그전에 install.sh 파일을 다운로드 받는다.
기존의 install.sh 파일은 실행 시 에러가 발생하기 때문에, 다운로드 받은 파일로 대체한다.

#cd fscommand/Linux/WiFi_Direct_User_Interface
#./install.sh

realtek 드라이버의 모듈을 올린다.

#./P2P_UI wlan2
****************************************************************************************************
*                                      P2P UI TEST v0.5                                            *
****************************************************************************************************
* Enable: [Disabled]                                                                               *
* Intent:  1                                                                                       *
* Status: P2P_STATE_NONE                                                                           *
* Role: P2P_ROLE_DISABLE                                                                           *
* WPS method: P2P_NO_WPSINFO                                                                       *
* PIN code: 12345670                                                                               *
* Device name: "RTL8192CU"                                                                         *
* Peer device address: 00:00:00:00:00:00                                                           *
* Peer interface address: 00:00:00:00:00:00                                                        *
*                                                                                                  *
* e) Wi-Fi Direct Enable/Disable                                                                   *
* i) Intent ( The degree to be Group Owner/SoftAP )                                                *
* a) Scan Wi-Fi Direct devices                                                                     *
* m) Peer device address you want to test                                                          *
* p) Provision discovery                                                                           *
* c) Input PIN codes                                                                               *
* w) WPS method                                                                                    *
* n) Group owner negotiation                                                                       *
* x) Start wpa_supplicant/hostapd                                                                  *
* h) Set operation channel                        | t) Set SoftAP ssid                             *
* r) Get Current P2P Role                         | s) Get Current P2P Status                      *
* d) Set device name                              | l) Set Listen channel                          *
* f) Reflash Current State                        | q) Quit                                        *
****************************************************************************************************
*                                                                                                  *
****************************************************************************************************
*                                                                                                  *
*                                                                                                  *
*                                                                                                  *
*                                                                                                  *
*                                                                                                  *
*                                                                                                  *
*                                                                                                  *
*                                                                                                  *
*                                                                                                  *
****************************************************************************************************
*insert cmd:

실행 순서는 다음과 같다.

  1. Wi-Fi Direct 기능을 활성화한다(e)
  2. Direct 기능을 지원하는 디바이스를 검색한다(a)
  3. 접속하려는 디바이스를 지정한다(m 입력 후, 리스트 목록번호 입력)
  4. Direct 접속 시 사용할 방법을 지정한다(display/keypad/pbc/label)
  5. 방법에 따라 상대방 기기의 pin 코드를 입력한다

이외에도, intent 값이나 ssid 를 수정할 수 있고, 현재 상태를 확인할 수 있다.

방법 접속 시 현상
display 상대방의 화면에 pin 코드를 test program 에 입력한다
keypad 상대방의 화면에 realtek 드라이버의 pin 코드를 입력할 수 있는 창이 뜨고, 여기에 test program 의 pin 코드를 입력한다
pbc 상대방의 화면에 pbc 버튼창이 출력되고 이를 누른다
label 상대방의 기기 라벨에 쓰여진 pin 값을 test program 에 입력한다. 이때 상대방 기기에는 아무런 창도 출력되지 않는다
  • computer/technology/wi-fi_direct.txt
  • Last modified: 3 years ago
  • by likewind