MTU w BLE: co to jest, rozmiar pakietu i negocjacja

Autor: IT Sectr Opublikowano: 2026-07-15 Czas czytania: 10 min

MTU (Maximum Transmission Unit) — to maksymalny rozmiar użytecznych danych w jednym pakiecie BLE, który może być przesłany między urządzeniami w ramach jednej transakcji GATT. W BLE Classic (4.x) MTU jest stałe na poziomie 23 bajtów, co wystarcza do małych odczytów czujników, ale nie do przesyłania plików lub aktualizacji OTA. Bluetooth Core Specification 4.2 (2014) wprowadziła procedurę MTU Size Request, umożliwiającą negocjację większego MTU — do 247 bajtów (BLE 5.0 — do 251 bajtów). Prawidłowa konfiguracja MTU to jeden z kluczowych czynników wydajności aplikacji BLE przesyłających duże ilości danych.

Najważniejsze

  • MTU — maksymalny rozmiar danych w jednym pakiecie BLE, od 23 bajtów (BLE 4.x) do 251 bajtów (BLE 5.0).
  • Negocjacja MTU odbywa się przez MTU Size Request/Response po nawiązaniu połączenia GATT.
  • Duże MTU (247 bajtów) zwiększa szybkość przesyłania danych 5–10 razy w porównaniu ze standardowymi 23 bajtami.
  • Android automatycznie żąda MTU 517 bajtów z BLE 5.0, iOS — 512 bajtów przez requestMTU.
  • Przy aktualizacjach OTA oprogramowania duże MTU skraca czas transmisji z minut do sekund.

Czym jest MTU w BLE?

Maximum Transmission Unit (MTU) w kontekście BLE — to maksymalny rozmiar Application Protocol Data Unit (APDU), który urządzenie może przyjąć w jednym żądaniu GATT. MTU jest określane na poziomie ATT (Attribute Protocol) i zawiera nagłówek ATT (1 bajt) + dane użyteczne. Domyślnie wszystkie urządzenia BLE obsługują MTU 23 bajtów (23 = 1 bajt nagłówka ATT + 22 bajty danych).

MTU to nie fizyczny limit kanału radiowego, ale umowa między urządzeniami na poziomie GATT. Fizyczny rozmiar pakietu BLE w warstwie Link Layer może być większy (do 27 bajtów w BLE 4.0, do 257 bajtów w BLE 5.0 z Data Length Extension), ale warstwa GATT ogranicza, ile danych jest przesyłanych w jednej transakcji. Data Length Extension (DLE) — to osobny mechanizm w warstwie Link Layer, który zwiększa fizyczny pakiet do 251 bajtów i musi być negocjowany osobno.

Różnica między MTU a DLE: ATT MTU — ile danych jest przesyłanych w jednym żądaniu GATT, DLE — ile danych mieści się w jednym pakiecie Link Layer. Aby uzyskać maksymalną prędkość, należy negocjować oba parametry. Bez DLE nawet przy MTU 247 bajtów dane będą fragmentowane na kilka pakietów Link Layer po 27 bajtów, zmniejszając przepustowość.

Negocjacja MTU: procedura i protokół

MTU Size Request — procedura inicjowana przez Central po nawiązaniu połączenia GATT. Central wysyła MTU Request z podaniem swojej pojemności MTU (maksymalny rozmiar, jaki może przyjąć). Peripheral odpowiada MTU Response ze swoją wartością. Używane MTU to minimalna z dwóch wartości. Jeśli Central proponuje MTU 512, a Peripheral obsługuje tylko 128, połączenie będzie używać MTU 128.

swift
import CoreBluetooth

// Żądanie maksymalnego MTU w iOS
func requestMTU(central: CBCentralManager,
                    peripheral: CBPeripheral) {
    peripheral.maximumWriteValueLength(
        for: .withoutResponse
    )

// iOS automatycznie negocjuje MTU przy połączeniu
            // MTU = 512 dla urządzeń BLE 5.0
    let mtu = peripheral.maximumWriteValueLength(
        for: .withResponse
    )

    print("Negocjowane MTU: " +
          String(mtu))
}

Moment negocjacji: MTU Request powinien być wysłany po wykryciu usług (discoverServices), ale przed rozpoczęciem aktywnego przesyłania danych. W iOS Core Bluetooth automatycznie negocjuje MTU przy połączeniu — programista nie musi ręcznie wysyłać MTU Request. W Androidzie należy jawnie wywołać requestMTU. Po negocjacji MTU pozostaje stałe dla danego połączenia — ponowna negocjacja jest niemożliwa bez rozłączenia i ponownego połączenia.

Ograniczenia ATT: dlaczego MTU nie może być większe niż 251 bajtów

ATT (Attribute Protocol) — protokół, na którym zbudowany jest GATT. Pakiet ATT ma maksymalny rozmiar 257 bajtów (ATT_MTU-1). Z tego 1 bajt to Opcode (typ operacji), 1 bajt to Handle, do 255 bajtów to Value. Zatem maksymalne MTU dozwolone przez specyfikację ATT to 257 bajtów (w praktyce używa się do 251 bajtów, ponieważ część pól pomocniczych i tak jest potrzebna).

Do wysyłania danych większych niż MTU używa się fragmentacji na poziomie aplikacji. Programista sam dzieli dane na kawałki o rozmiarze ≤ MTU i wysyła je sekwencyjnie. Każdy kawałek jest formalnie osobnym żądaniem GATT Write Request. Strona odbierająca składa kawałki w jeden bufor. Wbudowanej obsługi fragmentacji w GATT nie ma — to zadanie programisty.

Wersja BLEMaks. MTUMaks. DLELimit ATT MTU
BLE 4.0 / 4.123 bajty27 bajtówATT stały
BLE 4.2247 bajtów251 bajtów257 bajtów
BLE 5.0251 bajtów251 bajtów257 bajtów
Android + iOS512 / 517251 bajtówPrzekroczenie ATT

Ciekawostka: iOS i Android żądają MTU odpowiednio 512 i 517 bajtów, ale ta wartość przekracza limit ATT. W praktyce stos BLE automatycznie fragmentuje takie dane, wysyłając je jako kilka sekwencyjnych żądań GATT po maksymalnie 251 bajtów. Dla programisty różnica jest niezauważalna — writeValue działa z dowolnym rozmiarem do 512 bajtów w iOS.

Wpływ MTU na wydajność

Rozmiar MTU bezpośrednio wpływa na przepustowość połączenia BLE. Przy MTU 23 bajtów maksymalna użyteczna szybkość transmisji wynosi około 7–10 KB/s w idealnych warunkach. Zwiększenie MTU do 247 bajtów podnosi prędkość do 60–90 KB/s (z DLE i optymalnym connection interval). Jest to szczególnie ważne dla aplikacji przesyłających obrazy, fragmenty audio lub logi.

Wydajność transmisji BLE zależy od trzech czynników: MTU (ile danych w jednym żądaniu ATT), connection interval (jak często odbywają się zdarzenia wymiany) i DLE (ile danych w jednym pakiecie Link Layer). Optymalna konfiguracja dla maksymalnej prędkości: MTU = 247, DLE = 251, connection interval = 7.5 ms (wartość minimalna).

Według danych Bluetooth SIG White Paper (2023), zwiększenie MTU z 23 do 247 bajtów przy connection interval 30 ms zwiększa przepustowość z 8 KB/s do 42 KB/s — wzrost 5-krotny. Przy connection interval 7.5 ms przepustowość osiąga 88 KB/s. Dla aplikacji niewymagających dużej prędkości (czujniki temperatury, beacony BLE) standardowe MTU 23 bajtów pozostaje wystarczające.

Konfiguracja MTU w iOS i Androidzie

iOS Core Bluetooth automatycznie negocjuje MTU przy połączeniu z Peripheral. Programista może sprawdzić bieżące MTU przez maximumWriteValueLength, ale nie może go ustawić ręcznie. iOS używa MTU do 512 bajtów dla urządzeń BLE 5.0 i do 247 dla BLE 4.2. Do zapisu dużych ilości danych używaj writeType: .withResponse dla gwarantowanej dostawy.

kotlin
// Żądanie MTU na Androidzie (Kotlin)
val bluetoothGatt: BluetoothGatt = ...

// Żądanie MTU 517 bajtów
bluetoothGatt.requestMtu(517)

// Obsługa wyniku w callbacku
override fun onMtuChanged(
    gatt: BluetoothGatt,
    mtu: Int,
    status: Int
) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        println("MTU negotiated: $mtu")
    }
}

Android udostępnia BluetoothGatt.requestMtu(int), który pozwala zażądać dowolnego MTU do 517 bajtów. Rzeczywiste MTU jest określane przez urządzenie peryferyjne — jeśli obsługuje tylko 23 bajty, Android zwróci MTU 23. Do określenia bieżącego MTU użyj gatt.requestMtu(0) — zwróci bieżącą wartość bez próby zmiany. Android 12+ obsługuje automatyczną negocjację MTU przy połączeniu przez TRANSPORT_LE.

Frameworki międzyplatformowe (Flutter, React Native) zazwyczaj udostępniają API do requestMTU. W bibliotece FlutterBlue Plus MTU jest ustawiane jako parametr połączenia. W RxAndroidBle — przez metodę requestMtu. Zaleca się zawsze negocjować maksymalne MTU zaraz po wykryciu usług, przed rozpoczęciem przesyłania danych, aby uniknąć fragmentacji na poziomie aplikacji.

MTU a aktualizacje OTA

OTA (Over-The-Air) aktualizacje oprogramowania — najbardziej wymagający względem MTU scenariusz w BLE. Typowy rozmiar oprogramowania urządzenia IoT to 100–500 KB. Przy MTU 23 bajtów i connection interval 30 ms transmisja 100 KB zajmuje około 2–3 minut. Przy MTU 247 bajtów i DLE 251 bajtów — 20–40 sekund. A przy MTU 512 bajtów (iOS) — 10–15 sekund.

Proces aktualizacji OTA zazwyczaj obejmuje: fragmentację oprogramowania na pakiety o rozmiarze ≤ MTU, sekwencyjne wysyłanie przez Notify/Write, weryfikację sumy kontrolnej każdego pakietu i potwierdzenie odbioru. Jeśli któryś pakiet zostanie utracony, urządzenie żąda ponownego wysłania. Niezawodność OTA krytycznie zależy od prawidłowego wyboru MTU i connection interval.

Zalecenia dla OTA: negocjuj maksymalne MTU (247–512 bajtów), ustaw connection interval 7.5–15 ms (jeśli urządzenie obsługuje), używaj DLE (Data Length Extension) do zwiększenia fizycznego pakietu do 251 bajtów. Dla urządzeń z ograniczoną pamięcią bufora (np. moduły BLE oparte na nRF52) sprawdzaj maksymalne MTU w specyfikacji układu.

Często zadawane pytania

Co się stanie, jeśli nie negocjuję MTU?

Połączenie będzie używać domyślnego MTU — 23 bajtów. Dla większości scenariuszy IoT (przesyłanie odczytów czujników) to wystarczy. Do przesyłania dużych ilości danych prędkość będzie 5–10 razy niższa niż z negocjowanym MTU 247 bajtów.

Czy można zmienić MTU po rozpoczęciu przesyłania danych?

Nie, MTU jest negocjowane jeden raz po połączeniu i nie może być zmienione bez rozłączenia i ponownego połączenia. Dlatego zaleca się negocjować MTU zaraz po wykryciu usług, przed rozpoczęciem aktywnego przesyłania danych.

Dlaczego Android żąda MTU 517 bajtów, a iOS tylko 512?

Są to historycznie ustalone empiryczne maksima dla każdego stosu. Rzeczywiste ATT MTU i tak jest ograniczone do 257 bajtów zgodnie ze specyfikacją. Stosy automatycznie fragmentują dane większe niż 251 bajtów na kilka pakietów, więc różnica między 512 a 517 jest nieistotna.

Jak MTU jest powiązane z Data Length Extension (DLE)?

MTU — rozmiar żądania GATT na poziomie ATT. DLE — rozmiar fizycznego pakietu w warstwie Link Layer. Bez DLE każde żądanie GATT (do 247 bajtów) jest fragmentowane na pakiety po 27 bajtów. Z DLE — przesyłane jest w jednym pakiecie. Dla maksymalnej prędkości należy negocjować oba parametry.

Jakie MTU wybrać dla trackera fitness?

Dla trackera fitness przesyłającego odczyty tętna i kroki standardowe MTU 23 bajtów wystarczy. Jeśli wymagane jest przesyłanie historii treningów (objętość 10–50 KB) — negocjuj MTU 247 bajtów, aby przyspieszyć synchronizację danych przy połączeniu ze smartfonem.

Podsumowanie

  • MTU — maksymalny rozmiar danych w jednym żądaniu GATT: od 23 bajtów (domyślnie) do 251 bajtów (BLE 5.0).
  • Negocjacja MTU odbywa się przez MTU Size Request/Response, inicjowane przez Central po połączeniu.
  • Protokół ATT ogranicza MTU do 257 bajtów, ale iOS i Android żądają do 512–517 bajtów z automatyczną fragmentacją.
  • Zwiększenie MTU z 23 do 247 bajtów zwiększa przepustowość 5–10 razy przy optymalnym connection interval.
  • Dla maksymalnej prędkości należy negocjować MTU + DLE + connection interval 7.5 ms.
  • W iOS MTU jest negocjowane automatycznie, w Androidzie — przez requestMtu, zaleca się żądanie 247–517 bajtów.
  • Aktualizacje OTA — najbardziej wymagający scenariusz: prawidłowe MTU skraca czas transmisji z minut do sekund.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również