블로그에 와이파이 다이렉트 키워드 관련으로 찾아오는 사람이 심심하지 않게 있다는 것을 알았습니다.


(이런 글을 올리면서 한편으로는 이렇게 마이너한 지식이 과연 누군가에게 도움이 되는 일이 있을까 싶기도 합니다.)


그래서 간단한 예제를 깃허브에 업로드해 올렸습니다.


페도라 26과 우분투 16.04에서 작동하는 것을 확인했습니다.


https://github.com/NaniteFactory/Wifi-Direct-on-Linux


wifid.py

import os
import time


def setup_conf_files():
    '''start_as_go를 위한 설정파일들 생성
    :return: None
    '''
    dir = os.path.dirname(__file__) + '/conf/'  # 설정파일들 넣어둠
    _copy_file_no_overwriting(os.path.abspath(dir + 'dhcpd.conf'), os.path.abspath('/etc/dhcp/dhcpd.conf'))
    _copy_file_no_overwriting(os.path.abspath(dir + 'udhcpd.conf'), os.path.abspath('/etc/udhcpd.conf'))
    _copy_file_no_overwriting(os.path.abspath(dir + 'wpa_supplicant.conf'), os.path.abspath('/etc/wpa_supplicant.conf'))


def _copy_file_no_overwriting(src, dst):
    import shutil
    if not os.path.isfile(dst):
        print('copying... ', dst)
        shutil.copyfile(src, dst)


def _system_critical(command):
    if os.system(command) is not 0:
        raise ConnectionError('wifi direct 연결 실패')


def start_as_go_fedora(str_interface='wls35u1', str_static_ip_addr_for_p2p='192.168.1.2'):
    """Wifi direct 연결을 GO로 시작하기 (페도라 26에서 테스트함)
    1. dhcpd(dhcp 서버) 종료하고 wifi 인터페이스 내림 (인터페이스를 내리는 데에 시간이 걸리기 때문에 몇 초 대기함)
    2. wifi p2p(direct) 인터페이스 생성
    3. dhcpd(dhcp 서버) 시동하며 p2p 연결 대기
    :param str_interface: 와이파이 인터페이스명
    :param str_static_ip_addr_for_p2p: GO에게 정적 할당하는 IP 주소
    :return: None
    """
    os.system('sudo killall dhcpd')  # dhcpd 종료
    os.system('sudo wpa_cli -i ' + str_interface + ' terminate -B')  # 인터페이스 내림
    # os.system('sudo wpa_cli -i p2p-' + str_interface + '-0 terminate -B')
    time.sleep(2)  # 인터페이스가 내려갈 때까지 대기
    os.system('echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward')  # ip 패킷 포워딩 활성화
    # os.system('echo "ctrl_interface=/var/run/wpa_supplicant\nupdate_config=1" | sudo tee /etc/wpa_supplicant.conf')
    _system_critical('sudo wpa_supplicant -d -Dnl80211 -c /etc/wpa_supplicant.conf -i' + str_interface + ' -B')  # 인터페이스 올림
    _system_critical('sudo wpa_cli -i' + str_interface + ' p2p_group_add')
    # p2p_group_add: Become an autonomous GO (p2p 인터페이스 생성)
    _system_critical('sudo ifconfig p2p-' + str_interface + '-0 ' + str_static_ip_addr_for_p2p)  # p2p 인터페이스에 정적 ip 할당
    _system_critical('sudo wpa_cli -i p2p-' + str_interface + '-0 p2p_find')  # p2p_find: Enables discovery
    os.system('sudo wpa_cli -ip2p-' + str_interface + '-0 p2p_peers')
    # p2p_peers: Shows list of discovered peers (not necessary)
    _system_critical('sudo wpa_cli -ip2p-' + str_interface + '-0 wps_pbc')
    # wps_pbc: pushbutton for GO WPS authorization to accept incoming connections (When devices try to connect to GO)
    _system_critical('sudo dhcpd')  # dhcpd 실행


