[사물 인터넷 네트워크와 서비스 구축 강좌] #3-5 BLE 프로토콜 소개
강좌 전체보기
.
본격적으로 BLE 에 대한 내용을 다루기 전에 BLE 프로토콜에 대해 먼저 언급을 해야겠습니다.
이미 [3-1 블루투스 소개] 파트에서 BLE 프로토콜에 대해서는 자세히 다루었습니다. 하지만 3-1 파트에서는 BLE 전반에 대한 내용을 다루다보니 짧은 시간안에 이해하기엔 내용이 많고 어렵습니다. 그래서 이 파트에서는 최대한 BLE 프로토콜을 쉽게, 필요한 부분만 다루도록 하겠습니다.
.
게시(Advertising)와 스캔(Scanning), iBeacon
유선 통신과는 달리 무선 통신은 반드시 서로의 존재를 무선으로 찾아서 인증을 거쳐야 합니다. 이건 무선 통신의 숙명입니다.
이 때, 두 개의 무선장치가 서로의 존재를 인식하기 위해 쓸 수 있는 방법은 많지 않습니다. 상식적으로 생각했을 때 떠오르는 방법, 그것이 정답니다. 한 쪽 기기는 주변에 자신의 존재를 알리는 데이터를 담아 무선 신호를 뿌리고, 다른 장치는 이 신호를 받아 상대방이 있음을 인지해야 겠지요. 이것이 게시와 스캔 동작입니다.
보통은 게시 동작을 하는 장치가(주변에 자신의 존재를 알리는 무선 신호를 뿌리는 장치) 센서장치가 되고, Slave(Peripheral) 장치가 됩니다.
반대로 주변에 있는 무선 신호를 보고 어떤 기기들이 있는지 스캔하는 장치가 핸드폰과 같은 장치이고, Master(Central) 장치가 됩니다. Master 장치는 향후 연결 및 데이터 통신을 주도할 장치이기 때문에 배터리나 컴퓨팅 성능이 높은 장치가 맡는 경우가 많습니다.
센서장치가 무선 신호를 게시할 때, 많은 데이터를 담을 수는 없습니다. 자신을 인식할 수 있는 최소한의 데이터만 담도록 표준상에 제약이 걸려 있습니다. BLE 프로토콜이 사용하는 데이터를 제외하고 사용자가 지정 가능한 데이터가 31 byte 정도입니다.
그래서 Master 장치는 일단 주변에서 수신한 신호를 처리하고, 이 정보로는 부족하니 추가 정보를 더 달라고 요청합니다. 이것이 Scan Request 입니다. 그러면 Slave 장치는 여기에 응답해서 31 byte의 추가 정보를 더 보내줍니다. 이것이 Scan Response 입니다. 보통은 Scan Response 에 BLE 센서장치의 이름이 담겨옵니다. 그래서 핸드폰 블루투스 설정 화면에서 스캔을 해보면, 처음에는 BLE 장치의 6 byte MAC address 정보만 뜨지만 시간이 지나면 이름이 함께 표시되는 겁니다.
그런데 BLE 장치중에 게시(advertising) 작업을 주 용도로 만든 장치가 있습니다. 흔히들 비컨이라고 부르는 장치들이 여기에 해당합니다. 비컨 장치는 소량의 정보를 31 byte, 사용자가 넣을 수 있는 데이터 공간에 담에 주변에 뿌리는 일을 하도록 설계된 장치입니다. 그리고 31 byte 사용자 지정 가능한 데이터 공간을 어떻게 나누어 사용할지 여러 표준이 정해졌는데, 그 중 가장 유명한 것이 iBeacon 입니다.
iBeacon 에서는 31 byte 데이터를 아래와 같이 분할해서 사용합니다.
iBeacon 을 이용한 서비스에서 중요한 데이터는 UUID, Major, Minor, TX power 입니다. iBeacon 에서는 검색된 비컨의 UUID-Major-Minor 값을 이용해서 위치 기반 서비스가 가능하다는 점을 설명하고 있습니다. 하지만 이 세 개의 값은 우리가 임의로 변경해서 사용할 수 있습니다. 마지막 TX power 값은 송출할 때의 신호 세기를 의미합니다. 이 값과 실제 수신 될 때의 신호 세기를 비교해서 신호가 얼마나 약해졌는지 확인하고, 비컨까지의 거리를 추정할 수 있습니다. 하지만 이렇게 계산한 거리는 주변 상황이나 장애물, 이동 속도에 따라 변화가 심하므로 대략적인 추정만 가능합니다.
iBeacon 형태로 사용되는 센서장치는 소량의 데이터를 주기적으로 뿌리기만 하므로 저전력으로 오래 동작할 수 있습니다. 실제 코인 배터리로 년 단위로 동작이 가능합니다. iBeacon 으로 사용되는 기기라도 BLE 연결을 맺고 데이터 통신을 할 수 있습니다.
.
BLE 연결, GAP, GATT
BLE 센서장치가 연결되는 과정은 클래식 블루투스의 그것과 별반 다르지 않습니다. BLE 장치를 스캔하고 페어링하면 PIN 코드 입력 후 연결이 완료됩니다.
이처럼 스캔부터 연결이 완료되기 까지의 과정을 다루는 스펙이 GAP 과 하위 레이어들 입니다.
그리고 GATT(Generic Attribute Profile), ATT 스펙이 담당하는 부분은 연결이 된 이후의 통신 과정입니다.
클래식 블루투스에서는 일반적인 데이터 통신을 위해 SPP(Serial Port Profile) 라는 표준을 사용합니다. 앞선 예제들에서 실습했듯이 별도의 설정 없이도 SPP 로 연결이 되고, 이후부터는 자유롭게 데이터를 주고받을 수 있습니다. 이런 방식은 동작 방식도 간단하고, 데이터 통신도 자유롭게 사용할 수 있는 이점이 있습니다.
하지만 내가 알지 못하는 장치와 페어링을 맺고 데이터 통신을 할 준비가 되었다면? 연결된 상대방이 무슨 일을 하는 센서장치인지 알기도 힘들고, 보내주는 데이터가 어떤 의미인지도 알 수가 없습니다. 반대로 내가 보낸 데이터도 상대방이 알수가 없겠죠. 센서장치가 원하는 구조대로 데이터를 보내야만 인식할 테니까요.
그래서 BLE 에서는 연결된 이후 데이터 통신을 할 때, 스펙에 정해진 구조대로 데이터를 읽고 쓰도록 만들었습니다. 이것이 GATT 입니다. GATT 표준을 따름으로써 센서장치를 누가 제조했든, GATT 표준에 정해진대로 특정 데이터를 읽고 쓸 수가 있습니다.
GATT 에서는 장치의 역할을 두 가지로 구분합니다.
- GATT client
- 일반적으로 모바일 폰, 태블릿, PC 등이 맡는 역할입니다. 반드시 그런건 아니지만 Master 장치가 이 역할을 맡는 경우가 많습니다.
- GATT client 장치는 GATT server 장치로 특정 데이터에 대한 요청(request)을 보내고 해당되는 응답(response)을 받습니다. 즉, 데이터가 무선으로 전달되기 위해서는 GATT client 가 먼저 요청을 보내야합니다.
- 이런 시나리오로 동작하기 위해서는 GATT client 장치는 사전에 GATT server 가 제공하는 service 가 무엇인지, service 는 어떤 데이터들을 보내줄 수 있는지 알고 있어야합니다. 그래서 BLE 연결이 성공적으로 이루어지는 시점에 GATT client 는 먼저 Service Discovery 라는 동작을 합니다. GATT server 에 요청해서 제공할 수 있는 service 와 데이터가 무엇인지 목록을 받는 것입니다.
- GATT server
- 일반적으로 웹 서버는 클라이언트가 보내는 request 가 있을 때, 여기에 상응하는 데이터를 response로 보내줍니다. GATT server 도 마찬가지로 GATT client 가 보내는 request 가 있으면, 해당하는 동작을 한 후 response 를 보내줍니다.
- 단, GATT server 는 일반적인 인식과는 달리 성능 좋은 PC나 모바일 폰 등이 담당하지는 않습니다. 보통은 저전력으로 동작하는 센서장치, Slave 장치가 GATT server 역할을 맡는 경우가 많습니다. BLE 데이터 요청과 컨트롤을 담당하는 GATT client 가 더 많은 에너지를 소비하기 때문입니다.
만약 핸드폰이 센서장치에 BLE 연결이 되었다면 센서장치가 GATT server 가 되고, 핸드폰이 GATT client 가 됩니다. 그리고 핸드폰은 연결이 완료되면 Service Discovery 를 실행해서 센서장치가 제공하는 서비스와 데이터가 무엇인지를 모두 가져옵니다.
.
GATT 구조
GATT 에서는 GATT client (센서장치)가 다음과 같은 구조로 데이터를 가지도록 정의하고 있습니다.
Profile 은 센서장치 자신이라고 생각해도 됩니다. BLE 표준 스펙에서는 자주 사용되는 장치들을 Profile로 정의해 두었기 때문에 표준에 맞는 장치를 만들때는 해당 Profile 을 참고해서 하위 구조를 만들면 됩니다. 그리고 내가 원하는대로 custom profile 을 만든다면 굳이 Profile 을 위해 특별히 정의하거나 조치해야 할 건 없습니다.
Service 와 Characteristic 은 매우 중요한 개념입니다.
Service 는 특정한 기능과 관련이 있는 데이터들의 집합입니다. 예를들어 심박 측정 기능과 체온 측정 기능이 함께 들어있는 센서장치를 만든다면, 이 장치는 2개의 service 를 갖게 될겁니다. Service 는 서로를 구분하기 위해 고유한 UUID 값을 가지는데, 블루투스 표준에 정의된 Service 인 경우 이미 정의된 16 bit UUID 값을 가집니다. 직접 만든 사용자 정의(user-defined) Service 는 128 bit UUID 를 사용합니다.
- Heart Rate Service UUID 예 : 180D
- user-defined Service 예 : 195AE58A-437A-489B-B0CD-B7C9C394BAE4
Characteristic 은 service 에 포함되는 필드로서 실제 센서장치가 제공하는 데이터를 담고 있습니다. 그래서 센서장치가 동작하면 Characteristic 의 값이 계속 변경이 됩니다. 이걸 GATT client 에서 요청해서 읽어가거나, 값을 여기에 기록하기도 하죠. 이런식으로 Characteristic 을 통해 양방향 통신이 되는겁니다.
Profile – Service – Characteristic 구조는 센서장치의 공유폴더에 담긴 파일이라고 보면 쉽습니다. BLE 센서장치 – 폴더 – 파일 구조에 맵핑된다고 볼 수 있습니다. 센서장치에 연결되면, 폴더의 이름을 보고(Service) 어떤 데이터가 담겨있는지 파악하고, 폴더에 담긴 파일을 열어서(Characteristic) 데이터를 읽거나 쓰는거죠.
PC에 저장된 파일들은 읽기/쓰기 권한이 부여되어 있죠? 마찬가지로 Characteristic 에도 read/write 권한을 부여해서 외부에서 어떤 동작만 가능한지 설정할 수 있습니다.
기억해야 할 중요한 개념이 하나 더 있습니다.
Service – Characteristic 구조는 폴더에 담긴 파일과 같다고 했습니다. 그리고 GATT 스펙에서는 항상 GATT client 가 요청하면 센서장치에 해당하는 GATT server 가 응답한다고 했습니다. 데이터는 항상 GATT client 의 요청에 의해서만 read/write 된다는 의미입니다.
그럼 센서장치인 GATT server 가 뭔가를 알려주고 싶을 때는 어떻게하죠? 예를들어, BLE 를 이용해서 채팅을 하도록 만들고 싶다면 GATT clent 든 GATT server 든, 서로 전달해 줄 메시지가 있을때마다 상대방에게 전달해줘야 합니다.
이런 경우를 위해 Characteristic 에는 read/write 에 추가로 notify/indicate을 설정할 수 있습니다. Characteristic 에 변화가 있다면 이걸 알려주는 기능입니다. notify는 단순히 변화가 있음을 알려주고, indicate 는 메시지를 받았는지 확인을 받는 과정이 추가됩니다. 단, 이 기능은 GATT client 에서 사용하겠다고 명시적으로 GATT server 에게 알려줘야만 동작합니다.
- 실제 Notify/indicate 기능을 on 시키는 작업은 Characteristic 의 설정 값을 가지고 있는 Descriptor 를 바꿈으로서 이루어집니다. Descriptor는 여러 종류가 있는데, CCCD (Client Characteristic Configuration Descriptor) 를 On 시키면 Notify/Indicate 기능이 활성화 됩니다.
.
BLE 동작 순서
정리를 하면, PC-휴대폰과 같은 장치는 아래 순서로 BLE 센서장치에 연결되어 동작합니다.
- Scanning : 주변 장치를 탐색합니다.
- 장치가 발견되면 Scan Request 를 보내 Scan Response를 받습니다.
- 특정 BLE 장치를 선택해서 연결합니다.
- Pairing 과정, PIN 입력 과정을 거쳐 연결이 성립됩니다.
- Service Discovery 작업을 수행합니다.
- BLE 센서장치가 가진 service/characteristic 구조를 모두 가져옵니다.
- Service 에 담긴 characteristic 을 확인하고, 어떤 characteristic 을 read/write 할 것인지 확인합니다.
- 필요하다면 notify/indicate 기능이 설정된 characteristic 의 CCCD 를 on 하도록 신호를 보냅니다.
- 이제 필요할 때 특정 characteristic 값을 읽거나 쓸 수 있습니다. Notify/Indicate 를 on 했다면 값이 바뀔 때 신호를 보내줄겁니다.
이 정도 내용을 알아두면 이후부터 해 볼 BLE 실습의 기술적인 부분들은 쉽게 이해가 되실겁니다.
.
참고
.
주의!!! [사물 인터넷 네트워크와 서비스 구축 강좌] 시리즈 관련 문서들은 무단으로 내용의 일부 또는 전체를 게시하여서는 안됩니다. 계속 내용이 업데이트 되는 문서이며, 문서에 인용된 자료의 경우 원작자의 라이센스 문제가 있을 수 있습니다.
.
강좌 전체보기
.