블루킷으로 구현하는 랜 엑세스 포인트

일반입력 :2002/10/10 00:00

이윤승

지난 호에 연재한 내용대로 '블루킷'을 직접 제작해 봤다면 이번 호에는 이를 응용할 수 있는 방법을 알아보자. 우선 자신이 제작한 블루킷이 제대로 동작할 수 있도록 펌웨어를 다운로드하고 설정하는 것부터 시작해야 할 것이다. 또한 블루챗(BlueChat)이라는 프로그램을 이용해 동작 테스트를 해본 다음 블루투스 랜 엑세스 포인트를 구현해 보자(필자의 개인적인 생각이겠지만 다양한 네트워크 프로그램들을 사용하기 때문에 이번 내용이 지난 호보다 훨씬 더 흥미로운 시간이 되지 않을까 싶다).

블루킷 테스트

블루킷이 제대로 동작하기 위해서는 블루킷에서 펌웨어(firmware)가 정상적으로 동작하는지 확인해야 한다. CSR은 자사의 블루투스 칩을 완벽하게 동작시키기 위해 지속적으로 펌웨어를 업그레이드하고 있다. 블루킷은 펌웨어 업그레이드를 할 수 있도록 SPI 인터페이스를 지원한다. 최신 펌웨어로 업그레이드하고 난 다음 사용자가 사용하려는 인터페이스(USB, H4, BCSP 등)에 따라 각각 펌웨어 설정(configuration)을 해야 한다. 최종적으로 일련의 작업들이 적절하게 적용되었는지 확인하기 위해 테스트 프로그램을 실행시켜 블루킷의 동작 상태를 테스트하면 된다. 여기서 사용할 프로그램들은 '이달의 디스켓'을 통해 얻을 수 있다.

<그림 1>은 블루투스의 기본적인 프로토콜 스택을 보여준다. 블루킷에 다운로드되는 펌웨어는 Baseband, LMP 부분의 기능을 수행한다.

블루킷 펌웨어 업그레이드

블루킷에 펌웨어를 업그레이드하기 위해 SPI 케이블을 PC와 블루킷에 연결한다. 여기서 사용되는 프로그램은 CSR에서 제공하는 'Blue Flash'라는 프로그램이다. 이 프로그램은 현재 블루킷에서 사용하고 있는 펌웨어 버전을 확인 할 수 있다. 그리고 원하는 펌웨어를 선택해서 블루킷에 다운로드할 수 있다. 펌웨어 다운로드 방법은 다음과 같다.

① 블루킷의 SPI 단자와 컴퓨터의 병렬 포트를 SPI 케이블을 통해 연결한다.

② Blue Flash를 실행하면 <화면 1>과 같은 창을 볼 수 있다. 'Firmware ID' 버튼을 클릭하면 현재 저장하고 있는 펌웨어 버전 정보를 볼 수 있다.

③ 'Stop Processor' 버튼을 클릭하면 이 버튼이 'Start Processor'라고 표시된다. 이 버튼을 클릭하면 펌웨어를 다운로드할 수 있도록 블루투스 칩 내부에서 동작하는 마이크로프로세서를 멈추게 한다. 주의할 점은 펌웨어 업그레이드가 끝나면 'Start Processor' 버튼을 클릭하거나 블루킷의 리셋 버튼을 눌러 프로세서를 재동작시켜야 한다.

④ 만약의 경우를 대비해서 현재 블루킷에 저장되어 있는 펌웨어를 저장해 둘 필요가 있다. 'Dump' 버튼을 클릭하고, 적절한 파일명을 입력해서 펌웨어를 백업한다.

⑤ 'Flash Erase' 버튼을 클릭하면 펌웨어가 저장될 플래시 메모리를 깨끗이 지운다. 이레이징(erasing) 작업이 끝나면 성공적으로 플레시 메모리가 지워졌다는 메시지가 나온다.

⑥ 이레이징 작업이 완료되면 'Choose File' 버튼을 클릭해서 업그레이드하려는 펌웨어 파일을 선택한다.

⑦ 업그레이드할 펌웨어를 선택한 후 'Download' 버튼을 클릭하면 펌웨어 다운로드를 시작한다. 진행 막대를 통해 다운로드 상태를 알 수 있다.

⑧ 모든 과정이 끝나면 'Finished, Successful'이라는 메시지가 나온다. 이로써 현재 블루킷에는 사용자가 선택한 새로운 펌웨어가 다운로드됐다. 'Firmware ID' 버튼을 누르면 새로운 펌웨어의 버전 정보를 확인할 수 있다.

펌웨어 설정

블루킷의 펌웨어가 새롭게 업그레이드되면 독자들은 자신이 원하는 상태로 펌웨어의 설정을 변경해야 한다. 펌웨어 설정을 변경하기 위해선 CSR의 'PSTool'이라는 프로그램을 사용한다. 펌웨어 설정을 변경할 때 일반적으로 변경되는 사항은 '블루투스 어드레스(Bluetooth Address)', '장치 분류(Class of Device)', '호스트 인터페이스(Host Interface)'이고, 호스트 인터페이스로 UART를 선택할 경우 추가적으로 '통신속도(UART : baud rate)', 'BCSP 사용 여부(UART : non-BCSP enable?)'를 설정해야 한다. 일반적으로 블루투스 모듈을 구입하면 필수적인 값들이 최적의 상태로 설정되어 있다. 따라서 펌웨어를 업그레이드하기 전에 PSTool을 이용해서 중요한 사항들을 기록해 두는 것도 좋은 방법이다.

