MTU (Maximum Transmission Unit) είναι το μέγιστο μέγεθος χρήσιμων δεδομένων σε ένα πακέτο BLE που μπορεί να μεταφερθεί μεταξύ συσκευών σε μία συναλλαγή GATT. Στο BLE Classic (4.x) το MTU είναι σταθερό στα 23 bytes, αρκετό για μικρές αναγνώσεις αισθητήρων αλλά ανεπαρκές για μεταφορά αρχείων ή OTA ενημερώσεις. Η Bluetooth Core Specification 4.2 (2014) εισήγαγε τη διαδικασία MTU Size Request, επιτρέποντας διαπραγμάτευση μεγαλύτερου MTU — έως 247 bytes (BLE 5.0 — έως 251 bytes). Η σωστή ρύθμιση MTU είναι ένας από τους κλειδικούς παράγοντες απόδοσης των BLE εφαρμογών που μεταφέρουν μεγάλες ποσότητες δεδομένων.
Κύρια σημεία
Maximum Transmission Unit (MTU) στο πλαίσιο του BLE — είναι το μέγιστο μέγεθος της Application Protocol Data Unit (APDU) που μια συσκευή μπορεί να λάβει σε ένα αίτημα GATT. Το MTU ορίζεται στο επίπεδο ATT (Attribute Protocol) και περιλαμβάνει την κεφαλίδα ATT (1 byte) + χρήσιμα δεδομένα. Από προεπιλογή, όλες οι συσκευές BLE υποστηρίζουν MTU 23 bytes (23 = 1 byte κεφαλίδα ATT + 22 bytes δεδομένα).
Το MTU δεν είναι φυσικό όριο του ραδιοφώνου, αλλά συμφωνία μεταξύ συσκευών στο επίπεδο GATT. Το φυσικό μέγεθος του πακέτου BLE στο επίπεδο Link Layer μπορεί να είναι μεγαλύτερο (έως 27 bytes στο BLE 4.0, έως 257 bytes στο BLE 5.0 με Data Length Extension), αλλά το επίπεδο GATT περιορίζει πόσα δεδομένα μεταφέρονται σε μία συναλλαγή. Το Data Length Extension (DLE) — είναι ένας ξεχωριστός μηχανισμός στο επίπεδο Link Layer που αυξάνει το φυσικό πακέτο σε 251 bytes και πρέπει να διαπραγματευτεί ξεχωριστά.
Διαφορά μεταξύ MTU και DLE: ATT MTU — πόσα δεδομένα μεταφέρονται σε ένα αίτημα GATT, DLE — πόσα δεδομένα χωράνε σε ένα πακέτο Link Layer. Για μεγίστη ταχύτητα, και οι δύο παράμετροι πρέπει να διαπραγματευτούν. Χωρίς DLE, ακόμη και με MTU 247 bytes, τα δεδομένα θα τμηματιστούν σε πολλά πακέτα Link Layer των 27 bytes, μειώνοντας το εύρος ζώνης.
MTU Size Request — διαδικασία που ξεκινά από το Central μετά τη σύναψη GATT. Το Central στέλνει ένα MTU Request με την χωρητικότητα MTU του (το μέγιστο μέγεθος που μπορεί να λάβει). Το Peripheral απαντά με MTU Response με τη δική του τιμή. Το χρησιμοποιούμενο MTU είναι το ελάχιστο από τις δύο τιμές. Αν το Central προτείνει MTU 512 και το Peripheral υποστηρίζει μόνο 128, η σύνδεση θα χρησιμοποιεί MTU 128.
import CoreBluetooth
// Αίτηση μέγιστου MTU σε iOS
func requestMTU(central: CBCentralManager,
peripheral: CBPeripheral) {
peripheral.maximumWriteValueLength(
for: .withoutResponse
)
// Το iOS διαπραγματεύεται αυτόματα το MTU κατά τη σύνδεση
// MTU = 512 για συσκευές BLE 5.0
let mtu = peripheral.maximumWriteValueLength(
for: .withResponse
)
print("Διαπραγματευμένο MTU: " +
String(mtu))
}
Χρονισμός διαπραγμάτευσης: το MTU Request πρέπει να αποσταλεί μετά την ανακάλυψη υπηρεσιών (discoverServices), αλλά πριν την έναρξη της ενεργής μεταφοράς δεδομένων. Στο iOS Core Bluetooth διαπραγματεύεται αυτόματα το MTU κατά τη σύνδεση — ο αναπτυκτής δεν χρειάζεται να στείλει μη χειροκίνητα το MTU Request. Στο Android, πρέπει να κληθεί ρητά η requestMTU. Μετά τη διαπραγμάτευση, το MTU παραμένει σταθερό για αυτή τη σύνδεση — η επαναδιαπραγμάτευση είναι αδύνατη χωρίς αποσύνδεση και επανασύνδεση.
ATT (Attribute Protocol) — το πρωτόκολλο στο οποίο βασίζεται το GATT. Ένα πακέτο ATT έχει μέγιστο μέγεθος 257 bytes (ATT_MTU-1). Από αυτά, 1 byte είναι Opcode (τύπος λειτουργίας), 1 byte είναι Handle, και έως 255 bytes είναι Value. Άρα, το μέγιστο MTU που επιτρέπεται από την προδιαγραφή ATT είναι 257 bytes (στην πράξη χρησιμοποιείται έως 251 bytes, επειδή κατά μήκος απαιτούνται κάποια εξυπηρετητικά πεδία).
Για την αποστολή δεδομένων μεγαλύτερων από το MTU χρησιμοποιείται τμηματισμός σε επίπεδο εφαρμογής. Ο αναπτυκτής μοιράζει ο ίδιος τα δεδομένα σε τμήματα μεγέθους ≤ MTU και τα αποστέλλει διαδοχικά. Κάθε τμήμα είναι τυπικά ένα ξεχωριστό αίτημα GATT Write Request. Η λήψτρια πλευρά συναρμολογεί τα τμήματα σε ένα μοναδικό buffer. Δεν υπάρχει ενσωματωμένη υποστήριξη για τμηματισμό στο GATT — αυτή είναι η δουλειά του αναπτυκτή.
| Έκδοση BLE | Μέγ. MTU | Μέγ. DLE | Όριο ATT MTU |
|---|---|---|---|
| BLE 4.0 / 4.1 | 23 bytes | 27 bytes | ATT σταθερό |
| BLE 4.2 | 247 bytes | 251 bytes | 257 bytes |
| BLE 5.0 | 251 bytes | 251 bytes | 257 bytes |
| Android + iOS | 512 / 517 | 251 bytes | Υπέρβαση ATT |
Ενδιαφέρον γεγονός: το iOS και το Android ζητούν MTU 512 και 517 bytes αντίστοιχα, αλλά αυτή η τιμή υπερβαίνει το όριο ATT. Στην πράξη, η στίβα BLE τμηματίζει αυτόματα τέτοια δεδομένα, στέλνοντάς τα ως πολλά διαδοχικά αιτήματα GATT μέχρι 251 bytes. Για τον αναπτυκτή, η διαφορά είναι αναισθητη — η writeValue λειτουργεί με οποιοδήποτε μέγεθος έως 512 bytes στο iOS.
Το μέγεθος του MTU επηρεάζει άμεσα το εύρος ζώνης της σύνδεσης BLE. Με MTU 23 bytes, η μέγιστη ωφέλιμη ταχύτητα μεταφοράς είναι περίπου 7–10 KB/s σε ιδανικές συνθήκες. Η αύξηση του MTU σε 247 bytes αυξάνει την ταχύτητα σε 60–90 KB/s (με DLE και βελτιστο συνασμο connection interval). Αυτό είναι ιδιαίτερα σημαντικό για εφαρμογές που μεταφέρουν εικόνες, ηχητικά τμήματα ή αρχεία καταγραφής.
Η απόδοση της μεταφοράς BLE εξαρτάται από τρεις παράγοντες: MTU (πόσα δεδομένα σε ένα αίτημα ATT), connection interval (πόσο συχνά συμβαίνουν τα συμβάντα ανταλλαγής) και DLE (πόσα δεδομένα σε ένα πακέτο Link Layer). Βελτιστη ρύθμιση για μεγίστη ταχύτητα: MTU = 247, DLE = 251, connection interval = 7.5 ms (ελάχιστη τιμή).
Σύμφωνα με τα δεδομένα της Bluetooth SIG White Paper (2023), η αύξηση του MTU από 23 σε 247 bytes με connection interval 30 ms αυξάνει το εύρος ζώνης από 8 KB/s σε 42 KB/s — αύξηση 5 φορών. Με connection interval 7.5 ms, το εύρος ζώνης φτάνει τα 88 KB/s. Για εφαρμογές που δεν απαιτούν υψηλή ταχύτητα (αισθητήρες θερμοκρασίας, BLE beacon), το στανταρ MTU 23 bytes παραμένει επαρκές.
iOS Core Bluetooth διαπραγματεύεται αυτόματα το MTU κατά τη σύνδεση με το Peripheral. Ο αναπτυκτής μπορεί να ελέγξει το τρέχον MTU μέσω maximumWriteValueLength, αλλά δεν μπορεί να το ρυθμίσει χειροκίνητα. Το iOS χρησιμοποιεί MTU έως 512 bytes για συσκευές BLE 5.0 και έως 247 για BLE 4.2. Για εγγραφή μεγάλων όγκων δεδομένων, χρησιμοποιήστε writeType: .withResponse για εγγυημένη παράδοση.
// Αίτηση MTU σε Android (Kotlin)
val bluetoothGatt: BluetoothGatt = ...
// Αίτηση MTU 517 bytes
bluetoothGatt.requestMtu(517)
// Χειρισμός αποτελέσματος σε callback
override fun onMtuChanged(
gatt: BluetoothGatt,
mtu: Int,
status: Int
) {
if (status == BluetoothGatt.GATT_SUCCESS) {
println("MTU negotiated: $mtu")
}
}
Android παρέχει το BluetoothGatt.requestMtu(int), που επιτρέπει την αίτηση οποιουδήποτε MTU έως 517 bytes. Το πραγματικό MTU καθορίζεται από την περιφερειακή συσκευή — αν υποστηρίζει μόνο 23 bytes, το Android θα επιστρέψει MTU 23. Για τον προσδιορισμό του τρέχοντος MTU, χρησιμοποιήστε gatt.requestMtu(0) — αυτό επιστρέφει την τρέχουσα τιμή χωρίς να προσπαθεί να την αλλάξει. Το Android 12+ υποστηρίζει αυτόματη διαπραγμάτευση MTU κατά τη σύνδεση μέσω TRANSPORT_LE.
Τα διαπλατφορμικά πλαίσια (Flutter, React Native) συνήθως παρέχουν API για requestMTU. Στη βιβλιοθήκη FlutterBlue Plus, το MTU ορίζεται ως παράμετρος σύνδεσης. Στο RxAndroidBle — μέσω της μεθόδου requestMtu. Συνιστάται να διαπραγματεύετε πάντα το μέγιστο MTU αμέσως μετά την ανακάλυψη υπηρεσιών, πριν από την έναρξη της μεταφοράς δεδομένων, για να αποφυγεί ο τμηματισμός σε επίπεδο εφαρμογής.
OTA (Over-The-Air) ενημερώσεις firmware — το πιο απαιτητικό σενάριο για το MTU στο BLE. Το τυπικό μέγεθος firmware μιας IoT συσκευής είναι 100–500 KB. Με MTU 23 bytes και connection interval 30 ms, η μεταφορά 100 KB διαρκεί περίπου 2–3 λεπτά. Με MTU 247 bytes και DLE 251 bytes — 20–40 δευτερόλεπτα. Και με MTU 512 bytes (iOS) — 10–15 δευτερόλεπτα.
Η διαδικασία OTA ενημέρωσης συνήθως περιλαμβάνει: τμηματισμό του firmware σε πακέτα μεγέθους ≤ MTU, διαδοχική αποστολή μέσω Notify/Write, επαλήθευση αθροίσματος ελέγχου σε κάθε πακέτο και επιβεβαίωση λήψης. Αν ένα πακέτο χαθεί, η συσκευή ζητά εκ νέου αποστολή. Η αξιοπιστία του OTA εξαρτάται κριτικά από τη σωστή επιλογή MTU και connection interval.
Συστάσεις για OTA: διαπραγματεύστε το μέγιστο MTU (247–512 bytes), ορίστε το connection interval σε 7.5–15 ms (αν το υποστηρίζει η συσκευή), χρησιμοποιήστε DLE (Data Length Extension) για αύξηση του φυσικού πακέτου σε 251 bytes. Για συσκευές με περιορισμένη μνήμη buffer (π.χ. BLE μονάδες με βάση το nRF52), ελέγξτε το μέγιστο MTU στις προδιαγραφές του chip.
Συχνές Ερωτήσεις
Η σύνδεση θα χρησιμοποιεί το προεπιλεγμένο MTU — 23 bytes. Για τα περισσότερα σενάρια IoT (μεταφορά αναγνώσεων αισθητήρων) αυτό είναι αρκετό. Για μεταφορά μεγάλων όγκων δεδομένων, η ταχύτητα θα είναι 5–10 φορές χαμηλότερη από ότι με διαπραγματευμένο MTU 247 bytes.
Όχι, το MTU διαπραγματεύεται μία φορά μετά τη σύνδεση και δεν μπορεί να αλλαχθεί χωρίς αποσύνδεση και επανασύνδεση. Για αυτό συνιστάται να διαπραγματεύετε το MTU αμέσως μετά την ανακάλυψη υπηρεσιών, πριν την έναρξη της ενεργής μεταφοράς δεδομένων.
Αυτά είναι ιστορικά καθορισμένα εμπειρικά μέγιστα για κάθε stack. Το πραγματικό ATT MTU εξακολουθεί να περιορίζεται σε 257 bytes σύμφωνα με την προδιαγραφή. Τα stacks τμηματίζουν αυτόματα δεδομένα μεγαλύτερα από 251 bytes σε πολλά πακέτα, οπότε η διαφορά μεταξύ 512 και 517 είναι ασημάντη.
MTU — μέγεθος του αιτήματος GATT στο επίπεδο ATT. DLE — μέγεθος του φυσικού πακέτου στο επίπεδο Link Layer. Χωρίς DLE, κάθε αίτημα GATT (έως 247 bytes) τμηματίζεται σε πακέτα των 27 bytes. Με DLE — μεταφέρεται σε ένα πακέτο. Για μεγίστη ταχύτητα, και οι δύο παράμετροι πρέπει να διαπραγματευτούν.
Για ένα fitness tracker που μεταφέρει καρδιακούς παλμούς και βήματα, το στανταρ MTU 23 bytes είναι αρκετό. Αν χρειάζεται να μεταφέρετε ιστορικό προπονήσεων (όγκου 10–50 KB) — διαπραγματεύστε MTU 247 bytes για να επιταχύνετε τον συγχρονισμό δεδομένων κατά τη σύνδεση με το smartphone.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης