بازسازی RIL

‫Android 7.0 «لایه میانای رادیویی» (RIL) را بااستفاده از مجموعه‌ای از ویژگی‌ها برای بهبود عملکرد RIL بازسازی کرد. برای پیاده‌سازی این ویژگی‌ها، که اختیاری اما توصیه شده است، تغییرات کد شریک لازم است. تغییرات بازسازی با نسخه‌های قدیمی سازگار است، بنابراین پیاده‌سازی‌های قبلی ویژگی‌های بازسازی‌شده همچنان کار می‌کنند.

بازسازی RIL شامل بهبودهای زیر است:

  • کدهای خطای RIL. علاوه‌بر کد GENERIC_FAILURE موجود، کدهای خطای خاصی را فعال می‌کند. این کار با ارائه اطلاعات دقیق‌تر درباره علت خطاها به عیب‌یابی خطا کمک می‌کند.
  • نسخه‌بندی RIL. اطلاعات نسخه دقیق‌تر و پیکربندی آسان‌تری ارائه می‌دهد.
  • ارتباط RIL بااستفاده از wakelocks. عملکرد باتری دستگاه را بهبود می‌بخشد.

می‌توانید هریک یا همه بهبودهای بالا را پیاده‌سازی کنید. برای جزئیات بیشتر، به نظرات کد درباره نسخه‌بندی RIL در https://android.googlesource.com/platform/hardware/ril/+/android17-release/include/telephony/ril.h مراجعه کنید.

پیاده‌سازی کدهای خطای RIL بهبودیافته

تقریباً همه تماس‌های درخواست RIL می‌توانند کد خطای GENERIC_FAILURE را در پاسخ به خطا برگردانند. این مشکل در همه پاسخ‌های درخواست‌شده که توسط OEM برگردانده می‌شوند وجود دارد، که می‌تواند اشکال‌زدایی مشکل را از گزارش اشکال دشوار کند اگر همان کد خطای GENERIC_FAILURE توسط تماس‌های RIL به دلایل مختلف برگردانده شود. ممکن است زمان قابل‌توجهی طول بکشد تا فروشندگان حتی تشخیص دهند کدام بخش از کد می‌تواند کد GENERIC_FAILURE را برگرداند.

در Android نسخه ۷.x و بالاتر، سازندگان تجهیزات اصلی می‌توانند مقدار کد خطای متمایزی را که با هر خطای مختلفی که درحال‌حاضر به‌عنوان GENERIC_FAILURE دسته‌بندی می‌شود مرتبط است برگردانند. تولیدکنندگان اصلی سخت‌افزار که نمی‌خواهند کدهای خطای سفارشی‌شان را به‌طور عمومی فاش کنند می‌توانند خطاها را به‌صورت مجموعه‌ای متمایز از اعداد صحیح (مثل ۱ تا x) که به‌صورت OEM_ERROR_1 تا OEM_ERROR_X نگاشت شده‌اند برگردانند. فروشندگان باید مطمئن شوند که هریک از این کدهای خطای پوشانده‌شده به یک دلیل خطای منحصربه‌فرد در کد نگاشت می‌شود. استفاده از کدهای خطای خاص می‌تواند اشکال‌زدایی RIL را در هر زمانی که خطاهای عمومی توسط سازنده تجهیزات اصلی برگردانده می‌شود تسریع کند، زیرا اغلب شناسایی علت دقیق کد خطای GENERIC_FAILURE زمان زیادی می‌برد (و گاهی اوقات تشخیص آن غیرممکن است).

علاوه‌براین، ril.h کدهای خطای بیشتری برای شمارش‌ها RIL_LastCallFailCause و RIL_DataCallFailCause اضافه می‌کند تا کد فروشنده بتواند از برگرداندن خطاهای عمومی مثل CALL_FAIL_ERROR_UNSPECIFIED و PDP_FAIL_ERROR_UNSPECIFIED اجتناب کند.

اعتبارسنجی کدهای خطای RIL بهبودیافته

پس‌از افزودن کدهای خطای جدید برای جایگزینی کد GENERIC_FAILURE، درستی‌سنجی کنید که کدهای خطای جدید به‌جای GENERIC_FAILURE توسط تماس RIL برگردانده شوند.

پیاده‌سازی نسخه‌بندی بهبودیافته RIL

نسخه‌بندی RIL در نسخه‌های قدیمی‌تر Android مشکل‌ساز بود: خود نسخه دقیق نبود، سازوکار گزارش نسخه RIL نامشخص بود (که باعث می‌شد برخی‌از فروشندگان نسخه نادرستی را گزارش کنند)، و راهکار تخمینی نسخه مستعد خطا بود.