PSTool을 실행하면 <화면 2>와 같은 인터페이스 선택 화면을 볼 수 있다. PSTool은 5가지의 다양한 인터페이스를 지원한다. SPI 케이블이 연결된 경우 SPI BCCMD를 선택하면 된다. 여기서는 SPI 케이블이 연결된 것으로 가정하고 설명을 진행한다. 다른 인터페이스를 사용하는 경우라도 설정 방법은 모두 같기 때문에 설정하는데 특별한 문제는 없을 것이다.

인터페이스를 선택하고 'OK' 버튼을 클릭하면 PSTool 창이 나온다. 처음에는 <화면 3>처럼 블루투스 어드레스(Bluetooth Address) 등 몇 가지 사항만을 볼 수 있다. 우리가 관심을 가지고 있는 호스트 인터페이스(Host Interface) 선택 항목은 아무리 찾아봐도 없을 것이다. 이것은 PSTool에서 변경할 수 있는 사항이 너무 많기 때문에 아주 기초적인 내용만을 보여주기 때문이다. PSTool을 처음 실행시킬 때 나오는 항목을 보기 위해서는 다음과 같은 3가지 핫키(Hot Key)를 사용해야 한다.

: 사용자 항목만 보여준다.

: 사용자 항목과 개발자 항목을 보여준다.

: 설정할 수 있는 모든 항목을 보여준다.

지금까지 설명한 내용은 PSTool의 전체적인 내용이고, 이제부터 독자가 호스트 인터페이스(Host Interface)를 변경하는 경우 어떻게 설정을 바꿔야 하는지 설명한다.

H4로 변경하는 경우

H4 인터페이스는 일반적인 UART 인터페이스를 사용하는 경우이다. H4라는 이름은 블루투스 스펙에서 UART 인터페이스에 대한 내용이 'PART H:4'에 기술되어 있기 때문에 만들어진 이름이다. 설정 방법은 다음과 같다.

① PSTool을 실행한다. 인터페이스는 일반적으로 SPI BCCMD를 선택한다. 단 SPI 케이블이 연결된 상태여야 한다. (<화면 2>참조)

핫키를 이용해 개발자 항목을 볼 수 있게 한다.

③ 'Host Interface' 항목에서 'UART link running H4'를 선택하고 'Set' 버튼을 클릭한다.

④ UART baud rate 항목에서 '115.2 kbaud'를 선택한다. 다른 Baud rate를 선택해도 된다.

⑤ 'UART Bitfields' 항목을 168로 설정한다.

이 값은 블루킷의 UART 포트 설정을 변경한다. 각 비트에 대한 내용은 <표 1>과 같다.

<표 1> UART Bitfield 설명

BCSP로 결정된 경우

BCSP는 CSR에서 고속 시리얼 통신을 위해 만든 통신 프로토콜이다. BCSP를 인터페이스로 사용할 경우 1Mbps 이상의 속도로 시리얼 통신을 할 수 있다. 그러나 일반적인 PC의 경우 고속의 시리얼 통신을 하드웨어적으로 지원하지 않기 때문에 BCSP는 무용지물이다. BCSP 인터페이스 설정 방법은 다음과 같다.

① PSTool을 실행한다. 인터페이스는 일반적으로 SPI BCCMD를 선택한다. 단 SPI케이블이 연결된 상태여야 한다(<화면 2>참조).

핫키를 이용해서 개발자 항목을 볼 수 있게 한다.

③ 'Host Interface' 항목에서 'UART link running BCSP'를 선택하고 'Set' 버튼을 클릭한다.

④ UART baud rate 항목에서 '115.2 kbaud'를 선택한다. 다른 Baud rate를 선택해도 된다.

⑤ 'UART Bitfields' 항목을 6으로 설정한다. Bitfield에 각 비트의 내용은 H4와 같다.

USB로 결정된 경우

USB는 블루투스와 궁합이 가장 잘 맞는 인터페이스다. H4나 BCSP 인터페이스를 사용할 경우 여러 가지 이유로 블루투스에서 지원하는 최대 1.5Mbps의 전송 속도를 충분히 소화할 수 없지만, USB의 경우 기본적으로 1.5Mbps전송 속도를 지원하기 때문에 블루투스의 최대 전송 속도를 충분히 소화할 수 있다. USB 인터페이스 설정은 다음과 같다.

① PSTool을 실행한다. 인터페이스는 일반적으로 SPI BCCMD를 선택한다. 단 SPI 케이블이 연결된 상태여야 한다(<화면 2>참조).

핫키를 이용해서 개발자 항목을 볼 수 있게 한다.

③ 'Host Interface' 항목에서 'USB link'를 선택하고 'Set' 버튼을 누른다.

USB 인터페이스의 경우 H4나 BCSP 인터페이스처럼 전송 속도나 포트 설정을 따로 할 필요가 없기 때문에 설정이 비교적 간단하다.

