Characteristic هي وحدة أساسية للبيانات في Bluetooth Low Energy، يقوم الجهاز المركزي (Central) من خلالها بقراءة أو كتابة المعلومات على جهاز طرفي (Peripheral). كل Characteristic تنتمي إلى خدمة GATT محددة، ولها UUID فريد ومجموعة من الخصائص (read، write، notify، indicate) التي تحدد العمليات الممكنة. وفقًا لـ Bluetooth Core Specification 5.4 (2023)، فقد حدد Bluetooth SIG أكثر من 500 خاصية قياسية للأجهزة الطبية والرياضية والصناعية. يقوم المطورون بإنشاء خصائص مخصصة لنقل أي بيانات مستخدم، من قراءات الحساسات إلى أوامر التحكم في الجهاز.
النقاط الرئيسية
Characteristic هي سمة من سمات بروتوكول GATT تحتوي على قيمة وبيانات تعريفية. في معمارية BLE، لا تنتقل البيانات مباشرة بين الأجهزة، وإنما من خلال قراءة وكتابة قيم خصائص الخدمة. إذا كانت الخدمة مجلدًا، فإن Characteristic هي ملف داخل ذلك المجلد.
تتكون كل Characteristic من ثلاثة مكونات: الإعلان (declaration)، القيمة (value)، والواصفات (descriptors). يحتوي الإعلان على UUID للخاصية وخصائصها. القيمة هي البيانات الفعلية المنقولة بين Central و Peripheral. توفر الواصفات تكوينًا إضافيًا.
وفقًا لـ Bluetooth Core Specification 5.4 (2023)، تتم جميع عمليات تبادل البيانات في BLE من خلال العمليات على الخصائص. حتى الملفات القياسية مثل Heart Rate Profile أو Battery Service مبنية على مجموعة من الخصائص بأحجام UUID محددة مسبقًا. يضمن ذلك توافق الأجهزة من مصنعين مختلفين دون تكوين مسبق.
من المهم أن يفهم المطور: يمكن لكل Characteristic دعم مختلف توليفات الخصائص. قد تكون إحدى الخصائص للقراءة فقط، وأخرى للكتابة، وثالثة للإشعارات. يحدد الاختيار الصحيح للخصائص سيناريو الاستخدام واستهلاك الطاقة للجهاز.
الخصائص (properties) للخاصية تحدد العمليات المسموح بها. إنها قناع بايتية حيث يقوم كل بت بتمكين أو تعطيل عملية محددة. دونك الخصائص الرئيسية.
| الخاصية | البت | الوصف | الاستخدام النموذجي |
|---|---|---|---|
| Read | 0x02 | يمكن للجهاز المركزي قراءة القيمة الحالية | الحالة، مستوى البطارية، التكوين |
| Write | 0x08 | يمكن للجهاز المركزي كتابة قيمة جديدة | أوامر التحكم، الإعدادات |
| Notify | 0x10 | يرسل الجهاز الطرفي القيمة دون تأكيد | بيانات التدفق (النبض، درجة الحرارة) |
| Indicate | 0x20 | يرسل الجهاز الطرفي القيمة مع تأكيد | بيانات حرجة (تنبيهات، حالات) |
| 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 | 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: يرسل الجهاز المركزي طلبًا لقراءة قيمة الخاصية. يستجيب الجهاز الطرفي بالقيمة الحالية. العملية متزامنة وتتطلب طلبًا صريحًا من كل جانب. تستخدم للبيانات التي نادراً ما تتغير: إصدار البرنامج الثابت، الرقم التسلسلي، الإعدادات.
Write: يرسل الجهاز المركزي بيانات إلى الجهاز الطرفي. هناك وضعان: Write with Response (تأكيد من الجهاز الطرفي) و Write Without Response (بدون تأكيد). Write with Response يضمن التسليم — يرسل الجهاز الطرفي تأكيدًا بعد الكتابة. Write Without Response أسرع ولكنه لا يضمن التسليم.
Notify و Indicate: يبدأ الجهاز الطرفي إرسال البيانات إلى الجهاز المركزي. في Notify، تُرسل البيانات دون تأكيد — إذا لم يتمكن الجهاز المركزي من استلام الحزمة، تفقد. في Indicate، يرسل الجهاز المركزي تأكيدًا (على مستوى PDU)، مما يضمن التسليم. Indicate أبطأ ولكنه أكثر موثوقية. للاشتراك في الإشعارات، يكتب الجهاز المركزي القيمة 0x0001 في CCCD (واصف تكوين خاصية العميل).
MTU (Maximum Transmission Unit) يحدد الحد الأقصى لحجم حزمة بيانات BLE واحدة. افتراضيًا، يبلغ MTU 23 بايتًا، منها 3 بايتات للرأس — الحمولة (ATT payload) تساوي 20 بايتًا. هذا يكفي لمعظم بيانات الحساسات ولكنه غير كاف لنقل الملفات أو التكوينات الكبيرة.
تدعم Bluetooth Core Specification 5.4 تفاوض MTU — يمكن للجهاز المركزي والجهاز الطرفي الاتفاق على حجم حزمة أكبر يصل إلى 517 بايتًا. تعمل العملية كالتالي: يرسل الجهاز المركزي طلب MTU Exchange مع MTU المقترح، يستجيب الجهاز الطرفي بـ MTU الخاص به، ويتم استخدام القيمة الأصغر من القيمتين.
// iOS تطلب MTU عند الاتصال
// الحد الأقصى لـ MTU في iOS هو 185 بايتًا
func peripheral(
_ peripheral: CBPeripheral,
didDiscoverServices error: Error?
) {
// طلب MTU لجهاز طرفي محدد
peripheral.maximumWriteValueLength(for: .withResponse)
}
وفقًا لـ Bluetooth SIG (2023)، فإن زيادة MTU من 23 إلى 185 بايتًا تقلل النفقات الإضافية لنقل البيانات بنسبة تصل إلى 80% بفضل تقليل عدد الحزم. بالنسبة للتطبيقات التي تنقل قراءات عالية التردد (مثل تخطيط القلب أو مقياس التسارع)، فإن زيادة MTU تعد أمرًا حرجًا لاستقرار التدفق.
الأسئلة الشائعة
لا تقيد مواصفات BLE عدد الخصائص في الخدمة. في الممارسة، يتحدد الحد بواسطة الذاكرة المتاحة لخادم GATT ومتطلبات الأداء. للأجهزة المضمنة، يُوصى بـ 10–15 خاصية لكل خدمة.
Notify يرسل البيانات دون تأكيد — قد تفقد الحزمة دون إعلام المرسل. يتطلب Indicate تأكيدًا (ACK) على مستوى البروتوكول، مما يضمن التسليم. Indicate أبطأ ولكنه أكثر موثوقية. للبيانات الحرجة (تنبيهات، أوامر)، استخدم Indicate.
نعم، يمكن أن تكون للخاصية مجموعة من الخصائص. على سبيل المثال، يمكن لخاصية الإعدادات دعم Read (قراءة القيمة الحالية) و Write (تغيير الإعداد). قم بالدمج بين الخصائص حسب سيناريو الاستخدام الخاص بك.
استخدم تفاوض MTU لزيادة حجم الحزمة إلى 185–517 بايتًا. إذا كانت البيانات لا تزال أكبر، قم بتطبيق التجزئة على مستوى التطبيق: قسم البيانات إلى عدة طلبات متسلسلة مع التحكم في السلامية.
إذا كانت مهمتك مغطاة بخاصية قياسية، استخدم UUID من سجل Bluetooth SIG. يسهل ذلك الشهادة ويضمن التوافق مع النظام البيئي. انشأ UUID مخصص فقط لبيانات طرف ثالث فريدة.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.