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

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

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

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

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

बेहतर आरआईएल गड़बड़ी कोड लागू करना

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

RIL कम्यूनिकेशन के उदाहरण

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

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

स्थिति: आरआईएल अनुरोध और एसिंक्रोनस जवाब

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

पहली इमेज. RIL ने एसिंक्रोनस जवाब का अनुरोध किया है.

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

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

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

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

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

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

सिनारियो: RIL से बिना मांगे जवाब मिलना

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

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

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

पांचवीं इमेज. टाइम किए गए वेकलॉक के बजाय, ack का इस्तेमाल किया जा रहा है.

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

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