블루챗을 이용한 블루킷 테스트

앞서 설명한 펌웨어 업그레이드와 펌웨어 세부 설정이 완료되면, 이제부터 본격적으로 블루킷의 동작 테스트를 해볼 수 있다. 동작 테스트를 위해 사용되는 프로그램은 '블루챗'이으로, 이 프로그램 역시 CSR에서 제공되는 데모 프로그램이다. 독자들은 블루챗을 이용해 블루킷에서 Inquiry, ACL 연결, SCO 연결, 파일 전송, 텍스트 전송 등을 테스트해볼 수 있다.

블루챗을 통해 블루킷을 테스트하기 위해서는 2대의 블루킷과 2대의 PC가 필요하다. 두 대의 PC가 없을 경우 블루킷을 각각 'COM1'과 'COM2'에 연결한 후 사용해도 된다. 이 원고에서는 인터페이스로 'UART link running H4'를 설정하고, 전송 속도를 '115200bps'로 설정한 것으로 가정하고 설명을 진행하겠다.

다음은 블루챗을 통해 블루킷간의 통신을 설명한다.

① 블루챗을 실행시키면 PSTool에서처럼 호스트 인터페이스(Host Interface)를 선택하라는 창이 뜬다. 'Protocol'은 H4로 설정하고, 'Port and Baud Rate'은 각각 COM1, 115200으로 설정한다.

② 두 대의 컴퓨터에 블루킷이 연결된 경우 <화면 5>와 같은 초기화면이 나타난다. 블루투스 어드레스(Bluetooth Address)가 각각 다를 것이다. 만일 블루투스 어드레스가 같은 경우 정상적인 통신이 이루어질 수 없으므로 앞에서 설명한 PSTool을 이용해 블루투스 어드레스를 변경해야 한다.

③ PC-1은 마스터로 설정하고 PC-2는 슬레이브로 설정한다.

④ 마스터로 설정된 PC-1에서 'Inquire' 버튼이 활성화되며, 이 버튼을 클릭하면 몇 초 후에 PC-2의 블루투스 어드레스를 표시한다. Inquire는 주변에 있는 블루투스 장치를 스캔(scan)해서 찾아주는 명령이다. 만일 주변에 블루투스 장치가 여러 개 존재한다면 존재하는 장치들이 모두 찾아질 것이다. 메시지 창을 보면 'page scan mode', 'inquiry complete : Device found...'라는 메시지를 볼 수 있다.

⑤ Bluetooth Device Addresses 항목에 있는 Address에서 PC-2의 Address를 선택하고 'Connect' 버튼을 클릭한다. 잠시 후 ACL 연결이 되고, Xfer type 항목에 'Data'가 선택된다. 이렇게 되면 데이터가 연결된 상태이다. 메시지 창을 보면 'Connection Complete'라는 메시지를 볼 수 있다.

파일 전송

앞에서 설명한 것처럼 블루킷간 데이터 연결이 된 상태에서 파일 전송 테스트를 해볼 수 있다.

① 'File Transfer'항목에서 '…'버튼을 클릭하면 파일 선택창이 열린다.

② 열기 버튼을 클릭하면 파일이 선택된다. 파일을 선택한 후 'Send' 버튼을 클릭하면 데이터 전송이 시작된다.

③ 데이터 전송 상태는 PC-1, PC-2의 각각의 상태 바를 통해 볼 수 있다.

④ 전송이 완료되면 완료를 알리는 창이 표시된다.

오디오 연결

블루킷에서는 오디오 출력을 위한 코덱(Codec) 기능을 지원하지 않지만 블루투스 오디오 연결은 지원한다. 실제 소리를 듣기 위해서는 독자가 확장 커넥터의 PCM 단자를 이용해 코덱 회로를 구성하면 블루투스 무전기와 같은 오디오 연결을 실험해 볼 수 있다. 오디오 연결을 하기 위해서는 반드시 데이터 연결이 된 다음 오디오 연결을 시도해야 한다(블루투스 스펙 참조). Xfer Type 항목에서 오디오를 선택하면 PC-1, PC-2에 각각 오디오 연결로 선택된다. 메시지 창을 보면 오디오 연결이 됐음을 확인할 수 있다.

채팅 테스트

블루챗이라는 이름처럼 이 프로그램을 이용해서 채팅을 해볼 수 있다. 물론 블루투스 무선 데이터 연결을 이용해서 이루어지는 채팅이다.

① 파일 전송의 ①∼⑤와 똑같이 진행한다. 채팅 테스트도 데이터 연결이 이루어진 다음 실행된다.

② PC-1의 'Chat link' 항목에서 문자를 입력하면 PC-2의 'Chat link' 항목에 문자가 표시된다.

블루투스 랜 액세스 포인트

지금부터 동작이 확인된 블루킷을 이용해 블루투스 랜 액세스 포인트를 구성할 것이다. 독자들이 직접 제작한 블루킷으로 무선 인터넷 환경을 구축할 수 있다는 확신을 갖고 한 번 도전해 보기 바란다. 그럼 이제 출발하겠다.

블루투스 프로토콜 스택

