링크 계층 제어 절차: instant와 충돌 규칙
연결 간격을 바꾸고, 채널 맵을 바꾸고, PHY를 바꾸는 일은 두 기기가 같은 이벤트에서 동시에 바꿔야 한다. 한쪽만 먼저 바꾸면 서로 다른 시각, 다른 채널에서 기다리다 연결이 끊긴다. 링크 계층은 이것을 “instant”라는 미래의 이벤트 번호로 약속한다. 이 장은 그 약속의 규칙과, 두 기기가 동시에 절차를 시작했을 때 누가 양보하는지를 따라가고, 제어 PDU 하나를 공중 비트까지 직접 만들어 본다.
- LL 제어 PDU의 형식(헤더·opcode·CtrData)과 “한 번에 하나”, 40초 응답 타임아웃 규칙을 안다.
- instant를 고르는 규칙(6번의 기회, mod 65536 비교)과 Instant Passed(0x28)가 언제 나는지 설명할 수 있다.
- 연결 갱신에서 전송 창(WinOffset·WinSize)과 새 앵커 포인트가 정해지는 방식을 안다.
- 두 절차가 충돌할 때 센트럴과 페리페럴이 각각 무엇을 하는지, 오류 코드 0x23과 0x2A를 구별할 수 있다.
제어 PDU와 “한 번에 하나”
데이터 PDU 헤더의 LLID가 0b11이면 그 페이로드는 LL 제어 PDU다. 첫 바이트가 opcode이고 나머지가 CtrData다. 예: 0x00 LL_CONNECTION_UPDATE_IND, 0x01 LL_CHANNEL_MAP_IND, 0x02 LL_TERMINATE_IND, 0x03/0x04 LL_ENC_REQ/RSP(6장), 0x07 LL_UNKNOWN_RSP, 0x0F LL_CONNECTION_PARAM_REQ, 0x11 LL_REJECT_EXT_IND, 0x14/0x15 LL_LENGTH_REQ/RSP, 0x16~0x18 LL_PHY_REQ/RSP/UPDATE_IND. 모르는 opcode를 받으면 LL_UNKNOWN_RSP로 답하고, 이 답을 받은 쪽은 그 연결에서 같은 절차를 다시 시작하지 않는다.
규칙 둘. 종료 절차를 빼면 한 기기는 한 연결에서 한 번에 한 절차만 시작한다. 그리고 연결 갱신·채널 맵 갱신을 뺀 모든 절차에는 40초 응답 타임아웃(T_PRT)이 있다. 제어 PDU를 큐에 넣을 때마다 타이머를 다시 시작하고, 40초 안에 끝나지 않으면 연결을 잃은 것으로 본다(0x22 LL Response Timeout).
무대 조명과 음향을 동시에 바꾸려면 “지금!”이라고 외치면 늦는다. 소리가 닿는 사이에 이미 박자가 지나 있다. 그래서 감독은 “다음 소절의 셋째 박에 전환”이라고 미리 알려 둔다. 두 기사는 같은 악보를 보고 박자를 세니까 같은 순간에 바꾼다. instant가 그 “셋째 박”이고, 악보의 박자 번호가 connEventCounter다(3장).
LL 제어 PDU 형식과 opcode(Table 2.22), LL_UNKNOWN_RSP: [Vol 6] Part B §2.4.2 · 한 번에 하나의 절차: §5.1 · 응답 타임아웃 40초: §5.2 · 오류 코드: [Vol 1] Part F §2
instant: 미래의 이벤트 번호로 약속하기
instant가 있는 PDU(연결 갱신, 채널 맵, PHY 갱신, 연결 속도 갱신 등)는 “connEventCount가 이 값이 되는 이벤트부터 새 값을 쓴다”를 뜻한다. 규칙은 이렇다.
- instant는 거의 언제나 센트럴이 고른다(채널 사운딩 채널 맵만 예외).
- 센트럴은 instant 전에 페리페럴이 듣는 이벤트가 적어도 6번 있도록 고르는 것이 좋다. 페리페럴은 factor × (latency + 1) 이벤트마다 한 번 들을 수 있으므로 그만큼 곱해서 멀리 잡는다.
- 비교는 mod 65536이다. (Instant − connEventCount) mod 65536이 32767보다 작고 0이 아니면 미래, 32767 이상이면 과거다.
- 미래의 instant를 받은 페리페럴은 센트럴이 자기 확인 응답을 받았다고 알 때까지(또는 instant까지) 모든 이벤트를 듣는다.
- 이미 지난 instant의 연결 갱신을 받으면 페리페럴은 연결을 잃은 것으로 처리한다(0x28 Instant Passed). 다른 PDU는 그렇게 해도 된다.
페리페럴 지연이 4(서브레이팅 없음)인 연결에서, 센트럴이 연결 갱신의 instant를 지금부터 3 이벤트 뒤로 잡았다. 무엇이 일어나기 쉬울까?
페리페럴은 몇 이벤트마다 한 번 듣나? instant 전에 PDU를 받을 기회는?
instant를 얼마나 멀리 잡을까
instant 규칙(6번, mod 65536, 과거 instant와 0x28): [Vol 6] Part B §5.5·§5.5.1 · instant를 지나면 BIG도 동기를 멈출 수 있음: §5.5.2
연결 갱신: 전송 창과 새 앵커 포인트
LL_CONNECTION_UPDATE_IND(opcode 0x00)의 CtrData는 WinSize(1바이트, × 1.25 ms), WinOffset(2바이트, × 1.25 ms), Interval(× 1.25 ms), Latency, Timeout(× 10 ms), Instant다. instant 이벤트의 앵커 포인트에서 바로 새 간격을 쓰는 것이 아니라, instant 직전 이벤트의 앵커 포인트 + 옛 간격 + WinOffset에서 시작하는 전송 창 안에서 센트럴이 처음 보낸 패킷이 새 앵커 포인트가 된다. 그래서 센트럴은 갱신을 기회로 앵커 포인트를 옮겨 다른 연결과의 충돌을 피할 수 있다(호스트에 알리지 않는 “앵커 포인트 이동”).
그 밖의 규칙: WinOffset은 0 ~ 새 간격, WinSize는 1.25 ms ~ min(10 ms, 새 간격 − 1.25 ms). instant에 감독 타이머를 다시 시작한다. 간격이 바뀌면 서브레이트 factor는 1, continuation은 0으로 돌아간다. 센트럴은 instant와 그 직전 이벤트에서 보내고, 페리페럴은 서브레이팅이나 지연과 상관없이 그 두 이벤트를 듣는다. 두 기기 모두 연결 파라미터 요청 절차(0x0F)를 지원하면 그것을 먼저 쓴다.
LL_CONNECTION_UPDATE_IND 형식: [Vol 6] Part B §2.4.2.1 · 연결 갱신 절차(전송 창, instant 전후 이벤트, 서브레이트 초기화, 앵커 포인트 이동): §5.1.1 · 연결 파라미터 요청: §5.1.7
둘이 동시에 시작했을 때
제어 PDU는 실시간으로 처리되지 않는다. 센트럴이 PHY 갱신을 보내는 사이 페리페럴도 연결 파라미터 요청을 보낼 수 있다. 둘 다 instant가 있는 절차면 서로 다른 instant로 다른 것을 바꾸려는 셈이라 함께 진행할 수 없다. 사양은 양립할 수 없는 쌍을 정해 둔다. 둘 다 instant가 있는 절차, 프레임 간격 갱신끼리 또는 프레임 간격 갱신과 CIS 생성, 서브레이트 갱신·요청과 연결 속도 갱신·요청, 그리고 몇몇 채널 사운딩 절차 쌍이다.
절차 A를 시작해 아직 끝나지 않았는데 상대가 양립할 수 없는 절차 B를 시작하면:
- 상대가 이미 A에 응답 PDU를 하나라도 보냈다면 → 연결 상태를 떠나는 것이 좋다(끊는다).
- 아니면 센트럴은 B를 LL_REJECT_EXT_IND(둘 다 지원하면, 아니면 LL_REJECT_IND)로 거절하고 A를 계속한다.
- 페리페럴은 센트럴의 B를 처리하고, 자기 A는 센트럴의 거절을 받는 것 말고는 손을 뗀다.
오류 코드는 같은 절차끼리 부딪혔거나 A가 연결 갱신이고 B가 연결 파라미터 요청이면 0x23(LL Procedure Collision), 그 밖에는 0x2A(Different Transaction Collision)다. 한 번 상대 절차에 응답했다면, 그 절차가 끝날 때까지 양립할 수 없는 새 절차를 시작하지 않는다.
절차 충돌 판정기
충돌하는 쌍과 처리 순서, 0x23·0x2A: [Vol 6] Part B §5.3 · 절차별 시작 역할: §5.1.1·§5.1.2·§5.1.19·§5.1.20·§5.1.32·§5.1.33
제어 PDU 하나를 공중 비트까지
사양 [Vol 6] Part C §4.3.2에는 LL_CHANNEL_MAP_IND 하나가 공중에 나가는 비트 그대로 실려 있다. 채널 2, 5, 33~36을 빼는 채널 맵, instant 0x4321, 그리고 40 µs짜리 AoD 상수 톤 확장(CTE, 17장)까지. 헤더 첫 바이트의 비트는 LLID(2) · NESN · SN · MD · CP(CTE 정보 있음) · RFU(2)이고, CP가 1이면 길이 바이트 뒤에 CTEInfo 바이트가 붙는다. CRC는 헤더(CTEInfo 포함)와 페이로드에 대해 계산하고, 화이트닝은 그 둘과 CRC에 걸고, CTE는 화이트닝하지 않은 1로 끝에 붙는다.
LL 제어 PDU → 공중 비트 (사양 4.3.2 샘플)
헤더(Table 2.21)·CP·CTEInfo: [Vol 6] Part B §2.4·§2.5.2 · LL_CHANNEL_MAP_IND: §2.4.2.2 · CRC: §3.1.1 · 화이트닝: §3.2 · 샘플: [Vol 6] Part C §4.3.2(데이터 PDU는 §4.3.1)
핵심 정리
- LLID 0b11 = LL 제어 PDU, 첫 바이트 opcode. 한 기기는 한 연결에서 한 번에 한 절차(종료 제외), 응답 타임아웃 40초(연결 갱신·채널 맵 제외).
- instant = 새 값을 쓰기 시작할 connEventCount. 센트럴이 고르고, 페리페럴이 들을 기회가 6번 이상이게, mod 65536으로 비교. 지난 instant의 연결 갱신은 0x28로 끊긴다.
- 연결 갱신의 새 앵커 포인트는 instant 직전 앵커 + 옛 간격 + WinOffset에서 여는 전송 창 안의 첫 패킷.
- 양립할 수 없는 절차가 겹치면: 상대가 이미 응답했으면 끊고, 아니면 센트럴이 거절, 페리페럴이 양보. 같은 절차끼리면 0x23, 아니면 0x2A.
- 공중 비트 = 프리앰블 · 접근 주소 · 화이트닝된(헤더 · CTEInfo · 페이로드 · CRC) · 화이트닝 안 한 CTE.
확인 퀴즈
connEventCount가 0xFFF0일 때 Instant 0x0005인 PDU를 받았다. instant는?
연결 갱신 PDU의 instant가 이미 지났다. 페리페럴은?
페리페럴이 PHY 갱신을 시작했는데, 응답을 받기 전에 센트럴이 채널 맵 갱신을 보냈다. 페리페럴은?
LL 제어 PDU 응답 타임아웃이 적용되지 않는 절차는?