연결: 약속된 시각의 짧은 만남
스마트워치는 하루 종일 휴대폰과 “연결되어” 있다. 그런데 정말 하루 종일 전파를 주고받는 것일까? 아니다. 둘은 예를 들어 50 ms마다 1 ms도 안 되는 순간만 깨어나 몇 바이트를 주고받고, 나머지 98% 넘는 시간은 무선부를 끈 채 잔다. LE의 “연결”이란 끊기지 않는 선이 아니라 정확한 시간 약속이다. 이 장에서는 그 약속의 내용(연결 간격, 지연, 타임아웃), 약속 시각에 오가는 패킷의 비트 하나하나, 잃어버린 패킷을 되찾는 방법, 그리고 이 구조에서 나오는 처리량의 한계를 계산한다.
- 연결 이벤트·앵커 포인트·연결 간격의 관계와, 6.2에서 넓어진 연결 간격 범위(375 µs ~ 4 s)를 안다.
- 페리페럴 지연, 연결 서브레이팅, 감독 타임아웃 사이의 사양 규칙을 계산해 유효한 연결 파라미터를 고른다.
- 데이터 PDU 헤더(LLID, NESN, SN, MD, CP, Length)와 24비트 CRC, 화이트닝을 비트 단위로 만들고 사양 샘플 데이터와 맞춰 본다.
- 1비트 SN/NESN만으로 확인 응답과 재전송이 이루어지는 원리를 따라간다.
- PHY, 데이터 길이 확장(DLE), ATT_MTU, 연결 간격으로 실제 처리량을 계산한다.
연결 이벤트: 정해진 시각에 깨어나기
5장의 CONNECT_IND로 연결이 맺어지면 두 기기는 광고 채널을 떠난다. 이제부터 시간은 연결 간격(connInterval)으로 잘린다. 간격마다 한 번 연결 이벤트(connection event)가 열리고, 그 시작점을 앵커 포인트(anchor point)라 한다. 앵커 포인트에서 센트럴이 먼저 패킷을 보내고, 페리페럴은 받은 패킷 끝에서 정확히 T_IFS(기본 150 µs) 뒤에 답한다. 둘 중 하나라도 더 보낼 것이 있으면(헤더의 MD 비트) 같은 채널에서 핑퐁을 이어 가고, 둘 다 없으면 이벤트를 닫고 다음 앵커 포인트까지 잔다. 다음 이벤트는 4장의 채널 선택 알고리즘이 고른 새 채널에서 열린다.
6.2부터 연결 간격은 125 µs 단위로 375 µs ~ 4 s다. 다만 모든 컨트롤러가 이 전체를 지원하는 것은 아니다. 사양은 세 집합을 구분한다.
- BCV(baseline): 1.25 ms의 배수이면서 7.5 ms 이상인 값. 6.1까지의 연결 간격과 같고, 모든 컨트롤러가 지원해야 한다. 연결을 처음 맺을 때도 이 값을 쓴다.
- RCV(rounded): 1.25 ms의 배수인 모든 값(1.25 ms, 2.5 ms, 3.75 ms, 5 ms 포함).
- ECV(extended): 375 µs부터 125 µs 단위의 모든 값.
6.2의 새 기능 짧은 연결 간격(Shorter Connection Intervals, SCI)을 지원하는 컨트롤러는 RCV 전체를 지원해야 하고 ECV의 다른 값도 지원할 수 있다. 연결된 뒤 새로 생긴 Connection Rate Update/Request 절차로 짧은 간격으로 옮겨 간다. 고성능 게임 입력 장치나 실시간 제어처럼 수 ms의 지연도 아까운 곳을 겨냥한 기능이다.
connInterval 125 µs 단위 375 µs ~ 4 s, ECV·RCV·BCV, 연결 생성 시 BCV: [Vol 6] Part B §4.5.1 · T_IFS_ACL_CP/PC 기본 150 µs, Frame Space Update로 변경 가능: §4.1.1 · 6.2 새 기능: [Vol 1] Part C §16.1
쉬어도 되는 횟수와 포기하는 시간
연결 간격이 짧으면 반응이 빠르지만, 페리페럴이 매번 깨어나야 해서 배터리가 빨리 닳는다. 길면 배터리는 좋지만 버튼을 눌렀을 때 늦게 반응한다. 이 딜레마를 푸는 손잡이가 둘 있다.
- 페리페럴 지연(connPeripheralLatency): 보낼 것이 없을 때 페리페럴이 연속으로 건너뛰어도 되는 이벤트 수. 지연 4이면 다섯 번에 한 번만 깨어나도 된다. 하지만 보낼 것이 생기면 바로 다음 이벤트에서 말할 수 있다. 센트럴은 매 이벤트 앵커에서 기다리므로, 페리페럴 쪽 반응은 빠르고 배터리는 아낀다. 반대 방향(센트럴 → 페리페럴)은 페리페럴이 깨어날 때까지 기다려야 한다.
- 연결 서브레이팅(connection subrating): 5.3에서 추가. 두 기기가 합의해 평소에는 N번째 이벤트만 쓰다가(subrate factor), 데이터가 오가면 그 뒤 몇 이벤트(continuation number)를 연달아 쓴다. 연결 간격 자체를 바꾸는 협상 없이 빠른 모드와 느린 모드를 오간다.
그리고 안전장치가 하나 있다. 감독 타임아웃(connSupervisionTimeout)은 유효한 패킷을 하나도 받지 못한 채 이 시간이 지나면 연결이 끊어졌다고 판단하는 시간이다. 사양은 이 값들 사이에 규칙을 둔다.
페리페럴 지연·서브레이팅 규칙(subrate × (latency + 1) ≤ 500, 그 시간 × 2 < 타임아웃): [Vol 6] Part B §4.5.1 · 감독 타임아웃 100 ms ~ 32 s와 6 이벤트 규칙: §4.5.2
카페에서 두 사람이 “매 30분 정각에 잠깐 이야기하자”고 약속한다. 할 말이 없으면 몇 번은 빠져도 되고(페리페럴 지연), 너무 오래 안 나타나면 헤어진 것으로 친다(감독 타임아웃). 약속 간격이 짧으면 대답이 빠르지만 자주 일어나야 하니 피곤하다. 연결 파라미터가 이 약속이다.
연결 파라미터 설계기: 반응 속도, 배터리, 규칙 검사
데이터 패킷 해부: 헤더 16비트와 CRC 24비트
연결 중에 오가는 패킷은 5장의 광고 패킷과 겉모양이 같다. 프리앰블, 이 연결만의 접근 주소(CONNECT_IND에서 정한 무작위 32비트), PDU, CRC. 다른 것은 PDU 안이다. 데이터 PDU의 헤더 16비트에는 다음이 들어 있다.
| 필드 | 비트 | 뜻 |
|---|---|---|
| LLID | 2 | 01 = 이어지는 조각 또는 빈 PDU, 10 = L2CAP 메시지의 시작(또는 전체), 11 = 링크 계층 제어 PDU |
| NESN | 1 | 다음에 받기를 기대하는 일련번호 (= 확인 응답) |
| SN | 1 | 이 패킷의 일련번호 |
| MD | 1 | More Data: 보낼 것이 더 있다 |
| CP | 1 | CTEInfo가 있음(방향 찾기용 일정 톤, 11장) |
| (RFU) | 2 | 예약 |
| Length | 8 | 페이로드(+ MIC) 길이. 페이로드는 최대 251바이트, 암호화하면 MIC 4바이트가 붙는다 |
PDU 뒤에는 오류를 찾는 CRC(Cyclic Redundancy Check) 24비트가 붙는다. 다항식은 x24 + x10 + x9 + x6 + x4 + x3 + x + 1이고, 시프트 레지스터의 초깃값은 광고 채널이면 0x555555, 연결이면 CONNECT_IND에서 정한 CRCInit이다. 마지막으로 PDU와 CRC에 화이트닝(data whitening)을 한다. 채널 번호로 초기화한 7비트 LFSR(x7 + x4 + 1)의 출력과 XOR해서, 0이나 1이 길게 이어지지 않게 섞는 것이다. 3장의 수신기는 주파수 중심과 비트 타이밍을 비트 변화에서 계속 맞추는데, 같은 비트가 오래 이어지면 기준을 잃기 쉽다.
데이터 PDU 헤더(Table 2.21), 페이로드 ≤ 251바이트, MIC 4바이트: [Vol 6] Part B §2.4 · CRC: §3.1.1 · 화이트닝: §3.2 · 샘플 패킷: [Vol 6] Part C §4
패킷 만들기: 헤더 → CRC → 화이트닝 (사양 샘플로 검증)
1비트로 하는 확인 응답: SN과 NESN
무선은 패킷을 잃는다. 4장의 간섭, 2장의 페이딩 때문이다. LE는 따로 ACK 패킷을 보내지 않고, 다음에 보내는 패킷 헤더의 1비트 두 개로 확인 응답을 한다.
- 각자 보낼 패킷에 SN(0 또는 1)을 붙인다. 새 패킷을 보낼 때마다 SN을 뒤집는다.
- 받는 쪽은 받은 패킷의 SN이 기대하던 값이면 새 패킷으로 받아들이고, 기대값(NESN)을 뒤집어 다음 답장 헤더에 실어 보낸다.
- 보낸 쪽은 상대의 NESN이 뒤집혀 왔으면 “잘 받았구나” 하고 다음 패킷으로 넘어가고, 그대로면 “못 받았구나” 하고 같은 패킷을 다시 보낸다.
- CRC가 틀린 패킷은 받지 않은 것으로 친다. 같은 SN이 다시 오면 중복이므로 버리되 확인 응답은 해 준다.
이 방식은 “한 번에 하나씩 보내고, 확인되면 다음”(stop-and-wait)이다. 연결 이벤트 안에서 핑퐁이 150 µs 간격으로 빠르게 오가므로 손해가 작다. 패킷이 깨지면 이벤트가 닫힐 수 있고, 그러면 다음 이벤트(다른 채널!)에서 재전송한다. 감독 타임아웃까지 아무것도 받지 못하면 연결을 끊는다.
확인 응답과 흐름 제어(transmitSeqNum, nextExpectedSeqNum): [Vol 6] Part B §4.5.9 · 이벤트 닫기·MD: §4.5.6
SN/NESN 따라가기: 잃어버린 패킷은 어떻게 돌아오나
처리량: 2 Mb/s PHY에서 몇 Mb/s가 나올까
LE 2M의 공중 속도는 2 Mb/s다. 하지만 앱이 실제로 옮기는 데이터는 그보다 훨씬 적다. 이유를 하나씩 쌓아 보자.
- 패킷 머리와 꼬리: 데이터 패킷마다 프리앰블·접근 주소·헤더·CRC로 10~11바이트가 붙는다.
- 반이중과 응답: 데이터 패킷 하나마다 상대가 빈 PDU라도 답해야 하고, 사이사이 150 µs씩 쉰다.
- 상위 계층 헤더: L2CAP 헤더 4바이트, ATT 알림 헤더 3바이트(7장).
- 데이터 길이: 4.2 이전에는 페이로드가 27바이트였다. 4.2의 데이터 길이 확장(DLE, Data Length Extension)으로 251바이트까지 늘었다. 27바이트면 L2CAP·ATT 헤더를 빼고 20바이트만 남는다.
- 이벤트 길이: 한 이벤트에 몇 번 주고받을지는 센트럴(휴대폰 운영체제)이 정한다. 많은 휴대폰이 이벤트당 패킷 수에 상한을 둔다.
LE 처리량 계산기: 공중 2 Mb/s에서 앱까지
펌웨어 업데이트 파일(200 KB)을 LE로 보낸다. 연결 간격을 7.5 ms에서 30 ms로 늘리면(이벤트당 패킷 수 제한 없음) 전송 시간은?
처리량 계산기에서 간격만 바꿔 보자. 이벤트 사이의 빈틈이 얼마나 되는지 생각해 보자.
이 계산에서 보듯 LE 2M의 앱 처리량은 약 1.4 Mb/s가 천장이다. 이 천장을 올리려는 것이 다음 Core 사양에 들어갈 예정인 HDT(공개 초안, Core 6.3에도 없음)다. 공중 속도를 최대 7.5 Mb/s로 올리고 한 패킷에 약 8,000바이트까지 실어, 위 손실 폭포에서 “응답 + 150 µs 틈” 몫을 줄이려 한다(3장).
약속 바꾸기와 끝내기
연결 파라미터는 연결 중에 얼마든지 바꿀 수 있다. 바꾸는 절차는 모두 LL 제어 PDU(LLID 11)로 이루어지고, 대부분 “몇 번째 이벤트(instant)부터 새 값으로” 하는 식이다. 두 기기의 이벤트 카운터가 같으므로 정확히 같은 순간에 갈아탄다.
| 절차 | 바꾸는 것 | 쓰임 |
|---|---|---|
| Connection Update / Parameters Request | 간격, 지연, 타임아웃 | 연결 직후 빠르게 → 평소 느리게 |
| Channel Map Update | 채널 맵 | Wi-Fi 피하기 (4장) |
| PHY Update | 1M ↔ 2M ↔ Coded | 거리·속도 조절 (3장) |
| Data Length Update | 최대 페이로드 27 ~ 251바이트 | 처리량 (이 장) |
| Connection Subrate Update (5.3) | subrate factor, continuation number | 빠른 모드·느린 모드 전환 |
| Frame Space Update (6.0) | T_IFS, T_MCES 등 프레임 간격 | 빠른 칩끼리 150 µs보다 짧게 |
| Connection Rate Update / Request (6.2) | 짧은 연결 간격을 포함한 간격·서브레이팅 | SCI |
| Encryption Start | AES-CCM 암호화 시작 | 페어링 뒤 (8장) |
| Terminate | 연결 끝내기 (이유 코드 포함) | 사용자가 연결 해제 |
링크 계층 제어 절차: [Vol 6] Part B §5.1 (5.1.1 Connection Update, 5.1.2 Channel Map Update, 5.1.10 PHY Update, 5.1.19 Connection Subrate Update, 5.1.30 Frame Space Update, 5.1.32·5.1.33 Connection Rate Update/Request) · 오류 코드: [Vol 1] Part F
감독 타임아웃이 너무 짧으면 잠깐의 간섭(전자레인지 몇 초, 몸이 가린 순간)에도 끊긴다. 너무 길면 기기가 꺼졌는데도 오랫동안 연결된 것처럼 보인다. 흔한 선택은 수 초다. 연결이 끊긴 이유는 HCI의 Disconnection Complete 이벤트에 오류 코드로 남는다. 0x08은 “Connection Timeout”(감독 타임아웃), 0x13은 상대가 끊음, 0x3E는 연결 수립 실패다.
핵심 정리
- LE 연결은 연결 간격마다 열리는 짧은 연결 이벤트다. 앵커 포인트에서 센트럴이 먼저 말하고 페리페럴이 T_IFS(기본 150 µs) 뒤 답하며, MD 비트로 이벤트를 이어 가거나 닫는다.
- 6.2의 연결 간격은 125 µs 단위 375 µs ~ 4 s. 모든 컨트롤러는 7.5 ms 이상·1.25 ms 단위(BCV)를 지원하고, SCI를 지원하면 더 짧은 값을 쓸 수 있다.
- 페리페럴 지연은 건너뛸 수 있는 이벤트 수, 서브레이팅(5.3)은 평소 N번째 이벤트만 쓰기. 감독 타임아웃(100 ms ~ 32 s)은 (1 + 지연) × subrate × 간격 × 2보다 커야 한다.
- 데이터 PDU 헤더 = LLID·NESN·SN·MD·CP·Length. 페이로드 ≤ 251바이트(+MIC 4). CRC-24(x²⁴+x¹⁰+x⁹+x⁶+x⁴+x³+x+1)와 채널별 화이트닝(x⁷+x⁴+1)을 거쳐 전송한다.
- SN/NESN 1비트씩으로 확인 응답·재전송·중복 제거를 한다. 잃은 패킷은 다음 핑퐁이나 다음 이벤트(다른 채널)에서 다시 보낸다.
- 앱 처리량은 패킷 머리, 응답과 150 µs 틈, L2CAP·ATT 헤더, DLE, 이벤트당 패킷 상한에 깎인다. 2M·DLE 251·MTU 247이면 약 1.4 Mb/s가 상한이다.
확인 퀴즈
Core 6.3에서 SCI(6.2에 추가된 짧은 연결 간격)를 지원하지 않는 컨트롤러가 쓸 수 있는 가장 짧은 연결 간격은?
연결 간격 50 ms, 페리페럴 지연 9, 서브레이팅 없음. 감독 타임아웃으로 허용되는 것은?
페리페럴 지연을 크게 하면 어떤 방향의 반응이 느려지나?
센트럴이 SN=1인 패킷을 보냈는데, 페리페럴의 답장 헤더 NESN이 1이었다. 센트럴이 할 일은?
4.2의 데이터 길이 확장(DLE) 이전에 ATT 알림 하나로 보낼 수 있던 앱 데이터는 최대 몇 바이트였을까? (링크 페이로드 27바이트, L2CAP 헤더 4, ATT 알림 헤더 3)
같은 데이터를 다른 채널로 보내면 공중의 비트열이 달라지는 이유는?