Characteristic είναι η θεμελιώδης μονάδα δεδομένων στο Bluetooth Low Energy, μέσω της οποίας το Central λαμβάνει ή γράφει πληροφορίες σε μια περιφερειακή συσκευή. Κάθε Characteristic ανήκει σε μια συγκεκριμένη υπηρεσία GATT, έχει μοναδικό UUID και ένα σύνολο ιδιοτήτων (read, write, notify, indicate) που καθορίζουν τις δυνατές λειτουργίες. Σύμφωνα με το Bluetooth Core Specification 5.4 (2023), το Bluetooth SIG έχει προσδιορίσει περισσότερα από 500 τυπικά χαρακτηριστικά για ιατρικές, γυμναστικής και βιομηχανικές συσκευές. Ο προγραμματιστής δημιουργεί προσαρμοσμένα χαρακτηριστικά για τη μεταφορά οποιωνδήποτε δεδομένων χρήστη — από μετρήσεις αισθητήρων έως εντολές ελέγχου συσκευής.
Κύρια σημεία
Characteristic είναι ένα χαρακτηριστικό του πρωτοκόλλου GATT που περιέχει μια τιμή (value) και μεταδεδομένα. Στην αρχιτεκτονική BLE, τα δεδομένα δεν μεταφέρονται απευθείας μεταξύ συσκευών, αλλά μέσω ανάγνωσης και εγγραφής τιμών χαρακτηριστικών της υπηρεσίας. Εάν η υπηρεσία είναι ένας φάκελος, τότε το Characteristic είναι ένα αρχείο μέσα σε αυτόν τον φάκελο.
Κάθε Characteristic αποτελείται από τρία συστατικά: δήλωση (declaration), τιμή (value) και περιγραφείς (descriptors). Η δήλωση περιέχει το UUID του χαρακτηριστικού και τις ιδιότητές του. Η τιμή είναι τα πραγματικά δεδομένα που μεταφέρονται μεταξύ Central και Peripheral. Οι περιγραφείς παρέχουν πρόσθετη διαμόρφωση.
Σύμφωνα με το Bluetooth Core Specification 5.4 (2023), όλες οι ανταλλαγές δεδομένων στο BLE γίνονται μέσω λειτουργιών σε χαρακτηριστικά. Ακόμα και τα τυπικά προφίλ, όπως το Heart Rate Profile ή το Battery Service, είναι χτισμένα πάνω σε ένα σύνολο χαρακτηριστικών με προκαθορισμένα UUID. Αυτό εξασφαλίζει συμβατότητα συσκευών διαφορετικών κατασκευαστών χωρίς προηγούμενη διαμόρφωση.
Είναι σημαντικό για τον προγραμματιστή να κατανοήσει: κάθε Characteristic μπορεί να υποστηρίζει διαφορετικούς συνδυασμούς ιδιοτήτων. Ένα χαρακτηριστικό μπορεί να είναι μόνο για ανάγνωση, άλλο — μόνο για εγγραφή, τρίτο — για ειδοποιήσεις. Η σωστή επιλογή ιδιοτήτων καθορίζει το σενάριο χρήσης και την κατανάλωση ενέργειας της συσκευής.
Ιδιότητες (properties) του χαρακτηριστικού καθορίζουν ποιες λειτουργίες επιτρέπονται σε αυτό. Είναι μια μάσκα byte, όπου κάθε bit ενεργοποιεί ή απενεργοποιεί μια συγκεκριμένη λειτουργία. Παρακάτω παρατίθενται οι κύριες ιδιότητες.
| Ιδιότητα | Bit | Περιγραφή | Τυπική χρήση |
|---|---|---|---|
| Read | 0x02 | Το Central μπορεί να διαβάσει την τρέχουσα τιμή | Κατάσταση, επίπεδο μπαταρίας, διαμόρφωση |
| Write | 0x08 | Το Central μπορεί να γράψει μια νέα τιμή | Εντολές ελέγχου, ρυθμίσεις |
| Notify | 0x10 | Το Peripheral στέλνει τιμή χωρίς επιβεβαίωση | Δεδομένα ροής (σφυγμός, θερμοκρασία) |
| Indicate | 0x20 | Το Peripheral στέλνει τιμή με επιβεβαίωση | Κρίσιμα δεδομένα (συναγερμοί, καταστάσεις) |
| Write Without Response | 0x04 | Εγγραφή χωρίς αναμονή επιβεβαίωσης από τον διακομιστή | Μετάδοση εντολών υψηλής ταχύτητας |
Δικαιώματα (permissions) είναι το επίπεδο πρόσβασης σε επίπεδο διακομιστή GATT. Σε αντίθεση με τις ιδιότητες που δηλώνονται στη δήλωση του χαρακτηριστικού, τα δικαιώματα ελέγχονται σε κάθε λειτουργία. Μπορεί να περιλαμβάνουν απαιτήσεις κρυπτογράφησης και πιστοποίησης ταυτότητας.
Bluetooth SIG έχει προσδιορίσει περισσότερα από 500 τυπικά χαρακτηριστικά που καλύπτουν τα περισσότερα κοινά σενάρια χρήσης BLE. Η χρήση τυπικών UUID εγγυάται ότι οποιαδήποτε συσκευή λήψης θα ερμηνεύσει σωστά τα δεδομένα χωρίς προηγούμενη διαμόρφωση.
Ακολουθούν τα πιο συχνά χρησιμοποιούμενα τυπικά χαρακτηριστικά:
| UUID | Όνομα | Τύπος δεδομένων | Υπηρεσία |
|---|---|---|---|
| 0x2A19 | Battery Level | uint8 (0–100%) | Battery Service |
| 0x2A37 | Heart Rate Measurement | uint8 + σημαίες | Heart Rate |
| 0x2A6E | Temperature | int16 (0.01°C) | Environmental Sensing |
| 0x2A6F | Humidity | uint16 (0.01%) | Environmental Sensing |
| 0x2A00 | Device Name | UTF-8 string | Generic Access |
| 0x2A01 | Appearance | uint16 | Generic Access |
Εάν ένα υπάρχον τυπικό χαρακτηριστικό καλύπτει την εργασία σας — χρησιμοποιήστε το. Αυτό απλοποιεί την πιστοποίηση Bluetooth και αυξάνει τη συμβατότητα με το οικοσύστημα. Δημιουργήστε προσαρμοσμένα χαρακτηριστικά μόνο για μοναδικά δεδομένα που δεν υπάρχουν στο μητρώο SIG.
Η δημιουργία χαρακτηριστικού γίνεται στην πλευρά του Peripheral — της συσκευής που παρέχει δεδομένα. Ας εξετάσουμε την υλοποίηση σε iOS (Swift) και Android (Java).
Το Core Bluetooth παρέχει την κλάση CBMutableCharacteristic για τη δημιουργία χαρακτηριστικού με καθορισμό UUID, ιδιοτήτων και αρχικής τιμής.
import CoreBluetooth
let characteristicUUID = CBUUID("2A19") // Χαρακτηριστικό επιπέδου μπαταρίας
let characteristic = CBMutableCharacteristic(
type: characteristicUUID,
properties: [.read, .notify],
value: nil,
permissions: [.readable]
)
// Ενημέρωση τιμής κατά την αλλαγή
let batteryData = Data([batteryLevel]) // uint8
peripheralManager.updateValue(
batteryData,
for: characteristic,
onSubscribedCentrals: nil
)
Στο Android, το χαρακτηριστικό δημιουργείται μέσω BluetoothGattCharacteristic με καθορισμό UUID, ιδιοτήτων και δικαιωμάτων.
import android.bluetooth.*;
UUID charUuid = UUID.fromString("00002A19-0000-1000-8000-00805F9B34FB");
BluetoothGattCharacteristic characteristic =
new BluetoothGattCharacteristic(
charUuid,
BluetoothGattCharacteristic.PROPERTY_READ
| BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ
);
// Ορισμός τιμής
characteristic.setValue(batteryLevel, BluetoothGattCharacteristic.FORMAT_UINT8, 0);
gattServer.notifyCharacteristicChanged(device, characteristic, false);
Οι λειτουργίες στο Characteristic χωρίζονται σε τρεις τύπους: ανάγνωση (read), εγγραφή (write) και ειδοποιήσεις (notify/indicate). Η επιλογή λειτουργίας εξαρτάται από το σενάριο: τα δεδομένα κατόπιν αιτήματος διαβάζονται, οι εντολές γράφονται, τα δεδομένα ροής εγγράφονται σε ειδοποιήσεις.
Read — Το Central στέλνει αίτημα ανάγνωσης της τιμής του χαρακτηριστικού. Το Peripheral απαντά με την τρέχουσα τιμή. Η λειτουργία είναι σύγχρονη και απαιτεί σαφές αίτημα και από τις δύο πλευρές. Χρησιμοποιείται για δεδομένα που αλλάζουν σπάνια: έκδοση υλικολογισμικού, σειριακός αριθμός, ρυθμίσεις.
Write — Το Central στέλνει δεδομένα στο Peripheral. Υπάρχουν δύο τρόποι: Write with Response (επιβεβαίωση από το Peripheral) και Write Without Response (χωρίς επιβεβαίωση). Το Write with Response εγγυάται την παράδοση — το Peripheral στέλνει επιβεβαίωση μετά την εγγραφή. Το Write Without Response είναι ταχύτερο, αλλά δεν εγγυάται την παράδοση.
Notify και Indicate — Το Peripheral ξεκινά την αποστολή δεδομένων στο Central. Στο Notify, τα δεδομένα αποστέλλονται χωρίς επιβεβαίωση — εάν το Central δεν πρόλαβε να λάβει το πακέτο, χάνεται. Στο Indicate, το Central στέλνει επιβεβαίωση (σε επίπεδο PDU), που εγγυάται την παράδοση. Το Indicate είναι πιο αργό, αλλά πιο αξιόπιστο. Για εγγραφή σε ειδοποιήσεις, το Central γράφει την τιμή 0x0001 στο CCCD (Client Characteristic Configuration Descriptor).
MTU (Maximum Transmission Unit) καθορίζει το μέγιστο μέγεθος ενός πακέτου δεδομένων BLE. Από προεπιλογή, το MTU είναι 23 byte, εκ των οποίων τα 3 byte είναι η κεφαλίδα — το ωφέλιμο φορτίο (ATT payload) είναι 20 byte. Αυτό είναι αρκετό για τα περισσότερα δεδομένα αισθητήρων, αλλά ανεπαρκές για μεταφορά αρχείων ή μεγάλων διαμορφώσεων.
Το Bluetooth Core Specification 5.4 υποστηρίζει διαπραγμάτευση MTU (MTU negotiation) — το Central και το Peripheral μπορούν να συμφωνήσουν σε μεγαλύτερο μέγεθος πακέτου έως 517 byte. Η διαδικασία έχει ως εξής: το Central στέλνει αίτημα MTU Exchange με πρόταση του MTU του· το Peripheral απαντά με το δικό του MTU· χρησιμοποιείται η μικρότερη από τις δύο τιμές.
// Το iOS ζητά MTU κατά τη σύνδεση
// Μέγιστο MTU στο iOS είναι 185 byte
func peripheral(
_ peripheral: CBPeripheral,
didDiscoverServices error: Error?
) {
// Αίτημα MTU για συγκεκριμένη περιφερειακή συσκευή
peripheral.maximumWriteValueLength(for: .withResponse)
}
Σύμφωνα με το Bluetooth SIG (2023), η αύξηση του MTU από 23 σε 185 byte μειώνει το κόστος μεταφοράς δεδομένων έως και 80% λόγω μείωσης του αριθμού των πακέτων. Για εφαρμογές που μεταδίδουν μετρήσεις υψηλής συχνότητας (π.χ. ΗΚΓ ή επιταχυνσιόμετρο), η αύξηση του MTU είναι κρίσιμη για τη σταθερότητα της ροής.
Συχνές Ερωτήσεις
Η προδιαγραφή BLE δεν περιορίζει τον αριθμό των χαρακτηριστικών σε μια υπηρεσία. Στην πράξη, ο περιορισμός καθορίζεται από τη διαθέσιμη μνήμη του διακομιστή GATT και τις απαιτήσεις απόδοσης. Για ενσωματωμένες συσκευές, συνιστώνται όχι περισσότερα από 10–15 χαρακτηριστικά ανά υπηρεσία.
Notify στέλνει δεδομένα χωρίς επιβεβαίωση — το πακέτο μπορεί να χαθεί χωρίς ειδοποίηση του αποστολέα. Το Indicate απαιτεί επιβεβαίωση (ACK) σε επίπεδο πρωτοκόλλου, που εγγυάται την παράδοση. Το Indicate είναι πιο αργό, αλλά πιο αξιόπιστο. Για κρίσιμα δεδομένα (συναγερμοί, εντολές) χρησιμοποιήστε Indicate.
Ναι, ένα χαρακτηριστικό μπορεί να έχει συνδυασμό ιδιοτήτων. Για παράδειγμα, ένα χαρακτηριστικό ρυθμίσεων μπορεί να υποστηρίζει Read (ανάγνωση τρέχουσας τιμής) και Write (αλλαγή ρύθμισης). Συνδυάστε ιδιότητες σύμφωνα με το σενάριο χρήσης σας.
Χρησιμοποιήστε διαπραγμάτευση MTU για να αυξήσετε το μέγεθος πακέτου σε 185–517 byte. Εάν τα δεδομένα είναι ακόμα πολύ μεγάλα — εφαρμόστε κατατμηματισμό σε επίπεδο εφαρμογής: χωρίστε τα δεδομένα σε πολλά διαδοχικά αιτήματα με έλεγχο ακεραιότητας.
Εάν η εργασία σας καλύπτεται από ένα τυπικό χαρακτηριστικό — χρησιμοποιήστε UUID από το μητρώο Bluetooth SIG. Αυτό απλοποιεί την πιστοποίηση και εξασφαλίζει συμβατότητα με το οικοσύστημα. Δημιουργήστε προσαρμοσμένα UUID μόνο για μοναδικά δεδομένα κατασκευαστών τρίτων.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης