Maximum Transmission Unit. 한 번에 실어 보낼 수 있는 최대 크기다.
BLE 의 기본값이 아주 작다
BLE 기본 MTU 23 바이트
− ATT 헤더 3 바이트
─────────────────────
실제 데이터 20 바이트
20 바이트다. 차량 상태 스냅샷(팬 단수 + 실내 온도 + 도어 4개 + 각각의 신뢰도 + 타임스탬프)을 담으면 당연히 넘친다.
이 값이 이렇게 작은 이유는 BLE 의 설계 목표가 코인 배터리로 수년을 버티는 센서였기 때문이다. 한 번에 조금씩 보내면 무선을 켜 두는 시간이 짧아지고, 전력이 준다.
협상으로 늘린다
gatt.requestMtu(247)
요청한 값이 그대로 오는 게 아니다. 양쪽이 지원하는 값 중 작은 쪽으로 정해지고, OS·칩·안드로이드 버전에 따라 달라진다. 그래서 콜백으로 오는 실제 값을 받아서 그 크기에 맞춰 잘라야 한다.
요청 247 → 실제 185 로 확정 → 185 기준으로 나눠 보낸다
요청값을 믿고 자르면 일부 기기에서만 데이터가 잘린다. 재현이 어려운 종류의 버그다.
넘칠 때의 선택지
| 방법 | 특징 |
|---|---|
| MTU 협상 | 가장 단순. 상한이 있다 |
| 캐릭터리스틱 분할 | 상태를 여러 변수로 쪼갠다 — GATT 답게 |
| 애플리케이션 분할 | 직접 조각내고 재조립. 순서·유실 처리를 우리가 진다 |
두 번째가 대개 낫다. 도어 상태와 공조 상태를 한 덩어리로 밀어 넣을 이유가 없다 — 변하는 주기도 다르고, 나눠 두면 바뀐 것만 GATT 알림으로 보낼 수 있어 전력도 아낀다.
CAN 과 비교하면
CAN 은 한 프레임이 8 바이트로 고정이고 협상 자체가 없다. 그래서 10편의 신호 배치가 비트 단위로 촘촘하다. BLE 는 늘릴 수 있지만 얼마나 늘어날지 모른다 — 제약의 성격이 다르다.