11.5. الاتصالات¶
بمجرد أن يختار جهاز مركزي جهازًا طرفيًا من تدفق الإعلان ويرسل إليه طلب اتصال، يخرج الطرفان من وضع الإعلان / المسح إلى اتصال. تجدول الراديو الآن نشاطه على قنوات البيانات في طبقة الارتباط، متنقلًا بينها بشكل شبه عشوائي وفق التسلسل المتفق عليه وقت إنشاء الاتصال. كل ما يعلو طبقة الارتباط -- GATT والأمان وL2CAP -- يعمل فوق الاتصال الذي يُنشأ هنا.
11.5.1. حدث الاتصال¶
لا يتبادل جهازان في اتصال BLE البيانات بشكل مستمر. بل يتفقان على فترة اتصال، وعند كل فترة يوقظ الطرفان الراديو، ويتبادلان أي حزم في قائمة الانتظار، ويقرّان باستلام ما تلقياه، ثم يعودان إلى وضع السكون. كل عملية تبادل من هذه تُسمى حدث اتصال.
يكون الراديو في كل طرف مستيقظًا فقط أثناء أحداث الاتصال القصيرة، بينما يكون كل شيء آخر في وضع السكون. وقد يتجاوز الجهاز الطرفي بعض الأحداث في إطار زمن استجابة الطرفي.¶
تُتفاوض الأرقام التي تحكم ذلك وقت إنشاء الاتصال، وتفرضها طبقة الارتباط. وهي ظاهرة للتطبيق بوصفها مقابض على جانب الطلب وكقيم ناتجة يُبلَّغ عنها مرة أخرى.
فترة الاتصال. من 7.5 مللي ثانية إلى 4 ثوانٍ، بخطوات قدرها 1.25 مللي ثانية. يختار الجهاز المركزي القيمة التي يطلبها الجهاز الطرفي ما لم يكن الطلب غير معقول. تقدّم الفترات الأقصر البيانات بزمن استجابة أدنى مقابل المزيد من نشاط الراديو؛ أما الأطول فتوفّر الطاقة لكنها تجعل كل رحلة ذهاب وإياب أبطأ.
زمن استجابة الطرفي. عدد صحيح غير سالب N. يُسمح للجهاز الطرفي بتجاوز ما يصل إلى N من أحداث الاتصال عندما لا يكون لديه ما يرسله، فيعود إلى السكون بدلًا من إيقاظ الراديو لتبادل فارغ. مفيد للمستشعرات التي تستيقظ لتبلّغ مرة كل ثانية لكنها تريد فترة اتصال سريعة الاستجابة للرسالة الفورية النادرة.
مهلة الإشراف. من 100 مللي ثانية إلى 32 ثانية. إذا لم يسمع أي من الطرفين شيئًا من الآخر طوال هذه المدة، يُعلَن فقدان الارتباط ويعود الطرفان إلى الإعلان / المسح. يجب أن تكون المهلة أطول من
connection_interval * (1 + peripheral_latency)-- وترفض طبقة الارتباط القيم التي تخالف ذلك.
تأخذ aioble.Device.connect() المعاملين min_conn_interval_us وmax_conn_interval_us كي يتمكن الجهاز المركزي من طلب نطاق معيّن؛ ويمكن قراءة القيمة الفعلية التي استقر عليها الراديو من خلال تكوين طبقة الارتباط بعد قيام الاتصال.
11.5.2. ما الذي يعنيه "المركزي" و"الطرفي" داخل اتصال¶
تظل الأدوار التي تُحدَّد وقت الإعلان قائمة بعد قيام الاتصال:
يقود الجهاز المركزي التوقيت -- فهو يملك الجانب الرئيسي من تسلسل التنقل ومن أحداث الاتصال.
أما الجهاز الطرفي فهو تفاعلي. يمكنه طلب تغيير معلمات الاتصال (فترة أبطأ لتوفير الطاقة مثلًا) لكن الجهاز المركزي هو من يقرر القبول من عدمه.
الأدوار مستقلة عن من يستضيف قاعدة بيانات GATT، وهذا محور منفصل. وفقًا للعُرف، يكون الجهاز الطرفي أيضًا خادم GATT ويكون الجهاز المركزي عميل GATT، لكن BLE يتيح لأي من الطرفين استضافة خدمات GATT. وتتبع الكاميرات العُرف دائمًا تقريبًا: طرفي + خادم لتطبيقات "الكاميرا تنشر البيانات"، ومركزي + عميل لتطبيقات "الكاميرا تقرأ من مستشعر".
11.5.3. وحدة الإرسال القصوى (MTU)¶
تحمل طبقة الارتباط حزمًا قصيرة افتراضيًا -- 27 بايتًا من الحمولة، منها 23 فقط متاحة لـ GATT. وهذا يكفي لقراءة صغيرة أو أمر قصير لكنه ضئيل أمام أي شيء متعدد البايتات. يمكن للطرفين التفاوض على رفع هذا الحد حتى الحد الذي يدعمه البرنامج الثابت للراديو (عادةً بضع مئات من البايتات في المتحكمات الحديثة).
تقود واجهة aioble التفاوض عبر aioble.DeviceConnection.exchange_mtu() وتصبح النتيجة متاحة في السمة mtu. تعني قيم MTU الأكبر رحلات ذهاب وإياب أقل لأي قيمة أكبر من نحو 20 بايتًا، مقابل تكلفة طفيفة في ذاكرة المخزن المؤقت.
11.5.4. العمر¶
يستمر الاتصال إلى أن يحدث أحد ما يلي:
يستدعي أحد الطرفين
disconnect()،أو تنطلق مهلة الإشراف (خروج عن النطاق، أو إيقاف الراديو، أو تعطّل النظير)،
أو يقع فشل صريح في طبقة الارتباط (عدم تطابق التشفير، رفض الاقتران).
عندما ينقطع الاتصال، فإن كل عملية GATT في قائمة الانتظار أو قيد التنفيذ عليه تثير aioble.DeviceDisconnectedError، وأي كتل async with connection يكون التطبيق داخلها تخرج بشكل نظيف. يستجيب الجهاز الطرفي عادةً بالعودة إلى aioble.advertise() وانتظار الجهاز المركزي التالي؛ بينما يستجيب الجهاز المركزي إما بالمسح مجددًا أو بإظهار قطع الاتصال للتطبيق.
العمر هو أحد أسباب فائدة aioble. فأي واجهة BLE متزامنة سيكون عليها كشف دوال رد نداء لقطع الاتصال وأقنعة الأحداث؛ أما نسخة asyncio فتحوّل عمليات قطع الاتصال إلى استثناءات داخل الكوروتين الذي كان ينتظر العملية، وهو ما بُنيت من أجله آلية تنظيف async with.