11.2. BLE 스택

네트워킹과 마찬가지로, Bluetooth Low Energy는 계층의 스택으로 구축되며, 각 계층은 하나의 문제를 해결하고 그 위의 계층에 깔끔한 추상화를 노출합니다. 아래의 이름들은 Bluetooth Core 사양에서 그대로 가져온 것이며 aioblebluetooth API에 나타납니다.

다섯 개의 레이블이 붙은 상자가 세로로 쌓인 스택. 아래에서 위로: Physical(무선 송수신기), Link Layer, GAP, GATT, Application. 오른쪽 화살표가 스택 위쪽을 가리키며 "우리가 구축하는 것"이라고 표시되어 있습니다. 왼쪽 화살표가 스택 아래쪽을 가리키며 "제공되는 것"이라고 표시되어 있습니다.

Bluetooth Low Energy 스택. 각 계층은 더 깔끔한 추상화를 다음 계층으로 넘겨주며, 이는 네트워킹 스택이 사용하는 것과 동일한 패턴입니다.

물리 계층. 2.4 GHz 무선 송수신기를 통해 두 장치 사이에서 비트 를 이동시킵니다. 채널 선택, 변조, 송신 전력을 담당합니다. 카메라의 역할은 전원을 켜는 것이고, 나머지는 실리콘이 처리합니다.

링크 계층. 서로 통신하기로 합의한 두 장치 사이에서 패킷 을 이동시킵니다. 각 패킷이 하나의 이웃을 향할 수 있도록 장치 주소를 추가하고, 연결을 구성하는 주기적 무선 이벤트를 스케줄링하며, 수신자가 확인 응답하지 않은 패킷의 재전송을 처리합니다.

Generic Access Profile (GAP). 검색 및 연결 계층입니다. 네 가지 역할 – broadcaster, observer, peripheral, central – 과, 두 장치가 애초에 서로를 찾을 수 있게 해주는 광고 / 스캐닝 프로토콜, 그리고 둘 사이의 연결을 열고 닫는 절차를 정의합니다. 주소, 광고 페이로드, 연결 매개변수, 페어링이 여기에 속합니다.

Generic Attribute Profile (GATT). 데이터 계층입니다. 열린 GAP 연결 위에 위치하며 작은 키/값 데이터베이스를 노출합니다. 한쪽은 characteristics 라는 이름이 붙은 값들의 트리를 호스팅하고, 다른 쪽은 이를 읽거나 쓰거나 구독합니다. 실제 애플리케이션 바이트가 흐르는 곳이 바로 여기입니다.

Application. 카메라와 피어가 바이트의 의미에 대해 합의한 그 무엇이든 됩니다. Bluetooth SIG는 표준 프로파일 – 심박수, 배터리 레벨, 환경 센싱 – 을 게시하여 자주 사용되는 특성을 정의함으로써 서로 무관한 장치들이 상호 운용될 수 있게 합니다. 하지만 모든 애플리케이션은 자유롭게 자신만의 것을 정의할 수 있습니다.

11.2.1. 런타임에 계층이 쌓이는 방식

이 패턴은 네트워킹 스택과 일치합니다:

  • 애플리케이션의 바이트는 characteristic 값 으로 들어갑니다.

  • GATT는 그 바이트가 어떤 characteristic에 속하는지 식별하는 헤더로 이를 감쌉니다.

  • GAP는 GATT가 보낼 곳을 갖도록 열린 연결을 계속 유지합니다.

  • 링크 계층은 그 전부를 피어의 장치 주소로 지정된 패킷으로 감싸고, 이를 전송할 무선 이벤트를 스케줄링합니다.

  • 물리 계층은 패킷을 짧은 2.4 GHz 무선 버스트로 변환합니다.

물리 계층과 링크 계층은 Python에서 거의 보이지 않습니다 – 실리콘과 무선 펌웨어가 이를 처리합니다. GAP 이상부터는 카메라의 Python 코드가 더 많은 발언권을 갖습니다.

11.2.2. 사용자 대상 API가 조용히 건너뛰는 두 계층

Bluetooth 사양은 링크 계층과 GAP/GATT 사이에 위치하는 두 계층을 더 명명합니다: Host Controller Interface (HCI) – 호스트 CPU가 별도의 무선 칩을 구동하는 데 사용하는 프로토콜 – 와 L2CAP – 하나의 링크 계층 연결을 여러 논리 채널로 분할하는 멀티플렉서입니다.

둘 다 aioble API에서는 보이지 않지만, 둘 다 사라지는 것은 아닙니다. HCI는 BLE 포트 내부에 위치하며 MicroPython의 커스텀 빌드가 사용되지 않는 한 보이지 않고, L2CAP은 GATT가 그 위에서 실행되는 운반체입니다. 원시 바이트 스트림을 원하는 애플리케이션은 자체 L2CAP 채널을 요청할 수 있습니다(L2CAP 채널).