1. 소개
Google에서 출시한 OpenThread는 스레드 네트워킹 프로토콜의 오픈소스 구현입니다. Google Nest는 Nest 제품에 사용되는 기술을 개발자에게 광범위하게 제공하여 커넥티드 홈용 제품 개발을 가속화하는 OpenThread를 출시했습니다.
스레드 사양은 홈 애플리케이션을 위한 IPv6 기반의 안정적이고 안전한 저전력 무선 기기 간 통신 프로토콜을 정의합니다. OpenThread는 IPv6, 6LoWPAN, IEEE 802.15.4(MAC 보안, 메시 링크 설정, 메시 라우팅)를 비롯한 모든 스레드 네트워킹 레이어를 구현합니다.
이 Codelab에서는 시뮬레이션된 기기에서 스레드 네트워크를 시뮬레이션하는 방법을 설명합니다.
학습할 내용
- OpenThread 빌드 도구 모음 설정 방법
- 스레드 네트워크를 시뮬레이션하는 방법
- 스레드 노드 인증 방법
- OpenThread 데몬으로 스레드 네트워크를 관리하는 방법
필요한 항목
- git
- Linux, 네트워크 라우팅에 관한 기본 지식
2. 빌드 시스템 설정
Git
이 Codelab을 완료하려면 Git이 필요합니다. 계속하기 전에 다운로드하여 설치하세요.
설치가 완료되면 특정 OS의 안내에 따라 OpenThread를 다운로드하고 빌드합니다.
Mac OS X용 XCode
Mac OS X에서 OpenThread를 설치하고 빌드하려면 XCode가 필요합니다.
XCode가 설치되면 다음과 같이 XCode 명령줄 도구를 설치합니다.
$ xcode-select --install
Linux / Mac OS X에서 빌드
이 설치 안내는 Ubuntu Server 14.04 LTS와 Mac OS X Sierra 10.12.6에서 테스트되었습니다.
OpenThread를 설치합니다. bootstrap
명령어는 도구 모음이 설치되고 환경이 올바르게 구성되었는지 확인합니다.
$ mkdir -p ~/src $ cd ~/src $ git clone --recursive https://github.com/openthread/openthread.git $ cd openthread $ ./script/bootstrap
Windows 사용
Windows를 선호한다면 이 Codelab의 Docker 버전을 사용해 보는 것이 좋습니다.
3. OpenThread 애플리케이션 빌드
설치가 완료되면 예시 OpenThread 애플리케이션을 빌드합니다. 이 Codelab에서는 시뮬레이션 예를 사용합니다.
$ cd ~/src/openthread $ ./script/cmake-build simulation
이제 OpenThread Daemon을 빌드합니다.
$ ./script/cmake-build posix -DOT_DAEMON=ON
4. 스레드 네트워크 시뮬레이션
이 Codelab에서 사용할 예시 애플리케이션은 기본 명령줄 인터페이스 (CLI)를 통해 OpenThread 구성 및 관리 인터페이스를 노출하는 최소한의 OpenThread 애플리케이션을 보여줍니다.
이 연습에서는 시뮬레이션된 다른 스레드 기기에서 시뮬레이션된 스레드 기기를 핑하는 데 필요한 최소한의 단계를 안내합니다.
아래 그림은 기본적인 스레드 네트워크 토폴로지를 보여줍니다. 이 연습에서는 녹색 원 안에 있는 두 노드, 즉 스레드 리더와 스레드 라우터를 각각 단일 연결이 있는 시뮬레이션해 보겠습니다.
노드 핑하기
1. 노드 1 시작
openthread
디렉터리로 이동하고 ot-cli-ftd
바이너리를 사용하여 시뮬레이션된 스레드 기기의 CLI 프로세스를 생성합니다.
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 1
참고: 이 명령어를 실행한 후에도 >
프롬프트가 표시되지 않으면 enter
를 누르세요.
이 바이너리는 POSIX를 기반으로 시뮬레이션된 OpenThread 디바이스를 구현합니다. IEEE 802.15.4 무선 드라이버는 UDP 위에 구현됩니다 (IEEE 802.15.4 프레임은 UDP 페이로드 내에서 전달됨).
1
의 인수는 '팩토리 할당'의 최하위 비트를 나타내는 파일 설명자입니다. 시뮬레이션된 기기의 경우 IEEE EUI-64 이 값은 IEEE 802.15.4 무선 에뮬레이션 (포트 = 9000 + 파일 설명자)을 위해 UDP 포트에 바인딩할 때도 사용됩니다. 이 Codelab에서 시뮬레이션된 스레드 기기의 각 인스턴스는 서로 다른 파일 설명자를 사용합니다.
참고: 시뮬레이션된 기기의 프로세스를 생성할 때는 이 Codelab에 설명된 대로 1
이상의 파일 설명자만 사용해야 합니다. 0
의 파일 설명자는 다른 용도로 예약되어 있습니다.
새 운영 데이터 세트를 만들어 활성 데이터 세트로 커밋합니다. 운영 데이터 세트는 생성 중인 스레드 네트워크의 구성입니다.
> dataset init new Done > dataset Active Timestamp: 1 Channel: 20 Channel Mask: 07fff800 Ext PAN ID: d6263b6d857647da Mesh Local Prefix: fd61:2344:9a52:ede0/64 Network Key: e4344ca17d1dca2a33f064992f31f786 Network Name: OpenThread-c169 PAN ID: 0xc169 PSKc: ebb4f2f8a68026fc55bcf3d7be3e6fe4 Security Policy: 0, onrcb Done
이 데이터 세트를 활성 데이터 세트로 커밋합니다.
> dataset commit active Done
IPv6 인터페이스를 불러옵니다.
> ifconfig up Done
스레드 프로토콜 작업을 시작합니다.
> thread start Done
몇 초 동안 기다렸다가 기기가 스레드 리더가 되었는지 확인합니다. 리더는 라우터 ID 할당을 관리하는 기기입니다.
> state leader Done
노드 1의 스레드 인터페이스에 할당된 IPv6 주소를 확인합니다 (출력은 다름).
> ipaddr fd61:2344:9a52:ede0:0:ff:fe00:fc00 fd61:2344:9a52:ede0:0:ff:fe00:5000 fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6 fe80:0:0:0:94da:92ea:1353:4f3b Done
특정 IPv6 주소 유형을 확인합니다.
fd
로 시작 = Mesh-localfe80
(으)로 시작 = link-local
메시-로컬 주소 유형은 다음과 같이 추가로 분류됩니다.
ff:fe00
포함 = 라우터 로케이터 (RLOC)ff:fe00
= 엔드포인트 식별자 (EID)를 포함하지 않음
콘솔 출력에서 EID를 식별하여 나중에 사용할 수 있도록 기록해 둡니다. 위의 샘플 출력에서 EID는 다음과 같습니다.
fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6
2. 노드 2 시작
새 터미널을 열고 openthread
디렉터리로 이동하여 CLI 프로세스를 생성합니다. 두 번째 시뮬레이션된 스레드 기기입니다.
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 2
참고: 이 명령어를 실행한 후에도 >
프롬프트가 표시되지 않으면 enter
를 누르세요.
노드 1의 운영 데이터 세트와 동일한 값을 사용하여 스레드 네트워크 키와 PAN ID를 구성합니다.
> dataset networkkey e4344ca17d1dca2a33f064992f31f786 Done > dataset panid 0xc169 Done
이 데이터 세트를 활성 데이터 세트로 커밋합니다.
> dataset commit active Done
IPv6 인터페이스를 불러옵니다.
> ifconfig up Done
스레드 프로토콜 작업을 시작합니다.
> thread start Done
기기가 자체적으로 하위 요소로 초기화됩니다. 스레드 하위 요소는 상위 기기와만 유니캐스트 트래픽을 전송하고 수신하는 스레드 기기인 최종 기기와 동일합니다.
> state child Done
2분 이내에 상태가 child
에서 router
로 전환되는 것을 확인할 수 있습니다. 스레드 라우터는 스레드 기기 간에 트래픽을 라우팅할 수 있습니다. 상위 관리자라고도 합니다.
> state router Done
네트워크 확인
메시 네트워크를 쉽게 확인할 수 있는 방법은 라우터 테이블을 확인하는 것입니다.
1. 연결 확인
Node 2에서 RLOC16을 가져옵니다. RLOC16은 기기 RLOC IPv6 주소의 마지막 16비트입니다.
> rloc16 5800 Done
노드 1에서 라우터 테이블에서 노드 2의 RLOC16을 확인합니다. 먼저 노드 2가 라우터 상태로 전환되었는지 확인합니다.
> router table | ID | RLOC16 | Next Hop | Path Cost | LQI In | LQI Out | Age | Extended MAC | +----+--------+----------+----------+-------+---------+-----+------------------+ | 20 | 0x5000 | 63 | 0 | 0 | 0 | 0 | 96da92ea13534f3b | | 22 | 0x5800 | 63 | 0 | 3 | 3 | 23 | 5a4eb647eb6bc66c |
노드 1의 RLOC 0xa800
가 테이블에 있으므로 메시에 연결되었는지 확인할 수 있습니다.
2. 노드 2에서 노드 1 핑
시뮬레이션된 두 스레드 기기 간의 연결을 확인합니다. 노드 2에서 ping
는 노드 1에 할당된 EID입니다.
> ping fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6 > 16 bytes from fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6: icmp_seq=1 hlim=64 time=12ms
enter
를 눌러 >
CLI 프롬프트로 돌아갑니다.
네트워크 테스트
이제 시뮬레이션된 두 스레드 기기 간에 핑을 성공적으로 마칠 수 있으므로 노드 하나를 오프라인으로 전환하여 메시 네트워크를 테스트합니다.
노드 1로 돌아가서 스레드를 중지합니다.
> thread stop Done
노드 2로 전환하고 상태를 확인합니다. 2분 이내에 노드 2는 리더 (노드 1)가 오프라인 상태임을 감지하고 노드 2가 네트워크의 leader
로 전환되는 것을 확인할 수 있습니다.
> state router Done ... > state leader Done
확인이 완료되면 스레드를 중지하고 Node 2를 초기화한 후 종료합니다. 이 실습에서 사용한 스레드 네트워크 사용자 인증 정보가 다음 실습으로 이전되지 않도록 초기화가 수행됩니다.
> thread stop Done > factoryreset > > exit
또한 초기화하고 Node 1을 종료합니다.
> factoryreset > > exit
사용 가능한 모든 CLI 명령어를 살펴보려면 OpenThread CLI 참조를 확인하세요.
5. 커미셔닝으로 노드 인증
이전 연습에서는 두 개의 시뮬레이션된 기기와 확인된 연결을 사용하여 스레드 네트워크를 설정했습니다. 하지만 이 경우 인증되지 않은 IPv6 링크-로컬 트래픽만 기기 간에 전달될 수 있습니다. 노드 간 전역 IPv6 트래픽 (및 스레드 보더 라우터를 통한 인터넷)을 라우팅하려면 노드를 인증해야 합니다.
인증하려면 하나의 기기가 커미셔닝 역할을 해야 합니다. 커미셔너는 현재 새로운 스레드 디바이스에 대해 선택된 인증 서버이며, 디바이스가 네트워크에 참여하는 데 필요한 네트워크 크리덴셜을 제공하는 승인자입니다.
이 연습에서는 이전과 동일한 2노드 토폴로지를 사용합니다. 인증의 경우 스레드 리더가 커미셔너 역할을 하고 스레드 라우터는 조인자 역할을 합니다.
1. 네트워크 만들기
이전 연습을 계속 진행하는 경우 이미 두 개의 터미널 창이 열려 있어야 합니다. 그렇지 않은 경우 두 기기가 열려 있고 사용할 준비가 되었는지 확인하세요. 하나는 노드 1로, 다른 하나는 노드 2가 됩니다.
노드 1에서 CLI 프로세스를 생성합니다.
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 1
참고: 이 명령어를 실행한 후에도 >
프롬프트가 표시되지 않으면 enter
를 누르세요.
새 운영 데이터 세트를 만들어 활성 데이터 세트로 커밋한 후 스레드를 시작합니다.
> dataset init new Done > dataset Active Timestamp: 1 Channel: 12 Channel Mask: 07fff800 Ext PAN ID: e68d05794bf13052 Mesh Local Prefix: fd7d:ddf7:877b:8756/64 Network Key: a77fe1d03b0e8028a4e13213de38080e Network Name: OpenThread-8f37 PAN ID: 0x8f37 PSKc: f9debbc1532487984b17f92cd55b21fc Security Policy: 0, onrcb Done
이 데이터 세트를 활성 데이터 세트로 커밋합니다.
> dataset commit active Done
IPv6 인터페이스를 불러옵니다.
> ifconfig up Done
스레드 프로토콜 작업을 시작합니다.
> thread start Done
몇 초 동안 기다렸다가 기기가 스레드 리더가 되었는지 확인합니다.
> state leader Done
2. 커미셔닝 실행자 역할 시작하기
노드 1에서 커미셔닝 역할을 시작합니다.
> commissioner start Done
J01NME
Joiner 사용자 인증 정보와 함께 모든 Joiner (*
와일드 카드 사용)가 네트워크에 커미셔닝하도록 허용합니다. Joiner는 관리자가 의뢰한 스레드 네트워크에 추가하는 기기입니다.
> commissioner joiner add * J01NME Done
3. 연결자 역할 시작
두 번째 터미널 창에서 새 CLI 프로세스를 생성합니다. Node 2입니다.
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 2
노드 2에서 J01NME
Joiner 사용자 인증 정보를 사용하여 Joiner 역할을 사용 설정합니다.
> ifconfig up Done > joiner start J01NME Done
... 확인을 위해 몇 초간 기다리세요 ...
Join success
Joiner로서 기기 (노드 2)는 커미셔닝원 (노드 1)을 통해 자체 인증을 성공적으로 수행하고 스레드 네트워크 사용자 인증 정보를 수신했습니다.
이제 노드 2가 인증되었으므로 스레드를 시작합니다.
> thread start Done
4. 네트워크 인증 확인
노드 2의 state
를 확인하여 네트워크에 연결되었는지 확인합니다. 2분 내에 노드 2가 child
에서 router
로 전환됩니다.
> state child Done ... > state router Done
5. 구성 재설정
다음 연습을 준비하려면 구성을 재설정하세요. 각 노드에서 스레드를 중지하고 초기화한 다음 시뮬레이션된 스레드 기기를 종료합니다.
> thread stop Done > factoryreset > > exit
factoryreset
명령어 다음에 >
프롬프트를 다시 표시하려면 enter
를 몇 번 눌러야 할 수 있습니다.
6. OpenThread 데몬으로 네트워크 관리
이 연습에서는 CLI 인스턴스 (단일 내장 SoC 스레드 기기) 하나와 무선 공동 프로세서 (RCP) 인스턴스 하나를 시뮬레이션해 보겠습니다.
ot-daemon
는 OpenThread 코어를 서비스로 실행할 수 있도록 UNIX 소켓을 입력 및 출력으로 사용하는 OpenThread Posix 앱의 모드입니다. 클라이언트는 OpenThread CLI를 프로토콜로 사용하여 소켓에 연결하여 이 서비스와 통신할 수 있습니다.
ot-ctl
는 RCP를 관리하고 구성하기 위해 ot-daemon
에서 제공하는 CLI입니다. 이를 사용하여 RCP를 스레드 기기에서 만든 네트워크에 연결합니다.
ot-daemon 사용
이 연습에서는 다음에 해당하는 세 개의 터미널 창을 사용합니다.
- 시뮬레이션된 스레드 기기의 CLI 인스턴스 (노드 1)
ot-daemon
프로세스- CLI 인스턴스
ot-ctl
개
이전 연습을 계속 진행하는 경우 이미 두 개의 터미널 창이 열려 있어야 합니다. 세 번째 창을 열어 이 연습에서 사용할 수 있는 터미널 창이 세 개 있는지 확인합니다.
1. 노드 1 시작
첫 번째 터미널 창에서 시뮬레이션된 스레드 기기의 CLI 프로세스를 생성합니다.
$ cd ~/src/openthread $ ./build/simulation/examples/apps/cli/ot-cli-ftd 1
참고: 이 명령어를 실행한 후에도 >
프롬프트가 표시되지 않으면 enter
를 누르세요.
새 운영 데이터 세트를 만들어 활성 데이터 세트로 커밋한 후 스레드를 시작합니다.
> dataset init new Done > dataset Active Timestamp: 1 Channel: 13 Channel Mask: 07fff800 Ext PAN ID: 97d584bcd493b824 Mesh Local Prefix: fd55:cf34:dea5:7994/64 Network Key: ba6e886c7af50598df1115fa07658a83 Network Name: OpenThread-34e4 PAN ID: 0x34e4 PSKc: 38d6fd32c866927a4dfcc06d79ae1192 Security Policy: 0, onrcb Done
이 데이터 세트를 활성 데이터 세트로 커밋합니다.
> dataset commit active Done
IPv6 인터페이스를 불러옵니다.
> ifconfig up Done
스레드 프로토콜 작업을 시작합니다.
> thread start Done
노드 1의 스레드 인터페이스에 할당된 IPv6 주소를 확인합니다.
> ipaddr fd55:cf34:dea5:7994:0:ff:fe00:fc00 fd55:cf34:dea5:7994:0:ff:fe00:d000 fd55:cf34:dea5:7994:460:872c:e807:c4ab fe80:0:0:0:9cd8:aab6:482f:4cdc Done >
스레드 네트워크 시뮬레이션 단계에서 설명한 것처럼 한 주소는 링크-로컬 (fe80
)이고 세 개는 메시 로컬 (fd
)입니다. EID는 주소에 ff:fe00
가 포함되지 않은 메시 로컬 주소입니다. 이 샘플 출력에서 EID는 fd55:cf34:dea5:7994:460:872c:e807:c4ab
입니다.
ipaddr
출력에서 노드와 통신하는 데 사용할 특정 EID를 식별합니다.
2. ot-daemon 시작
두 번째 터미널 창에서 openthread
디렉터리로 이동하여 노드 2라고 하는 RCP 노드의 ot-daemon
를 시작합니다. 로그 출력을 보고 실행 중인지 확인할 수 있도록 -v
상세 플래그를 사용합니다. sudo
를 사용해야 합니다.
$ cd ~/src/openthread $ sudo ./build/posix/src/posix/ot-daemon -v \ 'spinel+hdlc+forkpty://build/simulation/examples/apps/ncp/ot-rcp?forkpty-arg=2'
성공하면 상세 모드의 ot-daemon
가 다음과 유사한 출력을 생성합니다.
ot-daemon[12463]: Running OPENTHREAD/thread-reference-20200818-1938-g0f10480ed; POSIX; Aug 30 2022 10:55:05 ot-daemon[12463]: Thread version: 4 ot-daemon[12463]: Thread interface: wpan0 ot-daemon[12463]: RCP version: OPENTHREAD/thread-reference-20200818-1938-g0f10480ed; SIMULATION; Aug 30 2022 10:54:10
이 터미널을 열어 두고 백그라운드에서 실행되도록 둡니다. 더 이상 명령어를 입력하지 않습니다.
3. ot-ctl을 사용하여 네트워크 참여
아직 스레드 네트워크에 노드 2 (ot-daemon
RCP)를 커미셔닝하지 않았습니다. 이때 ot-ctl
가 필요합니다. ot-ctl
는 OpenThread CLI 앱과 동일한 CLI를 사용합니다. 따라서 시뮬레이션된 다른 스레드 기기와 동일한 방식으로 ot-daemon
노드를 제어할 수 있습니다.
세 번째 터미널 창에서 ot-ctl
를 시작합니다.
$ sudo ./build/posix/src/posix/ot-ctl >
참고: 이 명령어를 실행한 후에도 >
프롬프트가 표시되지 않으면 enter
를 누르세요.
이 세 번째 터미널 창에서 ot-ctl
를 사용하여 ot-daemon
로 두 번째 터미널 창에서 시작한 노드 2 (RCP 노드)를 관리합니다. 노드 2의 state
를 확인합니다.
> state disabled Done
특정 Joiner로의 조인을 제한하려면 노드 2의 eui64
를 가져옵니다.
> eui64 18b4300000000001 Done
노드 1 (첫 번째 터미널 창)에서 커미셔를 시작하고 해당 eui64로만 조인을 제한합니다.
> commissioner start Done > commissioner joiner add 18b4300000000001 J01NME Done
노드 2 (세 번째 터미널 창)에서 네트워크 인터페이스를 표시하고 네트워크에 연결합니다.
> ifconfig up Done > joiner start J01NME Done
... 확인을 위해 몇 초간 기다리세요 ...
Join success
조이너로서 RCP (노드 2)는 커미셔너 (노드 1)를 통해 자체 인증을 성공적으로 수행하고 스레드 네트워크 크리덴셜을 받았습니다.
이제 노드 2를 스레드 네트워크에 조인합니다.
> thread start Done
4. 네트워크 인증 확인
노드 2의 state
를 확인하여 네트워크에 연결되었는지 확인합니다. 2분 내에 노드 2가 child
에서 router
로 전환됩니다.
> state child Done ... > state router Done
5. 연결 확인
Ctrl+D 또는 exit
명령어를 사용하여 ot-ctl
를 종료하고, 호스트 머신의 명령줄에서 ping6
명령어와 함께 EID를 사용하여 노드 1을 핑합니다. ot-daemon
RCP 인스턴스가 스레드 네트워크에 성공적으로 연결되고 스레드 네트워크와 통신하면 핑이 성공합니다.
$ ping6 -c 4 fd55:cf34:dea5:7994:460:872c:e807:c4ab PING fd55:cf34:dea5:7994:460:872c:e807:c4ab (fd55:cf34:dea5:7994:460:872c:e807:c4ab): 56 data bytes 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=0 ttl=64 time=4.568 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=1 ttl=64 time=6.396 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=2 ttl=64 time=7.594 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=3 ttl=64 time=5.461 ms --- fd55:cf34:dea5:7994:460:872c:e807:c4ab ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max/stddev = 4.568/6.005/7.594/1.122 ms
7. 축하합니다.
OpenThread를 사용하여 첫 번째 스레드 네트워크를 시뮬레이션했습니다. 좋습니다.
이 Codelab을 통해 학습한 내용은 다음과 같습니다.
- OpenThread 빌드 도구 모음 설정
- 스레드 네트워크 시뮬레이션
- 스레드 노드 인증
- OpenThread 데몬으로 스레드 네트워크 관리
자세한 내용은 다음 자료를 참조하세요.