تصميم BLE GATT: معرّفات UUID وتنسيقات البيانات والإشعارات وتوافق الإصدارات
قد ينجح اتصال BLE بينما يفشل تكامل المنتج. فقد يكتشف التطبيق خاصية غير المقصودة، أو يفك ترميز قياس ذي إشارة بطريقة خاطئة، أو يتوقف عن استقبال التحديثات بعد ترقية البرنامج الثابت. تحتاج واجهة GATT القابلة للاستخدام إلى اتفاق مكتوب يحدد الهوية والبايتات ومعنى التسليم والأمان وتغييرات الإصدارات. يوضح هذا الدليل كيفية إعداد ذلك الاتفاق لواجهة مخصصة للاستشعار والتحكم.
تعريف الواجهة قبل تطوير التطبيق
سجّل UUID لكل خدمة وخاصية، وسماتها وأذوناتها وطولها الأقصى واستجابات الخطأ. أعد استخدام خدمة من Bluetooth SIG فقط عندما يناسب معناها وتنسيقها المحددان المنتج. وللدلالات الخاصة، عيّن UUID ثابتًا بطول 128 بت بدلًا من اختراع UUID قصير غير مخصص. تقصر مواصفة أنواع البيانات لدى SIG استخدام معرّفات الخدمات القصيرة على القيم التي خصصتها SIG.
احتفظ بمعرّفات UUID في سجل واحد خاضع للتحكم في الإصدارات، تتشاركه البرمجيات الثابتة والتطبيق وأدوات الاختبار. لا تستخدم اسم الجهاز وحده لتحديد هويته؛ فقد يتغير الاسم وقد تعلن وحدات متعددة الاسم نفسه. كذلك لا تثبّت مقابض السمات داخل الشيفرة عبر إصدارات البرنامج الثابت. اكتشف الخدمة، واختر النسخة المطلوبة منها، ثم حدّد الخصائص داخل تلك الخدمة.
| الخاصية | العملية المقترحة | الاتفاق المطلوب توثيقه |
|---|---|---|
| معلومات البروتوكول | قراءة | الإصدار الرئيسي والفرعي للتنسيق، والقدرات، وأقصى إطار للتطبيق |
| تدفق القياسات | إشعار | الوحدات وعدّاد التسلسل والمرجع الزمني وسياسة الفيض |
| التهيئة | قراءة وكتابة مع استجابة | المجالات والتفويض والتحقق ووقت الحفظ الدائم |
| نتيجة الأمر | Indication أو إشعار مع إقرار على مستوى التطبيق | معرّف المعاملة ورمز النتيجة ومعنى الاكتمال |
تحديد تنسيق بايتات قابل للاختبار
المثال التالي إطار قياس توضيحي بطول 12 بايت، وليس ملف تعريف قياسيًا للبلوتوث. جميع الحقول متعددة البايتات تستخدم ترتيب Little Endian. وتمثيل درجة الحرارة بنقطة ثابتة يجنّب الاعتماد على طريقة تسلسل الأعداد العائمة في لغة معينة. وتُقرأ معلومات البروتوكول بشكل منفصل لمعرفة الإصدار الفرعي والقدرات المدعومة.
| الإزاحة | الحقل | التعريف |
|---|---|---|
| 0 | major | إصدار رئيسي للتنسيق من 8 بتات دون إشارة، يبدأ بالقيمة 1 |
| 1 | flags | البت 0 يعني أن الحرارة صالحة؛ البتات الأخرى محجوزة وتساوي صفرًا |
| 2–3 | sequence | عداد من 16 بت دون إشارة، يلتف بترديد 65536 |
| 4–7 | uptime_ms | وقت العينة منذ الإقلاع من 32 بت دون إشارة؛ يلتف بترديد 2³² |
| 8–9 | temperature | 16 بت بإشارة، و0.01 °C لكل وحدة؛ يُتجاهل عند عدم الصلاحية |
| 10–11 | battery_mV | ميليفولت من 16 بت دون إشارة؛ 65535 تعني غير متاح |
في هذا المثال، يُصفّر رقم التسلسل وزمن التشغيل عند إعادة التشغيل؛ ويتيح معرّف إقلاع يُقرأ عند إعداد الجلسة التمييز بين إعادة التشغيل والتفاف العداد. يجب أن تتضمن متجهات الاختبار المرجعية المشتركة درجات الحرارة السالبة والأعلام غير الصالحة والإطارات المبتورة والتفاف العدادات. يوضح محلل Python التالي التحقق الصريح:
import struct
def decode_v1(payload):
if len(payload) != 12:
raise ValueError("expected 12 bytes")
major, flags, seq, ms, temp, mv = struct.unpack("<BBHIhH", payload)
if major != 1 or flags & 0xFE:
raise ValueError("unsupported schema or flags")
return {
"sequence": seq, "uptime_ms": ms,
"temperature_C": temp / 100 if flags & 1 else None,
"battery_mV": None if mv == 65535 else mv,
}
متجه مرجعي هو 01 01 2A 00 E8 03 00 00 2E FB E4 0C: إصدار رئيسي 1، ودرجة حرارة صالحة، وتسلسل 42، وزمن تشغيل 1000 ms، وحرارة −12.34 °C، وجهد 3300 mV. فك ترميزه على الجانبين قبل توصيل الأجهزة الفعلية.
يعني التحقق الصارم من البتات المحجوزة أن هذا المحلل لا يستطيع قبول معانٍ جديدة للأعلام بصمت. احتفظ بإطار v1، أو تفاوض على امتداد مدعوم، أو أدخل تنسيقًا بإصدار رئيسي جديد. ولا تكون إضافة بايتات في النهاية متوافقة مع الإصدارات السابقة إلا إذا صُمم المحلل الموجود صراحة لقبولها.