OpenBT란 Axis Communication에서 진행중인 Open Bluetooth Stack Project이다. 많은 개발자들이 이 프로젝트에 참여하고 있기 때문에 프로토콜 스택은 빠르게 버전업되고 있으며, 그에 따라 빠른 속도로 안정화되고 있다. 모든 리눅스 프로젝트처럼 소스는 모두 공개돼 있고 GPL 규정에 따라 자유롭게 사용이 가능하다. 초기 릴리즈는 사용하기도 어려웠고, 버그도 많았다. 하지만 현재는 어느 정도 안정화가 되었고 실제 Axis사에서는 몇몇 기능을 추가해서 OpenBT에 기반을 둔 랜 액세스 포인트를 판매하고 있다. 리눅스 환경에서 개발된 OpenBT는 리눅스의 다양한 네트워킹 프로토콜과 유기적으로 동작할 수 있도록 설계되었다.

<그림 2>는 OpenBT의 구조를 보여준다. 그림에서 ttyS0는 리눅스에서 기본적으로 사용하는 시리얼 포트의 장치 이름이다. 시리얼 포트를 통해 PPP가 사용될 경우 왼쪽 그림과 같이 시리얼 드라이버가 사용된다. OpenBT가 장치 드라이버로 사용될 경우 오른쪽 그림과 같이 ttyBT0는 ttyS0를 대신해서 사용되고, 기존 ttyS0는 블루투스 드라이버와 시리얼 드라이버를 연결하는 인터페이스로 사용된다. 그림에서 진하게 표시된 부분이 OpenBT가 디바이스 드라이버로 추가된 영역이다.

OpenBT는 http://sourceforge.net/projects/openbt에서 다운로드받을 수 있다. 여기에서 사용되는 OpenBT의 버전은 최종 릴리즈인 2002/10/21일자 버전인 0.0.8이다. 따라서 독자들은 0.0.8 버전을 다운로드하면 된다. OpenBT는 지속적으로 버그가 수정되고 새로운 기능이 추가되기 때문에 될 수 있으면 최신 버전의 스택을 사용하는 것이 좋다.

시스템 환경

OpenBT는 리눅스를 기반으로 만들어졌기 때문에 OpenBT를 사용하기 위해 리눅스를 탑재한 PC가 필요하다. 그리고 랜 액세스 포인트를 구성하기 위해서는 PPP, Netfilter 등의 네트워크 모듈도 리눅스 PC에 설치돼 있어야 한다. 필자가 사용하는 시스템 환경은 다음과 같다.

서버측 PC(랜 액세스 포인트)

- 펜티엄 4 600MHz, 192MB 메모리

- 레드햇 7.2(커널 버전 2.4.7-10)

- pppd 버전 2.4.1-2

- iptables 버전 1.2.3-1

- COM 1 포트에 블루킷 연결(장치 주소 00:05:C9:00:00:91)

- KT의 외장형 ADSL 사용

- 이더넷 카드 2개(Eth0는 ADSL에서 사용, Eth1은 사용하지 않음)

클라이언트측 PC

- 셀러론 300MHz, 128MB 메모리

- 레드햇 7.2(커널 버전 2.4.7-10)

- pppd 버전 2.4.1-2

- iptables 버전 1.2.3-1

- COM 1 포트에 블루킷 연결(장치 주소 00:05:C9:00:00:90)

- 이더넷 카드 1개(사용하지 않음)

리눅스를 이용해 무엇인가를 할 때 문제가 되는 것은 커널 버전 또는 패키지 버전에 따라 사용법이 바뀔 수도 있고 서로 호환이 되지 않을 수도 있다는 것이다. 리눅스에 대한 내공(?)이 쌓여 있는 독자들일 경우 이러한 문제들을 충분히 헤쳐나갈 수 있겠지만, 초보 개발자들에게는 이런 것들이 커다란 장벽처럼 느껴질 수도 있다. 따라서 이번 연재를 통해서 처음으로 리눅스에 접하는 독자들은 사용하는 리눅스 커널, pppd, iptables의 버전을 필자가 사용하는 것과 일치시킨다면 불필요한 수고를 덜 수 있을 것이다.

OpenBT 컴파일 및 설치

이번에는 OpenBT를 컴파일하고, 블루투스 디바이스 드라이버인 bt.o 모듈을 커널에 설치해 보겠다. 리눅스 PC를 부팅한다. 디바이스 드라이버를 설치해야 하기 때문에 반드시 root 계정으로 로그인해야 한다. 그 다음 다운로드된 OpenBT 0.0.8 버전 파일의 압축을 풀어야 한다. 만일 OpenBT 파일을 다운로드 하지 않은 경우 앞서 언급한 것처럼 OpenBT-0.0.8 버전을 다운로드한 후 OpenBT 파일의 압축을 풀면 된다.

#tar vxfz openbt-20011021.tar.gz

압축을 풀면 openbt라는 디렉토리가 생기고 이 디렉토리에 OpenBT의 모든 디렉토리와 파일들이 생성된다. OpenBT는 기본적으로 에릭슨에서 제작된 블루투스 장치를 사용한다. 따라서 블루킷에서 OpenBT를 동작하기 위해서는 btconfig.h 파일을 수정해야 한다.

#cd linux/include/linux/bluetooth

#vi btconfig.h