در Android 7.x و بالاتر، ril.h همه مقادیر نسخه RIL را مستند می‌کند، نسخه RIL مربوطه را شرح می‌دهد، و همه تغییرات آن نسخه را فهرست می‌کند. هنگام ایجاد تغییراتی که با نسخه RIL مطابقت دارد، فروشندگان باید نسخه خود را در کد به‌روز کنند و آن نسخه را در RIL_REGISTER برگردانند.

اعتبارسنجی نسخه‌بندی RIL بهبودیافته

تأیید کنید که نسخه RIL مربوط به کد RIL شما درطول RIL_REGISTER (به‌جای RIL_VERSION تعریف‌شده در ril.h) برگردانده می‌شود.

پیاده‌سازی ارتباط RIL بااستفاده از wakelocks

قفل‌های بیداری زمان‌دار به‌صورت غیردقیق در ارتباط RIL استفاده می‌شوند که بر عملکرد باتری تأثیر منفی می‌گذارد. در Android نسخه ۷.x و بالاتر، می‌توانید با طبقه‌بندی درخواست‌های RIL و به‌روزرسانی کد برای مدیریت متفاوت wakelocks برای انواع مختلف درخواست، عملکرد را بهبود دهید.

طبقه‌بندی درخواست‌های RIL

درخواست‌های RIL می‌تواند هم درخواست‌شده و هم درخواست‌نشده باشد. فروشندگان باید درخواست‌های خواسته را به‌عنوان یکی از موارد زیر طبقه‌بندی کنند:

  • هم‌زمان. درخواست‌هایی که زمان زیادی برای پاسخ دادن نیاز ندارند. برای مثال، RIL_REQUEST_GET_SIM_STATUS.
  • ناهمزمان. درخواست‌هایی که زمان قابل‌توجهی برای پاسخ دادن نیاز دارند. برای مثال، RIL_REQUEST_QUERY_AVAILABLE_NETWORKS.

درخواست‌های RIL ناهمزمان و درخواست‌شده ممکن است زمان قابل‌توجهی طول بکشند. پس‌از دریافت تأییدیه از کد فروشنده، RIL Java قفل بیداری را آزاد می‌کند که ممکن است باعث شود پردازنده برنامه از حالت آماده به‌کار به حالت تعلیق برود. وقتی پاسخ از کد فروشنده دردسترس قرار می‌گیرد، RIL Java (پردازنده برنامه) دوباره wakelock را به‌دست می‌آورد، پاسخ را پردازش می‌کند، سپس به حالت آماده به کار برمی‌گردد. چنین تغییری از حالت غیرفعال به تعلیق و سپس به غیرفعال می‌تواند انرژی زیادی مصرف کند.

اگر زمان پاسخ‌دهی کافی نباشد، نگه داشتن «قفل بیداری» و ماندن در حالت آماده‌به‌کار برای کل زمان لازم برای پاسخ‌دهی می‌تواند نسبت‌به رفتن به حالت تعلیق با رها کردن «قفل بیداری» و بیدار شدن هنگام رسیدن پاسخ، مصرف انرژی بهینه‌تری داشته باشد. فروشندگان باید از اندازه‌گیری‌های توان مختص پلاتفرم برای تعیین مقدار آستانه زمان T استفاده کنند، زمانی که توان مصرف‌شده با ماندن در حالت آماده به کار برای کل زمان T بیشتر از توان مصرف‌شده با رفتن از حالت آماده به کار به حالت تعلیق و دوباره به حالت آماده به کار در همان زمان T است. وقتی زمان T مشخص باشد، فرمان‌های RIL که بیشتر از زمان T طول می‌کشند می‌توانند به‌عنوان ناهم‌زمان طبقه‌بندی شوند و فرمان‌های باقی‌مانده به‌عنوان هم‌زمان طبقه‌بندی شوند.

سناریوهای ارتباطی RIL

نمودارهای زیر سناریوهای رایج ارتباط RIL را نشان می‌دهند و راه‌حل‌هایی برای اصلاح کد به‌منظور مدیریت درخواست‌های RIL خواسته و ناخواسته ارائه می‌دهند.