الفصل بين الاشتراك والتسليم الموثوق على مستوى التطبيق
الإشعارات Notifications لا تتضمن تأكيدًا على مستوى ATT، بينما تتضمنه رسائل Indications. ولا يثبت أي منهما أن القياس وصل إلى قاعدة بيانات سحابية أو أن محركًا أكمل أمرًا. لرابط BLE المتصل آليات إعادة إرسال خاصة به، لكن انقطاع الاتصال وامتلاء الطوابير البرمجية وإعادة تشغيل التطبيق تظل بحاجة إلى سياسة شاملة من طرف إلى طرف. استخدم أرقام التسلسل لاكتشاف العينات المفقودة ومعرّفات المعاملات لمطابقة نتائج الأوامر. تحدد مواصفة ATT الإجراءات الأساسية.
اشترك عبر واجهة برمجة المنصة وتحقق من اكتمال العملية قبل إعلان جاهزية التدفق. على مستوى GATT، يفعّل واصف Client Characteristic Configuration، ذي UUID يساوي 0x2902، الإشعارات بالقيمة 0x0001 ورسائل Indications بالقيمة 0x0002. حالة الاشتراك مستقلة لكل عميل. وتختلف استمرارية الحالة بين الأجهزة التي تحتفظ بعلاقة ربط أمني والأجهزة غير المرتبطة؛ لذلك يجب أن يعيد منطق الاتصال دالة الاستدعاء المحلية ويتحقق من نشاط الاشتراك. انظر مواصفة GATT.
ضع حدًا لحجم الطابور ووثّق الاستجابة للحمل الزائد: حذف أقدم العينات، أو الاحتفاظ بأحدث قيمة فقط، أو إيقاف الالتقاط مؤقتًا إذا سمح المنتج بذلك. أتح عدادًا للعينات المحذوفة. وبالنسبة للأوامر، ميّز بين «مقبول» و«قيد التنفيذ» و«مكتمل». يجب ألا يؤدي تكرار المعاملة نفسها بعد انقطاع الاتصال إلى تشغيل المشغّل مرتين عن طريق الخطأ.
توضيح MTU والاختلافات بين المنصات
في إشعار تقليدي ذي مقبض واحد، يجب أن يتسع ATT_MTU ناقص 3 بايتات للقيمة؛ ويوجد أيضًا حد مستقل لقيمة السمة يبلغ 512 بايت. لذلك تتيح قيمة LE ATT MTU الافتراضية البالغة 23 مساحة 20 بايت لهذا الإشعار. تتطلب القيم الأكبر مخطط تجزئة متفقًا عليه في التطبيق أو إجراء نقل آخر مناسبًا. زيادة MTU وحدها لا تختار PHY أسرع ولا تزيد طول بيانات طبقة الربط. انظر تنسيقات حزم ATT.
ابتداءً من Android 14، يدفع أول طلب MTU من عميل GATT المكدس إلى طلب 517، وتُتجاهل الطلبات اللاحقة. استخدم نتيجة التفاوض الواردة في الاستدعاء الراجع لتحديد طول الإطارات، ولا تستخدم الرقم المطلوب. على منصات Apple، استعلم عن maximumWriteValueLength(for:) لنوع الكتابة المختار بدلًا من نسخ افتراضات Android. راجع مرجع BluetoothGatt في Android ومرجع طول الكتابة لدى Apple.
نفّذ خطوات الإعداد غير المتزامنة بالتتابع، ما لم يدعم المكدس المختار نمط التزامن المطلوب صراحة. غالبًا يعني نجاح الاستدعاء أن الطلب أُضيف إلى الطابور فقط؛ أما النتيجة فتصل في الاستدعاء الراجع. سجّل معًا MTU المتفاوض عليها وUUID الخاصية المختارة وحالة الأمان ونتيجة الاشتراك وإصدار المحلل.
تخطيط التوافق بين إصدارات البرنامج الثابت والتطبيق
إصدار تنسيق البروتوكول وإصدار البرنامج الثابت وبنية قاعدة GATT مسائل منفصلة. حافظ على معاني الحقول الموجودة داخل التنسيق المدعوم. أعلن القدرات بدلًا من إجبار العملاء على استنتاج الوظائف من سلسلة إصدار البرنامج الثابت. ارفض الإصدار الرئيسي غير المدعوم مع تشخيص مفيد قبل إرسال أوامر التحكم.
إذا غيّر التحديث قاعدة الخدمات، فنفّذ سلوك Service Changed والتخزين المؤقت المنطبق. ويدعم Database Hash اكتشاف التغييرات حيث يتوفر. لا تترجم هذه الآليات تنسيقات حمولة التطبيق التي تغيرت. اختبر الترقية والتراجع باستخدام عملاء مرتبطين سابقًا وباستخدام تثبيتات جديدة أيضًا. توضح قواعد التخزين المؤقت في GATT المتطلبات على مستوى قاعدة البيانات.
استخدام مصفوفة إصدار تكشف الأعطال
| الاختبار | العطل المراد إحداثه | الدليل المطلوب الاحتفاظ به |
|---|---|---|
| تطبيق قديم مع برنامج ثابت جديد؛ وتطبيق جديد مع برنامج ثابت قديم | إصدار رئيسي غير معروف أو حقل اختياري مفقود أو بنية متغيرة | قراءة القدرات وقبول أو رفض صريح |
| MTU تساوي 23 وMTU أكبر متفاوض عليها | حمولة زائدة أو طول جزء خاطئ أو بتر | الطول المستلم والمتجه المرجعي بعد فك الترميز |
| انقطاع الاتصال أثناء الأمر والاشتراك | تشغيل مكرر أو تدفق صامت | معرّف المعاملة واكتمال الاشتراك وأول عينة صالحة |
| ترقية وتراجع مع الاحتفاظ بعلاقات الربط الأمني | مقابض قديمة مخزنة مؤقتًا أو الوصول إلى خاصية خاطئة | انتقال الاكتشاف والذاكرة المؤقتة وربط UUID |
| مستهلك بطيء وطابور ممتلئ | نمو الذاكرة أو فقد غير مفسر | أعلى إشغال للطابور وإحصاء الحذف |
| عميل غير موثّق أو غير مخوّل | قبول التهيئة عند مستوى أمان غير مناسب | الخطأ المتوقع وبقاء التهيئة دون تغيير |
عندما لا يصدر التدفق بيانات، افحص سمة Notify ثم اكتمال الاشتراك ثم الأذونات ثم نشاط مصدر البيانات. وعندما تبدو القيم غير معقولة، قارن البايتات الخام بقواعد الإشارة والتحجيم وترتيب البايتات قبل تعديل معلمات الراديو. وإذا كان الفشل يقتصر على الأجهزة التي تمت ترقيتها، فابدأ بفحص ذاكرة قاعدة البيانات المؤقتة والتفاوض على التنسيق.
إعداد ملف تكامل قابل للمراجعة
جهّز سجل UUID ومواصفة الحزم ومتجهات الاختبار المرجعية وقائمة الهواتف وأنظمة التشغيل المدعومة ومصفوفة التوافق لمراجعة البرنامج الثابت. تمثل خدمة تشخيص البرامج الثابتة وBSP من Obeita نقطة بداية مناسبة. وتوضح حالة تكامل وحدة WS63 اللاسلكية المُسلَّمة سياق تحديد نطاق العتاد ونمط الراديو؛ لكنها لا تثبت تنفيذ اتفاق GATT التوضيحي هذا أو التحقق منه على تلك الوحدة.