btconfig.h에서 /* This sets current HW */ 부분을 수정해야 한다. 블루킷은 CSR에서 제작한 블루투스 칩을 사용하기 때문에 CSR Hardware이 선택되도록 변경해야 한다.

<리스트 1> btconfig.h 수정

/* This sets current HW */

#undef CONFIG_BLUETOOTH_NOINIT

#define CONFIG_BLUETOOTH_CSR // #undef을 #define으로 변경

#undef CONFIG_BLUETOOTH_DIGIANSWER

#undef CONFIG_BLUETOOTH_ERICSSON // #define을 #undef으로 변경

#undef CONFIG_BLUETOOTH_INFINEON_BMI

#undef CONFIG_BLUETOOTH_GENERIC

#undef CONFIG_BLUETOOTH_USBMODULE /* Not implemented */

수정해야 할 또 하나의 파일은 btdebug.h 파일이다. OpenBT는 프로토콜 스택이 동작하는 상황을 출력해준다. 개발자들은 btdebug.h에서 출력될 내용을 선택할 수 있다. 원하는 내용을 보기 위해서는 해당 항목을 1로 정의해야 한다. 이런 설정을 통해 개발자들은 수신된 데이터 패킷, 송신될 데이터 패킷, 프로토콜 레이어별 동작 상태를 볼 수 있다.

이번엔 Makefile을 수정해야 한다. Makefile에서 INCLUDEDIR 설정을 변경해야 하는데 2.2 버전의 커널을 사용할 경우 수정하지 않아도 되지만 2.4 이상의 버전을 사용하는 독자들은 다음과 같이 수정해야 한다.

# cd /root/openbt/linux/drivers/char/bluetooth

# vi Makefile

INCLUDEDIR = /usr/include 수정 전

INCLUDEDIR = /lib/modules/2.4.7-10/build/include 수정 후

수정할 때 2.4.7-10 문자열은 독자들의 리눅스 커널 버전에 따라 달라질 수 있다. 현재 필자는 2.4.7-10 버전의 커널을 사용하고 있다. 독자들의 커널 버전을 확인하기 위해 다음 명령을 실행하면 된다.

# uname -r

모든 수정이 끝난 다음 openbt 디렉토리로 이동해서 다음 명령어로 컴파일 환경을 만든다.

# source init_env

다음 명령어로 컴파일을 수행한다.

# make all

컴파일이 완료된 후 /usr/local/bin, /etc에 생성된 application 파일과 SDP 설정파일을 설치하기 위해 다음 명령을 실행한다.

# make install

만일 처음으로 OpenBT를 설치하는 경우라면 Bluetooth Device Node를 생성하기 위해 다음 명령을 실행해야 한다.

# make devs

여기까지 실행을 마치면 각 디렉토리에 OpenBT 블루투스 스택의 모듈과 실행 파일들이 생성되어 있을 것이다. OpenBT 블루투스 스택 디바이스 드라이버 모듈(bt.o)을 커널에 올리기 위해서 다음 명령을 실행한다.

# cd /root/openbt/linux/drivers/char/bluetooth/

# insmod bt.o

참고로 insmod 명령어는 모듈을 커널에 추가하는 명령이다.

만일 insmod 명령을 실행했는데 'insmod : a module named bt already exists'라는 에러가 나오면 이미 bt.o가 커널에 올라간 상태이다. 다시 bt.o를 커널에 올리고 싶을 경우 다음 명령을 실행시키면 bt.o가 커널에서 삭제된다.

#rmmod bt

그런 다음 insmod 명령을 다시 실행한다.

#insmod bt.o

bt.o가 정상적으로 커널에 추가되면 다음과 같은 메시지를 볼 수 있다.

Bluetooth Driver v1.3, Copyright (c) 2000, 2001 Axis Communications AB

BT SYS: Bluetooth driver registered in ttyBT

BT SYS: Bluetooth line discipline registered.

BT (driver) Initiating bt ctrl struct

BT SYS: Registering BT proc files

BT SYS: Bluetooth Driver Using ttyBT[0-6] (data), ttyBTC (ctrl [7])

블루투스 스택에서 출력되는 메시지는 /var/log 디렉토리에 있는 messages 파일을 보면 된다. 이 파일은 프로그램 실행시 발생하는 각종 메시지를 저장하고 있다.

여기까지 마치면 리눅스 PC에는 <그림 7>과 같이 블루투스 프로토콜 스택이 존재하게 된다. 이젠 애플리케이션 프로그램을 이용해서 블루킷을 통해 OpenBT를 실행해 보도록 하겠다.

OpenBT 실행

현재 블루투스 프로토콜 디바이스 드라이버가 커널에 올라가 있는 상태이다. 이 디바이스 드라이버가 커널에서 제대로 동작하는지 직접 확인해 보도록 하자. 먼저 블루킷을 COM 1에 연결하고, 전원을 켠다. 그리고 다음과 같이 블루킷을 동작시키는 프로그램을 실행한다.

# cd /root/openbt/apps/Bluetooth/btd

# btd

Btd 실행 후 다음과 같은 메시지가 나오면 블루킷이 정상적으로 동작하고 있는 것이다.

Bluetooth Control Application

-----------------------------

Running as server

