Descriptor — είναι ένα βοηθητικό χαρακτηριστικό GATT που παρέχει μεταδεδομένα ή διαμόρφωση για την τιμή του. Το Bluetooth Core Specification 5.4 ορίζει τους περιγραφείς ως αναπόσπαστο μέρος του προφίλ GATT: περιγράφουν μονάδες μέτρησης, εύρη τιμών, ονόματα κειμένου και διαχειρίζονται την εγγραφή σε ειδοποιήσεις. Ο πιο γνωστός περιγραφέας — Client Characteristic Configuration Descriptor (CCCD, 0x2902), ο οποίος επιτρέπει στο Central να εγγράφεται σε ειδοποιήσεις από το χαρακτηριστικό. Σύμφωνα με το Bluetooth SIG, έχουν καθοριστεί 8 τυπικοί περιγραφείς, ενώ προσαρμοσμένοι περιγραφείς μπορούν να δημιουργηθούν από τον προγραμματιστή για οποιαδήποτε πρόσθετα μεταδεδομένα.
Κύρια Σημεία
Descriptor — είναι ένα χαρακτηριστικό GATT που προσαρτάται σε ένα Characteristic και παρέχει πρόσθετες πληροφορίες σχετικά με την τιμή ή τον τρόπο χρήσης του. Στην ορολογία GATT, το χαρακτηριστικό είναι τα δεδομένα, ενώ ο περιγραφέας είναι τα μεταδεδομένα αυτών των δεδομένων.
Κάθε Characteristic μπορεί να έχει μηδέν ή περισσότερους περιγραφείς. Οι περιγραφείς ορίζονται ως ξεχωριστά χαρακτηριστικά GATT και έχουν δικά τους 16-bit UUID στον χώρο Bluetooth SIG. Οι περιγραφείς δεν μπορούν να υπάρχουν ανεξάρτητα — είναι πάντα συνδεδεμένοι με ένα συγκεκριμένο χαρακτηριστικό.
Σύμφωνα με το Bluetooth Core Specification 5.4 (2023), οι περιγραφείς χωρίζονται σε δύο κατηγορίες: τυπικοί (που ορίζονται από το Bluetooth SIG) και προσαρμοσμένοι (που ορίζονται από τον προγραμματιστή). Οι τυπικοί περιγραφείς έχουν UUID στο εύρος 0x2900–0x2908 και εκτελούν αυστηρά καθορισμένες λειτουργίες. Οι προσαρμοσμένοι περιγραφείς χρησιμοποιούν 128-bit UUID, παρόμοια με προσαρμοσμένες υπηρεσίες και χαρακτηριστικά.
Οι περιγραφείς αποτελούν βασικό μηχανισμό για τη διαμόρφωση συμπεριφοράς της σύνδεσης BLE. Χωρίς το CCCD (0x2902) είναι αδύνατο να εγγραφείτε σε ειδοποιήσεις, χωρίς το Presentation Format (0x2904) το Central δεν θα γνωρίζει πώς να ερμηνεύσει τα raw bytes του χαρακτηριστικού.
CCCD με UUID 0x2902 — ο πιο σημαντικός και ευρέως χρησιμοποιούμενος περιγραφέας στο BLE. Διαχειρίζεται την εγγραφή του Central σε ειδοποιήσεις (Notify) και επιβεβαιωμένες ειδοποιήσεις (Indicate) από το χαρακτηριστικό. Χωρίς εγγραφή στο CCCD, το χαρακτηριστικό δεν θα στέλνει ειδοποιήσεις, ακόμα κι αν έχει την ιδιότητα Notify.
Το CCCD είναι μια τιμή 16-bit, όπου το λιγότερο σημαντικό bit (0x0001) ενεργοποιεί το Notify και το δεύτερο bit (0x0002) ενεργοποιεί το Indicate. Το Central γράφει την επιθυμητή τιμή στο CCCD, εγγραφόμενο έτσι στις ειδοποιήσεις. Αν το Central γράψει 0x0000 — η εγγραφή ακυρώνεται.
Ο μηχανισμός λειτουργίας του CCCD έχει ως εξής: όταν το Central ανακαλύπτει ένα χαρακτηριστικό με υποστήριξη Notify, βρίσκει τον περιγραφέα CCCD και γράφει 0x0001. Στη συνέχεια, κάθε φορά που το Peripheral ενημερώνει την τιμή του χαρακτηριστικού, αυτή αποστέλλεται αυτόματα στο εγγεγραμμένο Central μέσω Handle Value Notification (χωρίς αίτημα από το Central).
Σύμφωνα με το Apple Core Bluetooth Programming Guide, το CCCD διαχειρίζεται αυτόματα από το σύστημα κατά την κλήση setNotifyValue για το χαρακτηριστικό. Ο προγραμματιστής δεν χρειάζεται να αναζητήσει και να γράψει χειροκίνητα το CCCD — το Core Bluetooth το κάνει αυτόματα κατά την ενεργοποίηση των ειδοποιήσεων.
Στο iOS η εγγραφή γίνεται μέσω της μεθόδου setNotifyValue στο αντικείμενο CBPeripheral.
import CoreBluetooth
// Εγγραφή στις ειδοποιήσεις χαρακτηριστικών
peripheral.setNotifyValue(true, for: characteristic)
// Ο delegate λαμβάνει ενημερωμένες τιμές
func peripheral(
_ peripheral: CBPeripheral,
didUpdateValueFor characteristic: CBCharacteristic,
error: Error?
) {
// Το characteristic.value έχει νέα δεδομένα
guard let data = characteristic.value else { return }
}
Στο Android η εγγραφή σε ειδοποιήσεις γίνεται μέσω BluetoothGatt.setCharacteristicNotification. Ο προγραμματιστής πρέπει επίσης να γράψει την τιμή 0x0001 στο CCCD χειροκίνητα.
import android.bluetooth.*;
// Ενεργοποίηση ειδοποιήσεων
bluetoothGatt.setCharacteristicNotification(characteristic, true);
// Εγγραφή 0x0001 στο CCCD
BluetoothGattDescriptor descriptor = characteristic
.getDescriptor(
UUID.fromString("00002902-0000-1000-8000-00805F9B34FB")
);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
bluetoothGatt.writeDescriptor(descriptor);
Το Bluetooth SIG έχει ορίσει 8 τυπικούς περιγραφείς για κοινές εργασίες διαμόρφωσης χαρακτηριστικών. Κάθε περιγραφέας έχει αυστηρά καθορισμένο UUID και μορφή τιμής.
| UUID | Όνομα περιγραφέα | Σκοπός | Τύπος τιμής |
|---|---|---|---|
| 0x2900 | Characteristic Extended Properties | Πρόσθετες ιδιότητες χαρακτηριστικού | uint16 (bitmask) |
| 0x2901 | Characteristic User Description | Όνομα κειμένου χαρακτηριστικού | UTF-8 string |
| 0x2902 | Client Characteristic Configuration | Διαχείριση ειδοποιήσεων | uint16 |
| 0x2903 | Server Characteristic Configuration | Διαμόρφωση διακομιστή για broadcast | uint16 |
| 0x2904 | Characteristic Presentation Format | Μορφή παρουσίασης δεδομένων | Δομή (7 bytes) |
| 0x2905 | Characteristic Aggregate Format | Συνένωση πολλαπλών χαρακτηριστικών | Λίστα UUID |
| 0x2906 | Valid Range | Εύρος επιτρεπόμενων τιμών | uint16 × 2 (min, max) |
| 0x2907 | External Report Reference | Αναφορά σε εξωτερική αναφορά | uint16 |
| 0x2908 | Report Reference | Αναφορά σε εσωτερική αναφορά | uint8 + uint16 |
Το Characteristic User Description (0x2901) είναι ιδιαίτερα χρήσιμο για UI: περιέχει ένα ανθρώπινο όνομα του χαρακτηριστικού που μπορεί να εμφανίζεται στη διεπαφή της εφαρμογής. Για παράδειγμα, το χαρακτηριστικό Battery Level μπορεί να έχει περιγραφέα User Description με τιμή "Επίπεδο μπαταρίας".
Το Characteristic Presentation Format (0x2904) περιέχει πληροφορίες για το πώς να ερμηνεύεται η τιμή του χαρακτηριστικού: μορφή (uint8, uint16, float), εκθέτης, μονάδα μέτρησης (μέσω UUID από το μητρώο Bluetooth SIG), χώρος ονομάτων και περιγραφή. Για παράδειγμα, η θερμοκρασία μπορεί να είναι int16 με εκθέτη -2 (διαίρεση 0.01°C) και μονάδα μέτρησης "βαθμός Κελσίου".
Η πρόσβαση σε περιγραφείς διαφέρει σε iOS και Android. Το Core Bluetooth διαχειρίζεται αυτόματα το CCCD κατά την ενεργοποίηση ειδοποιήσεων, ενώ το Android απαιτεί χειροκίνητη εγγραφή τιμής στον περιγραφέα. Ας δούμε και τις δύο προσεγγίσεις.
Στο iOS ο προγραμματιστής συνήθως δεν αλληλεπιδρά απευθείας με τους περιγραφείς. Το Core Bluetooth βρίσκει αυτόματα το CCCD και γράφει την απαιτούμενη τιμή κατά την κλήση setNotifyValue. Για ανάγνωση περιγραφέων χρησιμοποιείται η μέθοδος discoverDescriptors.
// Ανακάλυψη περιγραφέων
peripheral.discoverDescriptors(for: characteristic)
// Ανάγνωση τιμής User Description
func peripheral(
_ peripheral: CBPeripheral,
didDiscoverDescriptorsFor characteristic: CBCharacteristic,
error: Error?
) {
for descriptor in characteristic.descriptors ?? [] {
if descriptor.uuid == CBUUID("2901") {
peripheral.readValue(for: descriptor)
}
}
}
Στο Android ο προγραμματιστής πρέπει να βρει μόνος του τον περιγραφέα CCCD του χαρακτηριστικού και να γράψει την τιμή για ενεργοποίηση ειδοποιήσεων. Αυτό είναι ένα επιπλέον βήμα σε σύγκριση με το iOS.
// Ανάγνωση τιμής περιγραφέα User Description
BluetoothGattDescriptor userDesc = characteristic
.getDescriptor(
UUID.fromString("00002901-0000-1000-8000-00805F9B34FB")
);
if (userDesc != null) {
bluetoothGatt.readDescriptor(userDesc);
}
Οι προσαρμοσμένοι περιγραφείς χρησιμοποιούνται όταν οι τυπικοί περιγραφείς Bluetooth SIG δεν επαρκούν. Για παράδειγμα, ένας κατασκευαστής ιατρικού αισθητήρα μπορεί να προσθέσει έναν περιγραφέα με πληροφορίες βαθμονόμησης ή έναν περιγραφέα με καταγραφή σφαλμάτων.
Ένας προσαρμοσμένος περιγραφέας δημιουργείται με 128-bit UUID, όπως και ένα προσαρμοσμένο χαρακτηριστικό. Από την πλευρά του Peripheral, ο προγραμματιστής τον προσθέτει στο χαρακτηριστικό μέσω του αντίστοιχου API. Από την πλευρά του Central, ο περιγραφέας ανακαλύπτεται αυτόματα κατά την κλήση discoverDescriptors.
Κατά τη δημιουργία προσαρμοσμένου περιγραφέα, ακολουθήστε τους κανόνες: το μήκος της τιμής πρέπει να αντιστοιχεί στον αναμενόμενο τύπο δεδομένων, τα δικαιώματα πρόσβασης (read/write) πρέπει να ορίζονται ρητά. Μη χρησιμοποιείτε UUID από το εύρος των τυπικών περιγραφέων Bluetooth SIG (0x2900–0x2908) για προσαρμοσμένους σκοπούς.
Το Χαρακτηριστικό και ο περιγραφέας είναι διαφορετικά επίπεδα χαρακτηριστικών GATT. Το χαρακτηριστικό είναι ένα σημείο δεδομένων, ενώ ο περιγραφέας είναι τα μεταδεδομένα ή η διαμόρφωσή του. Η διαφορά εκδηλώνεται σε διάφορες πτυχές: σκοπό, UUID και κανόνες πρόσβασης.
Το χαρακτηριστικό έχει υποχρεωτική δήλωση (declaration) που βρίσκεται πάντα στον πίνακα GATT. Ο περιγραφέας είναι προαιρετικός — το χαρακτηριστικό μπορεί να μην έχει περιγραφείς. Το χαρακτηριστικό μπορεί να διαβαστεί, να γραφτεί ή να στέλνει ειδοποιήσεις ανεξάρτητα. Ο περιγραφέας είναι πάντα συνδεδεμένος με το χαρακτηριστικό και δεν υπάρχει ξεχωριστά.
Σύμφωνα με το Bluetooth Core Specification 5.4, στον πίνακα GATT η σειρά χαρακτηριστικών είναι: δήλωση υπηρεσίας, δήλωση χαρακτηριστικού, τιμή χαρακτηριστικού, περιγραφείς χαρακτηριστικού (αν υπάρχουν), στη συνέχεια η επόμενη υπηρεσία. Αυτή η σειρά είναι υποχρεωτική για τη σωστή λειτουργία των πελατών GATT.
Συχνές Ερωτήσεις
Το CCCD χρειάζεται για τη διαχείριση της εγγραφής: η ιδιότητα Notify απλώς δηλώνει ότι το χαρακτηριστικό μπορεί να στέλνει ειδοποιήσεις, αλλά δεν τις ενεργοποιεί. Το Central πρέπει να εγγραφεί ρητά γράφοντας 0x0001 στο CCCD. Αυτό αποτρέπει την ανεπιθύμητη αποστολή δεδομένων σε ένα μη προετοιμασμένο Central.
Η προδιαγραφή δεν περιορίζει τον αριθμό των περιγραφέων. Στην πράξη, κάθε χαρακτηριστικό έχει συνήθως 1–3 περιγραφείς: CCCD (για χαρακτηριστικά με Notify/Indicate), προαιρετικά User Description και Presentation Format. Πάρα πολλοί περιγραφείς αυξάνουν το μέγεθος του πίνακα GATT.
Στις περισσότερες περιπτώσεις όχι. Το Core Bluetooth σε iOS και Android προσθέτουν αυτόματα το CCCD σε χαρακτηριστικά που έχουν ιδιότητες Notify ή Indicate. Οι προσαρμοσμένοι περιγραφείς δημιουργούνται χειροκίνητα μόνο για συγκεκριμένα μεταδεδομένα.
Όχι, το CCCD έχει αυστηρά καθορισμένη μορφή (uint16) και σκοπό — τη διαχείριση ειδοποιήσεων. Η εγγραφή άλλων τιμών παραβιάζει την προδιαγραφή Bluetooth και μπορεί να καταστήσει την εγγραφή μη λειτουργική. Για προσαρμοσμένα δεδομένα χρησιμοποιήστε προσαρμοσμένους περιγραφείς με 128-bit UUID.
Το User Description περιέχει ένα όνομα του χαρακτηριστικού αναγνώσιμο από τον άνθρωπο — για παράδειγμα, "Θερμοκρασία περιβλήματος" αντί για UUID 0x2A6E. Η εφαρμογή μπορεί να εμφανίζει αυτό το όνομα στη διεπαφή, κάνοντας την αλληλεπίδραση με τη συσκευή BLE κατανοητή για τον χρήστη χωρίς σκληρά κωδικοποιημένες συμβολοσειρές.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης