आरआईएल रीफ़ैक्टरिंग

Android 7.0 में, रेडियो इंटरफ़ेस लेयर (आरआईएल) को फिर से तैयार किया गया है. इसके लिए, आरआईएल की सुविधाओं को बेहतर बनाने के लिए, कई सुविधाओं का इस्तेमाल किया गया है. इन सुविधाओं को लागू करने के लिए, पार्टनर कोड में बदलाव करना ज़रूरी है. हालांकि, ऐसा करना ज़रूरी नहीं है, लेकिन हमारा सुझाव है कि आप ऐसा करें. रीफ़ैक्टर करने से जुड़े बदलाव, पुराने सिस्टम के साथ काम करते हैं. इसलिए, रीफ़ैक्टर की गई सुविधाओं के पहले से लागू होने वाले वर्शन काम करते रहेंगे.

आरआईएल रीफ़ैक्टरिंग में ये सुधार शामिल हैं:

  • आरआईएल के गड़बड़ी कोड. मौजूदा GENERIC_FAILURE कोड के अलावा, गड़बड़ी के खास कोड चालू करता है. इससे गड़बड़ी की वजह के बारे में ज़्यादा जानकारी मिलती है. इससे गड़बड़ी को हल करने में मदद मिलती है.
  • आरआईएल वर्शन. इससे वर्शन की जानकारी को कॉन्फ़िगर करना ज़्यादा आसान और सटीक होता है.
  • वेकलॉक का इस्तेमाल करके RIL कम्यूनिकेशन. डिवाइस की बैटरी की परफ़ॉर्मेंस को बेहतर बनाता है.

ऊपर बताए गए सुधारों में से किसी एक या सभी को लागू किया जा सकता है. ज़्यादा जानकारी के लिए, https://android.googlesource.com/platform/hardware/ril/+/android16-release/include/telephony/ril.h में RIL वर्शन पर कोड की टिप्पणियां देखें.

बेहतर RIL गड़बड़ी कोड लागू करना

RIL के ज़्यादातर अनुरोध कॉल, गड़बड़ी के जवाब में GENERIC_FAILURE गड़बड़ी कोड दिखा सकते हैं. यह समस्या, OEMs से मांगे गए सभी जवाबों से जुड़ी है. अगर RIL कॉल से अलग-अलग वजहों से एक ही GENERIC_FAILURE गड़बड़ी कोड दिखता है, तो गड़बड़ी की रिपोर्ट से समस्या को डीबग करना मुश्किल हो सकता है. वेंडर को यह पता लगाने में भी काफ़ी समय लग सकता है कि कोड के किस हिस्से से GENERIC_FAILURE कोड मिल सकता है.

Android 7.x और उसके बाद के वर्शन में, OEM हर अलग गड़बड़ी के लिए, गड़बड़ी कोड की एक अलग वैल्यू दिखा सकते हैं. फ़िलहाल, इन गड़बड़ियों को GENERIC_FAILURE के तौर पर कैटगरी में रखा गया है. जो OEM सार्वजनिक तौर पर अपने पसंद के मुताबिक बनाए गए गड़बड़ी के कोड नहीं दिखाना चाहते वे गड़बड़ियों को पूर्णांक के अलग-अलग सेट (जैसे, 1 से x) के तौर पर दिखा सकते हैं. ये सेट, OEM_ERROR_1 से OEM_ERROR_X के तौर पर मैप किए जाते हैं. वेंडर को यह पक्का करना चाहिए कि गड़बड़ी का जो कोड दिखाया गया है वह कोड में गड़बड़ी की किसी खास वजह से मैप हो. गड़बड़ी के खास कोड का इस्तेमाल करने से, OEM से सामान्य गड़बड़ियां मिलने पर आरआईएल डीबगिंग की प्रोसेस तेज़ हो सकती है. ऐसा इसलिए, क्योंकि GENERIC_FAILURE गड़बड़ी कोड की सही वजह का पता लगाने में अक्सर काफ़ी समय लग सकता है. साथ ही, कभी-कभी यह पता लगाना असंभव भी हो सकता है.

इसके अलावा, ril.h, सूची के RIL_LastCallFailCause और RIL_DataCallFailCause के लिए गड़बड़ी के ज़्यादा कोड जोड़ता है, ताकि वेंडर कोड, CALL_FAIL_ERROR_UNSPECIFIED और PDP_FAIL_ERROR_UNSPECIFIED जैसी सामान्य गड़बड़ियां दिखाने से बच सके.

बेहतर आरआईएल गड़बड़ी कोड की पुष्टि करना

GENERIC_FAILURE कोड को बदलने के लिए नए गड़बड़ी कोड जोड़ने के बाद, पुष्टि करें कि RIL कॉल से GENERIC_FAILURE के बजाय नए गड़बड़ी कोड दिखाए जाएं.

बेहतर आरआईएल वर्शन लागू करना

Android के पुराने वर्शन में आरआईएल वर्शन की जानकारी देने में समस्याएं आती थीं: वर्शन की जानकारी सटीक नहीं थी, आरआईएल वर्शन की जानकारी देने का तरीका साफ़ नहीं था (इस वजह से कुछ वेंडर गलत वर्शन की जानकारी देते थे), और वर्शन का अनुमान लगाने के लिए इस्तेमाल किए जाने वाले तरीके से भी सटीक जानकारी नहीं मिलती थी.

Android 7.x और उसके बाद के वर्शन में, ril.h सभी आरआईएल वर्शन की वैल्यू को दस्तावेज़ में सेव करता है. साथ ही, उससे जुड़े आरआईएल वर्शन के बारे में बताता है और उस वर्शन में किए गए सभी बदलावों की सूची बनाता है. RIL वर्शन से जुड़े बदलाव करते समय, वेंडर को कोड में अपना वर्शन अपडेट करना होगा और उस वर्शन को RIL_REGISTER में वापस लौटाना होगा.

बेहतर आरआईएल वर्शन की पुष्टि करना

पुष्टि करें कि ril.h में बताए गए RIL_VERSION के बजाय, RIL_REGISTER के दौरान आपके आरआईएल कोड से जुड़ा आरआईएल वर्शन दिखाया गया हो.

वेकलॉक का इस्तेमाल करके आरआईएल कम्यूनिकेशन लागू करना

RIL कम्यूनिकेशन में, तय समय के लिए वेकलॉक का इस्तेमाल गलत तरीके से किया जाता है. इससे बैटरी की परफ़ॉर्मेंस पर बुरा असर पड़ता है. Android 7.x और इसके बाद के वर्शन में, RIL अनुरोधों को अलग-अलग कैटगरी में बांटकर और कोड को अपडेट करके, परफ़ॉर्मेंस को बेहतर बनाया जा सकता है. इससे, अलग-अलग तरह के अनुरोधों के लिए, वेकलॉक को अलग-अलग तरीके से मैनेज किया जा सकता है.

आरआईएल के अनुरोधों को अलग-अलग कैटगरी में बांटना

आरआईएल के अनुरोध, अनुरोध किए गए या बिना अनुरोध किए भेजे गए हो सकते हैं. वेंडर को अनुरोधों को इनमें से किसी एक कैटगरी में बांटना चाहिए:

  • सिंक्रोनस. ऐसे अनुरोध जिनका जवाब देने में ज़्यादा समय नहीं लगता. उदाहरण के लिए, RIL_REQUEST_GET_SIM_STATUS.
  • एसिंक्रोनस. ऐसे अनुरोध जिनका जवाब देने में काफ़ी समय लगता है. उदाहरण के लिए, RIL_REQUEST_QUERY_AVAILABLE_NETWORKS.

एसिंक्रोनस तरीके से किए गए RIL अनुरोधों को पूरा होने में काफ़ी समय लग सकता है. वेंडर कोड से पुष्टि मिलने के बाद, RIL Java वेक लॉक को रिलीज़ कर देता है. इससे ऐप्लिकेशन प्रोसेसर, निष्क्रिय से निलंबित स्थिति में जा सकता है. जब वेंडर कोड से रिस्पॉन्स मिलता है, तो RIL Java (ऐप्लिकेशन प्रोसेसर) फिर से वेकलॉक हासिल करता है, रिस्पॉन्स को प्रोसेस करता है, और फिर आइडल मोड में वापस आ जाता है. ऐसा होने पर, डिवाइस को निलंबित करने और फिर से चालू करने पर, बहुत ज़्यादा बैटरी खर्च हो सकती है.

अगर रिस्पॉन्स में लगने वाला समय ज़्यादा नहीं है, तो रिस्पॉन्स मिलने तक, रिस्पॉन्स देने वाले ऐप्लिकेशन को ऐक्टिव रखना और उसे निष्क्रिय मोड में नहीं भेजना, ऊर्जा की खपत को कम करने के लिहाज़ से बेहतर हो सकता है. ऐसा करने के लिए, रिस्पॉन्स मिलने पर, रिस्पॉन्स देने वाले ऐप्लिकेशन को ऐक्टिव मोड में भेजने के बजाय, रिस्पॉन्स मिलने तक उसे निष्क्रिय मोड में भेजा जाता है. वेंडर को प्लैटफ़ॉर्म के हिसाब से, बिजली की खपत का आकलन करना चाहिए. इससे, वे यह तय कर पाएंगे कि T समय के थ्रेशोल्ड की वैल्यू क्या होनी चाहिए. ऐसा तब करना चाहिए, जब T समय तक डिवाइस के आइडल मोड में रहने से खर्च होने वाली बिजली, आइडल मोड से निलंबित मोड और फिर से आइडल मोड में जाने में खर्च होने वाली बिजली से ज़्यादा हो.T जब समय T पता होता है, तो RIL के उन निर्देशों को असिंक्रोनस के तौर पर और बाकी निर्देशों को सिंक्रोनस के तौर पर बांटा जा सकता है जिनमें T से ज़्यादा समय लगता है.

आरआईएल के कम्यूनिकेशन के उदाहरण

नीचे दिए गए डायग्राम में, आरआईएल के साथ आम तौर पर होने वाले कम्यूनिकेशन के उदाहरण दिखाए गए हैं. साथ ही, आरआईएल के अनुरोधों और अनचाहे अनुरोधों को मैनेज करने के लिए, कोड में बदलाव करने के समाधान भी दिए गए हैं.

ध्यान दें: नीचे दिए गए डायग्राम में इस्तेमाल किए गए फ़ंक्शन को लागू करने के बारे में जानकारी पाने के लिए, ril.cpp में acquireWakeLock(), decrementWakeLock(), और clearWakeLock() के तरीकों को देखें.

स्थिति: आरआईएल का अनुरोध और अनुरोध के हिसाब से एसिंक्रोनस रिस्पॉन्स

इस स्थिति में, अगर RIL से अनुरोध किए गए जवाब में काफ़ी समय लगने की उम्मीद है (जैसे, RIL_REQUEST_GET_AVAILABLE_NETWORKS का जवाब), तो ऐप्लिकेशन प्रोसेसर की तरफ़ से, वेकलॉक को लंबे समय तक रखा जाता है. मॉडेम से जुड़ी समस्याओं की वजह से भी, आपको लंबे समय तक इंतज़ार करना पड़ सकता है.

पहली इमेज. आरआईएल ने एसिंक्रोनस रिस्पॉन्स का अनुरोध किया.

पहला समाधान: मॉडम, आरआईएल के अनुरोध और एसिंक्रोनस रिस्पॉन्स के लिए, वेकलॉक को होल्ड करता है.

दूसरी इमेज. मॉडम के पास Wakelock है.
  1. RIL अनुरोध भेजा जाता है और उस अनुरोध को प्रोसेस करने के लिए, मॉडेम को वेकलॉक मिलता है.
  2. मॉडेम, सूचना भेजता है. इसकी वजह से, Java साइड पर वॉकलॉक काउंटर कम हो जाता है और काउंटर की वैल्यू 0 होने पर उसे रिलीज़ कर दिया जाता है.

    ध्यान दें: अनुरोध-पुष्टि के क्रम के लिए, वेकलॉक टाइम आउट की अवधि, फ़िलहाल इस्तेमाल किए जा रहे टाइम आउट की अवधि से कम होगी. इसकी वजह यह है कि पुष्टि की जानकारी तुरंत मिलनी चाहिए.

  3. अनुरोध को प्रोसेस करने के बाद, मॉडेम वेंडर को एक इंटरप्ट भेजता है. यह इंटरप्ट, वेक लॉक हासिल करता है और ril.cpp को जवाब भेजता है. इसके बाद, ril.cpp वेक लॉक हासिल करता है और Java साइड को जवाब भेजता है.
  4. जब जवाब Java साइड पर पहुंचता है, तो वेकलॉक हासिल किया जाता है और कॉल करने वाले को जवाब दिया जाता है.
  5. सभी मॉड्यूल से रिस्पॉन्स प्रोसेस होने के बाद, ril.cpp को पुष्टि भेजी जाती है. यह पुष्टि, सॉकेट के ज़रिए भेजी जाती है. इसके बाद, ril.cpp तीसरे चरण में हासिल किए गए वेकलॉक को रिलीज़ कर देता है.

दूसरा समाधान: मॉडम, वेकलॉक को होल्ड नहीं करता और रिस्पॉन्स तुरंत मिलता है (रिएल अनुरोध और रिस्पॉन्स सिंक होता है). सिंक्रोनस बनाम असिंक्रोनस व्यवहार को किसी खास आरआईएल कमांड के लिए हार्डकोड किया जाता है और कॉल के हिसाब से तय किया जाता है.

तीसरी इमेज. मॉडम, Wakelock को होल्ड नहीं करता.
  1. RIL अनुरोध, Java साइड पर acquireWakeLock() को कॉल करके भेजा जाता है.
  2. वेंडर कोड को वेकलॉक हासिल करने की ज़रूरत नहीं होती. साथ ही, वह अनुरोध को प्रोसेस करके तुरंत जवाब दे सकता है.
  3. जब जवाब Java साइड को मिलता है, तो decrementWakeLock() को कॉल किया जाता है. इससे, वॉकलॉक का काउंटर कम हो जाता है और काउंटर की वैल्यू 0 होने पर, वॉकलॉक रिलीज़ हो जाता है.

स्थिति: RIL से अनचाहा जवाब

इस स्थिति में, आरआईएल के अनचाहे रिस्पॉन्स में, वेकलॉक टाइप का फ़्लैग होता है. इससे पता चलता है कि वेंडर के रिस्पॉन्स के लिए, वेकलॉक की ज़रूरत है या नहीं. अगर फ़्लैग सेट है, तो तय समय के लिए वेकलॉक सेट किया जाता है और जवाब को सोकेट के ज़रिए Java साइड पर भेजा जाता है. टाइमर खत्म होने पर, वेकलॉक रिलीज़ हो जाता है. RIL के अलग-अलग अनचाहे रिस्पॉन्स के लिए, समय के हिसाब से तय किया गया वेकलॉक बहुत लंबा या बहुत छोटा हो सकता है.

चौथी इमेज. RIL से अनचाहा जवाब मिला.

समाधान: अनचाहा रिस्पॉन्स भेजते समय, नेटिव साइड पर समय के हिसाब से वेकलॉक रखने के बजाय, Java कोड से नेटिव साइड (ril.cpp) पर एक सूचना भेजी जाती है.

पांचवीं इमेज. तय समय के लिए डिवाइस को चालू रखने की सुविधा के बजाय, ack का इस्तेमाल करना.

फिर से डिज़ाइन किए गए वेकलॉक की पुष्टि करना

पुष्टि करें कि आरआईएल कॉल को सिंक्रोनस या एसिंक्रोनस के तौर पर पहचाना गया है. बैटरी की खपत, हार्डवेयर/प्लैटफ़ॉर्म पर निर्भर हो सकती है. इसलिए, वेंडर को कुछ इंटरनल टेस्ट करने चाहिए, ताकि यह पता लगाया जा सके कि असाइनमेंट के लिए, नए वेकलॉक सेमेटिक्स का इस्तेमाल करने से बैटरी की खपत कम होती है या नहीं.