Physdev /dev/ttyS0, btdev /dev/ttyBT0, speed 115200 baud

Registered bluetooth line discipline on /dev/ttyS0

Init stack

Setting write_scan_enable in CSR module!

Setting write_pagescan_activity in CSR module!

Setting event filter in CSR module!

좀더 상세한 내용은 /proc 디렉토리에 있는 bt_status, bt_internal 파일을 통해 확인할 수 있다.

<리스트 2> /proc/bt_status

[LOCAL INFO]

stack_initiated : TRUE <-- 블루킷이 정상적으로 초기화 됨

bytes_received : 0

bytes_sent : 0

local_bd_address : 00:05:c9:00:00:90 <-- 블루킷의 블루투스 장치 주소

[REMOTE INFO]

unit_id unit_bd_address unit_mode unit_name <-- 다른 장치와 연결이 없기 때문에 내용이 없음

<리스트 3> /proc/bt_internal

[Bluetooth Status]

------------------------------

bytes received : 0

bytes sent : 0

[Hardware]

Vendor: CSR

Firmware info:

Firmware version: 99

[BT Interface]

line[0] state: BT_UPPERCONNECTED

line[1] state: BT_INACTIVE

line[2] state: BT_INACTIVE

line[3] state: BT_INACTIVE

line[4] state: BT_INACTIVE

line[5] state: BT_INACTIVE

line[6] state: BT_INACTIVE

BT CTRL state: BT_UPPERCONNECTED [1 open]

[BTMEM]

Buffer holds: 0

Bytes left: 2224

[RFCOMM]

[L2CAP]

local bd :[00:05:c9:00:00:90]

[HCI]

unit_id unit_bd_address unit_mode unit_name

The connected hci handlers are:

Free data buffers in HW : 8

Free command buffers in HW : 1

---------------------------------------

다음 단계를 위해 블루킷의 상태를 확인한 다음 키를 눌러서 btd 실행을 종료한다.

OpenBT를 이용한 블루킷 연결

블루투스 장치간의 연결로 구성된 네트워크를 피코넷(Piconet)이라 부른다. 피코넷은 1개의 마스터와 최대 7개의 슬래이브로 구성된 네트워크이다. 각각의 피코넷이 서로 연결되면 좀더 큰 스캐터넷(Scatternet)을 이룬다. 이번 연재에서는 두개의 블루트스 장치간의 연결만을 다룬다. 따라서 한 쪽 장비는 마스터가 되고 다른 쪽 장비는 슬레이브가 될 것이다. 일반적으로 마스터는 서버의 역할을 하게 되고, 슬래이브는 클라이언트의 역할을 한다. 이제 블루킷간의 연결을 수행해 보자. 서버 역할을 하는 PC에서는 다음과 같은 명령을 실행한다.

# cd /root/openbt/apps/Bluetooth/experimental/

# ./btdm -m 0

btdm은 멀티 포인트 블루투스 데몬 어플리케이션으로, 다중 연결을 지원한다. btdm에서 -m 0옵션은 모뎀 에뮬레이션을 하지 않겠다는 의미이다. 명령 실행 후 서버PC는 클라이언트로 요청되는 연결 메시지를 기다리는 상태가 된다.

클라이언트 PC에서는 btd 실행파일을 실행한다. <화면 6>은 btd를 실행한 화면이다. btd 옵션으로 --client, --physdev=/dev/ttyS0, --modem=0을 사용했다. 현재 PC를 클라이언트로 동작시키고, 블루킷과 연결된 시리얼 포트가 ttyS0이고, 모뎀 에뮬레이션을 하지 않겠다는 의미이다. btd를 실행하면 메시지를 통해 동작 내용을 보여준다. 블루킷을 초기화, 명령행으로 들어간다. inq 명령은 주변에 존재하는 블루투스 장비를 찾는 명령이다. 현재 장치 주소가 00:05:C9:00:00:91인 블루투스 장치가 찾아졌다. 이 장치는 서버로 사용할 PC의 블루킷 장치 주소이다. 마지막으로 rf_conn명령을 통해 상대편과 연결을 시도한다. 연결이 정상적으로 이루어졌을 경우 'connected.'라는 메시지가 출력된다.

연결이 정상적으로 이루어지면 <화면 7>처럼 서버 PC에는 연결된 클라이언트의 장치 주소를 보여준다.

이제 양측의 블루킷이 연결되었다. 현재의 연결은 블루투스 스택간의 연결을 의미한다. 즉 양쪽 L2CAP 레이어간의 Peer-to-peer 연결이다. 현재의 상태에서도 서로간의 간단한 데이터 통신은 가능하지만 TCP/IP 프로토콜을 사용하는 인터넷 연결을 불가능하다. 인터넷 연결을 가능하게 하기 위해 PPP 연결이 필요하다.

PPP over 블루투스

이제부터 본격적으로 블루투스 랜 엑세스 포인트 구현을 위한 작업에 들어간다. 현재까지의 작업을 통해 우리는 블루킷간의 연결을 완료했다. 이런 연결을 바탕으로 PPP 연결을 시도해보자. 한국통신이나 하나로통신을 통해 ADSL을 이용할 경우 PPPoE(PPP over Ethernet)를 이용한다. 이는 이더넷(Ethernet) 위로 PPP 연결을 이용해 사용자와 ISP간의 연결을 지원하는 서비스를 의미한다. 우리도 PPPoE처럼 블루투스 RF 연결을 바탕으로 PPP 연결을 이용하기 때문에 'PPPoB(PPP over Bluetooth)'라고 부를 수 있겠다.

일반적으로 리눅스에서 PPP 연결을 하기 위해서는 준비작업이 필요하다. 만일 PPP 패키지가 설치돼 있지 않을 경우 PPP 패키지를 설치한다. 필자가 사용하는 PPP 패키지는 2.4.1-2이다. 독자들도 버전을 확인하고, 버전이 필자의 것보다 낮은 경우 PPP 패키지를 업그레이드해야 한다. 다음 명령을 통해 현재 설치되어 있는 PPP 버전을 알아 볼 수 있다.

# rpm -q -a lgrep ppp

준비가 끝나면 서버측과 클라이언트측에서 options 파일은 수정하고, options.ttyBT0 파일은 새로 만들어야 한다. <리스트 4>, <리스트 5>, <리스트 6>, <리스트 7>은 각각 서버측과 클라이언트측에서 수정되거나 추가할 파일들이다. Options 파일은 ppp 연결시 공통적으로 참조되는 pppd 옵션을 가지고 있는 파일이고, options.ttyBT0는 ttyBT0 장치를 통해서 ppp 연결을 할 때 참조되는 pppd 옵션을 가지고 있는 파일이다.

<리스트 4> 서버측 /etc/ppp/options

noauth nodeflate nobsdcomp lock

mtu 1000

mru 1000

debug

local

<리스트 5> 서버측 /etc/ppp/options.ttyBT0

noauth nodeflate nobsdcomp lock

mtu 1000

mru 1000

debug

silent

192.168.10.1:192.168.10.2

proxyarp

<리스트 6> 클라이언트측 /etc/ppp/options

noauth nodeflate nobsdcomp lock

mtu 1000

mru 1000

debug

local

<리스트 7> 클라이언트측 /etc/ppp/options.ttyBT0

noauth nodeflate nobsdcomp lock

mtu 1000

mru 1000

debug

0.0.0.0:192.168.10.1

netmask 255.255.255.0

defaultroute

noipdefault

옵션 파일의 준비가 끝나면 PPP 연결을 시작하는데, 클라이언트 쪽에서 다음 명령을 실행한다. 특별한 에러 메시지가 표시되지 않으면 블루투스 RF 연결 위로 PPP 연결이 성공적으로 수행된 것으로 볼 수 있다.

# pppd /dev/ttyBT0

PPP 연결이 제대로 됐는지 확인하기 위해 다음 명령을 실행한다.

# ifconfig -a

<화면 8>처럼 명령을 실행하면 ppp0라는 항목이 만들어져 있는 것을 볼 수 있다. 클라이언트의 IP 주소는 서버측 options.ttyBT0에서 설정했던 192.168.10.2로 할당됐다.

<화면 9>처럼 서버측에서도 ifconfig 명령을 실행하면 ppp1이라는 항목이 만들어져 있는 것을 볼 수 있다. ppp0은 ADSL을 위해 할당된 것이다. 서버의 IP 주소는 options.ttyBT0에서 설정했던 192.168.10.1로 할당됐다.

서버나 클라이언트에서 ping 명령을 수행해 보면 PPP 연결이 정상적으로 동작하고 있음을 볼 수 있을 것이다. 이제 PPP 연결도 완료했다. 다음엔 클라이언트에서 서버를 통해 외부 네트워크로 접근할 수 있는 방법을 알아보겠다.

외부 네트워크와 연결

PPP 연결이 이뤄지면 서버와 클라이언트간의 TCP/IP 프로토콜을 이용할 수 있는 상태이다. 서버측에 웹 서버나 FTP 서버가 돌아가고 있다면 클라이언트 쪽에서 웹 브라우저를 이용해 서버 쪽의 홈페이지를 접속하거나 파일을 다운로드 받을 수 있다. 하지만 클라이언트와 외부 네트워크는 연결되지 않은 상태다. 클라이언트가 외부 네트워크에 접근할 수 있게 해주는 장치가 바로 랜 액세스 포인트이다.

<그림 3>은 랜 액세스 포인트의 프로토콜 스택을 보여준다. 랜 액세스 포인트는 서버측을 의미하고, Data Terminal은 클라이언트를 의미한다. PPP 네트워킹은 클라이언트와 서버간의 PPP 연결을 통해 전달되는 데이터를 외부 네트워크 쪽으로 전달해주는 역할을 한다. 리눅스에서는 이러한 기능을 넷필터(Netfilter)라는 패키지를 이용해 구현할 수 있다. 넷필터는 일반적으로 방화벽을 구성해주는 프로그램이지만 IP 포워딩 기능도 지원한다.