def start_as_go_ubuntu(str_interface='wlan0', str_static_ip_addr_for_p2p='192.168.1.2'):
    """Wifi direct 연결을 GO로 시작하기 (우분투 16.04에서 테스트함)
    페도라와 동일. 우분투에서는 dhcpd 대신 비지박스 툴인 udhcpd 사용함.
    :param str_interface: 와이파이 인터페이스명
    :param str_static_ip_addr_for_p2p: GO에게 정적 할당하는 IP 주소
    :return: None
    """
    os.system('sudo killall udhcpd')
    os.system('sudo wpa_cli -i ' + str_interface + ' terminate -B')
    # os.system('sudo wpa_cli -i p2p-' + str_interface + '-0 terminate -B')
    time.sleep(1)
    os.system('echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward')
    # os.system('echo "ctrl_interface=/var/run/wpa_supplicant\nupdate_config=1" | sudo tee /etc/wpa_supplicant.conf')
    _system_critical('sudo wpa_supplicant -d -Dnl80211 -c /etc/wpa_supplicant.conf -i' + str_interface + ' -B')
    _system_critical('sudo wpa_cli -i' + str_interface + ' p2p_group_add')
    _system_critical('sudo ifconfig p2p-' + str_interface + '-0 ' + str_static_ip_addr_for_p2p)
    _system_critical('sudo wpa_cli -i p2p-' + str_interface + '-0 p2p_find')
    os.system('sudo wpa_cli -ip2p-' + str_interface + '-0 p2p_peers')
    _system_critical('sudo wpa_cli -ip2p-' + str_interface + '-0 wps_pbc')
    _system_critical('sudo udhcpd /etc/udhcpd.conf &')


if __name__ == "__main__":
    # example
    import wifid
    wifid.setup_conf_files()
    try:
        wifid.start_as_go_fedora()
    except ConnectionError:
        print('ConnectionError from wifid')


wpa_supplicant.conf

# /etc/wpa_supplicant.conf

ctrl_interface=/var/run/wpa_supplicant
update_config=1

ap_scan=1

device_name=scope
device_type=1-0050F204-1

# If you need to modify the group owner intent, 0-15, the higher
# number indicates preference to become the GO. You can also set
# this on p2p_connect commands.
p2p_go_intent=15

# optional, can be useful for monitoring, forces
# wpa_supplicant to use only channel 1 rather than
# 1, 6 and 11:
p2p_listen_reg_class=81
p2p_listen_channel=1
p2p_oper_reg_class=81
p2p_oper_channel=1


dhcpd.conf

# /etc/dhcp/dhcpd.conf

#
# DHCP Server Configuration file.
#   see /usr/share/doc/dhcp-server/dhcpd.conf.example
#   see dhcpd.conf(5) man page
#

# specify DNS server's hostname or IP address # public google dns servers
#option domain-name-servers 8.8.8.8, 8.8.4.4;
# default lease time
default-lease-time 864000;
# max lease time # 10 days of
max-lease-time 864000;
# this DHCP server to be declared valid
authoritative;
# specify network address and subnet mask
subnet 192.168.1.0 netmask 255.255.255.0 {
    # specify the range of lease IP address
    range dynamic-bootp 192.168.1.20 192.168.1.254;
    # specify broadcast address
    option broadcast-address 192.168.1.255;
    # specify default gateway
    option routers 192.168.1.2;
}


udhcpd.conf

# /etc/udhcpd.conf

# Sample udhcpd configuration file (/etc/udhcpd.conf)
# The start and end of the IP lease block
start 		192.168.1.20	#default: 192.168.0.20
end	        192.168.1.254	#default: 192.168.0.254
# The interface that udhcpd will use
interface   p2p-wlan0-0		#default: eth0
#Examles
opt	dns	8.8.8.8  8.8.4.4 # public google dns servers
option	subnet	255.255.255.0
opt	router	192.168.1.2
option	lease	864000		# 10 days of



Top