توجه: برای جزئیات پیاده‌سازی توابع استفاده‌شده در نمودارهای زیر، به روش‌های acquireWakeLock()، decrementWakeLock()، و clearWakeLock( در ril.cpp مراجعه کنید.

سناریو: درخواست RIL و پاسخ ناهم‌زمان درخواست‌شده

در این سناریو، اگر انتظار می‌رود پاسخ درخواست RIL زمان قابل‌توجهی طول بکشد (یعنی پاسخ به RIL_REQUEST_GET_AVAILABLE_NETWORKS)، wakelock برای مدت طولانی در سمت پردازنده برنامه نگه داشته می‌شود. مشکلات مودم نیز می‌تواند باعث انتظار طولانی شود.

شکل ۱. پاسخ ناهمگام درخواست RIL.

راهکار ۱: مودم قفل بیدارباش را برای درخواست RIL و پاسخ ناهمگام نگه می‌دارد.

شکل ۲. مودم قفل بیداری را نگه داشته است.
  1. درخواست RIL ارسال می‌شود و مودم برای پردازش آن درخواست، قفل بیداری دریافت می‌کند.
  2. مودم تأییدیه‌ای ارسال می‌کند که باعث می‌شود طرف Java شمارنده قفل بیداری را کاهش دهد و وقتی مقدار شمارنده ۰ شد آن را آزاد کند.

    توجه: مدت زمان وقفه wakelock برای توالی request-ack کمتر از مدت زمان وقفه فعلی خواهد بود زیرا ack باید نسبتاً سریع دریافت شود.

  3. پس‌از پردازش درخواست، مودم وقفه‌ای به کد فروشنده ارسال می‌کند که wakelock را دریافت می‌کند و پاسخی به ril.cpp ارسال می‌کند که به‌نوبه خود wakelock را دریافت می‌کند و پاسخی به طرف Java ارسال می‌کند.
  4. وقتی پاسخ به طرف Java می‌رسد، wakelock دریافت می‌شود و پاسخی به تماس‌گیرنده برگردانده می‌شود.
  5. پس‌از اینکه پاسخ توسط همه واحدها پردازش شد، تأییدیه (ازطریق سوکت) به ril.cpp ارسال می‌شود، که سپس قفل بیداری دریافت‌شده در مرحله ۳ را آزاد می‌کند.

راه‌حل ۲: مودم قفل بیداری را نگه نمی‌دارد و پاسخ سریع است (درخواست و پاسخ هم‌زمان RIL). رفتار همگام درمقابل ناهمگام برای یک فرمان RIL خاص به‌صورت کدبندی‌شده است و براساس هر تماس تصمیم‌گیری می‌شود.

شکل ۳. مودم Wakelock را نگه نداشته است.
  1. درخواست RIL با فراخوانی acquireWakeLock() در سمت Java ارسال می‌شود.
  2. کد فروشنده نیازی به دریافت «قفل بیداری» ندارد و می‌تواند درخواست را پردازش کند و سریع پاسخ دهد.
  3. وقتی پاسخ در سمت Java دریافت می‌شود، decrementWakeLock() فراخوانده می‌شود که شمارنده wakelock را کاهش می‌دهد و اگر مقدار شمارنده ۰ باشد، wakelock را آزاد می‌کند.

سناریو: پاسخ ناخواسته RIL

در این سناریو، پاسخ‌های ناخواسته RIL دارای پرچم نوع wakelock در هستند که نشان می‌دهد آیا باید برای پاسخ فروشنده wakelock دریافت شود یا نه. اگر پرچم تنظیم شده باشد، یک قفل بیداری زمان‌دار تنظیم می‌شود و پاسخ ازطریق یک سوکت به سمت Java ارسال می‌شود. وقتی زمان‌سنج منقضی می‌شود، قفل بیداری آزاد می‌شود. زمان بیداری ممکن است برای پاسخ‌های ناخواسته RIL مختلف خیلی طولانی یا خیلی کوتاه باشد.

شکل ۴. پاسخ ناخواسته RIL.

راه‌حل: به‌جای نگه داشتن قفل بیداری زمان‌بندی‌شده در سمت بومی هنگام ارسال پاسخ ناخواسته، تأییدیه‌ای از کد Java به سمت بومی (ril.cpp) ارسال می‌شود.

شکل ۵. استفاده از ack به‌جای wakelock زمان‌بندی‌شده.

تأیید درستی قفل‌های بیداری بازطراحی‌شده

تأیید کنید که تماس‌های RIL به‌عنوان هم‌زمان یا ناهم‌زمان شناسایی می‌شوند. ازآنجایی‌که مصرف شارژ باتری می‌تواند به سخت‌افزار/پلاتفرم وابسته باشد، فروشندگان باید آزمایش‌های داخلی انجام دهند تا ببینند آیا استفاده از معناشناسی جدید قفل بیدارباش برای تماس‌های ناهمگام منجر به صرفه‌جویی در مصرف شارژ باتری می‌شود یا نه.