이제 Netfilter를 이용해 IP 포워딩을 수행할 수 있도록 서버를 설정한다. <리스트 8>은 현재 서버를 IP 포워딩이 동작하도록 설정하는 스크립트 파일이다. 필자는 집에서 한국통신의 ADSL을 사용하고 있다. 따라서 리눅스에서 인터넷에 연결할 경우 PPPoE가 사용된다. 필자가 구성하는 랜 액세스 포인트에서는 ppp 연결이 2개(ppp0, ppp1) 존재한다. LAN 환경에서 랜 액세스 포인트를 구성하는 독자들은 ppp0을 eth0(또는 eth1), ppp1을 ppp0으로 변경해야 할 것이다. <리스트 8>의 각 부분마다 설명을 달아 놓았지만 iptables에 대한 자세한 내용은 참고자료를 통해 얻을 수 있을 것이다.

<리스트 8> lapscript

#

# ppp0/ppp1을 각각 EXTIF/INTIF 변수로 선언

# 서버측에서 필자가 KT의 ADSL를 사용하기 때문에

# ppp0는 외부 네트워크에 해당하고

# ppp1은 블루투스를 통한 ppp 연결인 내부 네트워크이다.

# LAN 환경일 경우 EXTIF=eth0 INTIF=ppp0로 변경

EXTIF=ppp0

INTIF=ppp1

echo ---> External Ethernet Interface : $EXTIF

echo ---> Internal Ethernet Interface : $INTIF

#

# iptables + ftp 사용을 위한 모듈 등록

# iptalbe 모듈이 자동으로 등록되어 있는 경우 에러가 발생한다.

# 에러 발생시 주석 처리를 한다.

echo ---> iptables module up <---

/sbin/depmod -a

/sbin/insmod ip_tables

/sbin/insmod ip_conntrack

/sbin/insmod ip_conntrack_ftp

/sbin/insmod ip_nat_ftp

/sbin/insmod iptable_nat

#

# ip_forward를 위한 커널 매개 변수 수정

#

echo 1 > /proc/sys/net/ipv4/ip_forward

#

# Dynamic IP 사용을 위한 커널 매개 변수 수정

#

echo 1 > /proc/sys/net/ipv4/ip_dynaddr

#

# IP forwarding / Masquerading 설정

#

echo ---> Setting up IP forwarding/masquerading <---

#

# 1. 기존 rule을 지우고, 새로운 rule을 적용하기 위한 정책 설정

#

iptables -P INPUT ACCEPT

iptables -F INPUT

iptables -P OUTPUT ACCEPT

iptables -F OUTPUT

iptables -P FORWARD DROP

iptables -F FORWARD

iptables -t nat -F

echo ---> step 1 complete

#

# 2. iptables rule 설정

#

iptables -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT

iptables -A FORWARD -j LOG

echo ---> step 2 complete

#

# 3. ip masquerade 설정

#

iptables -t nat -A POSTROUTING -o $EXTIF -s 192.168.1.0/24 -j MASQUERADE

echo ---> step 3 complete

스크립트 파일을 실행하면 <화면 10>과 같은 메시지가 출력된다. 이제 서버에서 IP 포워딩이 정상적으로 동작한다.

독자들은 클라이언트에서 서버를 거쳐 외부 네트워크로 접근할 수 있다. Ping을 통해 외부와의 연결을 테스트해 볼 수 있다. <화면 11>은 서버에서 IP 포워딩이 동작하지 않은 경우와 동작하는 경우에 클라이언트에서 ping 테스트를 해본 결과를 보여준다. 211.197.14.82는 한국통신의 ADSL 연결 서버의 IP 주소이다.

만일 클라이언트측 웹 브라우저에서 외부 홈페이지 접속이 안 될 경우가 있다. 이때는 클라이언트의 DNS 서버를 설정해주면 해결된다.

클라언트측에서 웹 브라우저를 통해 인터넷 서핑이 가능하다면 블루투스 랜 액세스 포인트가 완성된 것이다. 독자들의 이해를 돕기 위해 단계별로 설명했지만 컴퓨터 부팅시 모든 과정을 자동으로 실행할 수 있게 스크립트를 작성한다면 속도가 좀 느리긴 하지만 무선 랜을 이용하는 것과 같은 느낌을 받을 수 있을 것이다. 필자의 경우 이미 1년 전에 스트롱암(StrongARM) 보드에 블루킷을 연결해서 랜 액세스 포인트를 구성해 사용했었다. 임베디드 시스템에 블루투스 스택을 올리는 것도 PC에 올리는 것과 별반 차이가 없다. 여기서 사용했던 서버설정과 스크립트를 그대로 사용할 수 있다. PC에서 성공한 독자들은 임베디드 시스템에 랜 액세스 포인트를 구현해 보는 것도 재미있는 도전이라 생각한다.

글을 마치면서

이번 연재를 통해 블루투스 개발킷 제작에서부터 블루투스 랜 액세스 포인트 구현까지 적지 않은 내용을 다루었다. 평상시 블루투스에 관심을 가지고 있었던 독자들에게 블루투스에 대한 이해를 높일 수 있는 기회가 되었으면 하는 바람이다. 이번 달에 소개된 파일들과 프로그램들은 '이달의 디스켓'을 통해 얻을 수 있고, 설명이 부족한 부분은 참고자료를 통해 자세한 내용을 얻을 수 있을 것이다. 관심을 보내준 독자들에게 다시 한 번 감사 드리며, 이것으로 연재를 마감한다. @