289 lines
12 KiB
HTML
289 lines
12 KiB
HTML
<html devsite>
|
|
<head>
|
|
<title>RIL Refactoring</title>
|
|
<meta name="project_path" value="/_project.yaml" />
|
|
<meta name="book_path" value="/_book.yaml" />
|
|
</head>
|
|
<body>
|
|
<!--
|
|
Copyright 2017 The Android Open Source Project
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
-->
|
|
|
|
|
|
|
|
<p>Android 7.0 included a refactoring of the Radio Interface Layer (RIL), using a set of
|
|
subfeatures to improve RIL functionality. Partner code changes are required to implement these
|
|
features, which are optional but encouraged. Refactoring changes are backward compatible, so prior
|
|
implementations of the refactored features continue to work.</p>
|
|
|
|
<p>The following subfeatures are included in the RIL refactoring feature. You
|
|
can implement any or all of the subfeatures:</p>
|
|
|
|
<ul>
|
|
<li>Enhanced RIL error codes: Code can return more specific error codes
|
|
than the existing <code>GENERIC_FAILURE</code> code. This enhances error
|
|
troubleshooting by providing more specific information about the cause
|
|
of errors.</li>
|
|
|
|
<li>Enhanced RIL versioning: The RIL versioning mechanism is enhanced to
|
|
provide more accurate and easier to configure version information.</li>
|
|
|
|
<li>Redesigned RIL communication using wakelocks: RIL communication using
|
|
wakelocks is enhanced to improve device battery performance.</li>
|
|
</ul>
|
|
|
|
<h2 id="examples">Examples and source</h2>
|
|
|
|
<p>Documentation for RIL versioning is also in code comments in <a
|
|
href="https://android.googlesource.com/platform/hardware/ril/+/master/include/telephony/ril.h"><code>https://android.googlesource.com/platform/hardware/ril/+/master/include/telephony/ril.h</code></a>.</p>
|
|
|
|
<h2 id="implementation">Implementation</h2>
|
|
|
|
<p>The following sections describe how to implement the subfeatures of the
|
|
RIL refactoring feature.</p>
|
|
|
|
<h3 id="errorcodes">Implementing enhanced RIL error codes</h3>
|
|
|
|
<h4 id="errorcodes-problem">Problem</h4>
|
|
|
|
<p>Almost all RIL request calls can return the <code>GENERIC_FAILURE</code>
|
|
error code in response to an error. This is an issue with all solicited
|
|
responses returned by the OEMs. It is difficult to debug an issue from
|
|
the bug report if the same <code>GENERIC_FAILURE</code> error code is
|
|
returned by RIL calls for different reasons. It can take considerable time
|
|
for vendors to even identify what part of the code could have returned a
|
|
<code>GENERIC_FAILURE</code> code.</p>
|
|
|
|
<h4 id="errorcodes-solution">Solution</h4>
|
|
|
|
<p>OEMs should return a distinct error code value associated
|
|
with each of the different errors that are currently categorized as
|
|
<code>GENERIC_FAILURE</code>.</p>
|
|
|
|
<p>If OEMs do not want to publicly reveal their custom error codes, they may
|
|
return errors as a distinct set of integers (for example, from 1 to x) that
|
|
are mapped as <code>OEM_ERROR_1</code> to <code>OEM_ERROR_X</code>. The
|
|
vendor should make sure each such masked error code returned maps to a unique
|
|
error reason in their code. The purpose of doing this is
|
|
to speed up debugging RIL issues whenever generic errors are returned
|
|
by the OEM. It can take too much time to identify what exactly caused
|
|
<code>GENERIC_FAILURE</code>, and sometimes it's impossible to figure out.<p>
|
|
|
|
<p>In <code>ril.h</code>, more error codes are
|
|
added for enums <code>RIL_LastCallFailCause</code> and
|
|
<code>RIL_DataCallFailCause</code> so that vendor code avoids returning
|
|
generic errors like <code>CALL_FAIL_ERROR_UNSPECIFIED</code> and
|
|
<code>PDP_FAIL_ERROR_UNSPECIFIED</code>.</p>
|
|
|
|
<h3 id="version">Implementing enhanced RIL versioning</h3>
|
|
|
|
<h4 id="version-problem">Problem</h4>
|
|
|
|
<p>RIL versioning is not accurate enough. The mechanism for vendors to
|
|
report their RIL version is not clear, causing vendors to report an incorrect
|
|
version. A workaround method of estimating the version is used, but it can
|
|
be inaccurate.</p>
|
|
|
|
<h4 id="version-solution">Solution</h4>
|
|
|
|
<p>There is a documented section in <code>ril.h</code> describing what a
|
|
particular RIL version value corresponds to. Each
|
|
RIL version is documented, including what changes correspond
|
|
to that version. Vendors must update their version in code when making
|
|
changes corresponding to that version, and return that version while doing
|
|
<code>RIL_REGISTER</code>.</p>
|
|
|
|
<h3 id="wakelocks">Implementing redesigned RIL communication using
|
|
wakelocks</h3>
|
|
|
|
<h4 id="wakelocks-prob-sum">Problem summary</h4>
|
|
|
|
<p>Timed wakelocks are used in RIL communication in an imprecise way,
|
|
which negatively affects battery performance. RIL requests can be either
|
|
solicited or unsolicited. Solicited requests should be classified as one of
|
|
the following:</p>
|
|
|
|
<ul>
|
|
<li>synchronous: Those that do not take considerable time to respond back. For
|
|
example, <code>RIL_REQUEST_GET_SIM_STATUS</code>.</li>
|
|
|
|
<li>asynchronous: Those that take considerable time to respond back. For
|
|
example, <code>RIL_REQUEST_QUERY_AVAILABLE_NETWORKS</code>.</li>
|
|
</ul>
|
|
|
|
<p>Follow these steps to implement redesigned wakelocks:</p>
|
|
|
|
<ol>
|
|
<li>
|
|
Classify solicited RIL commands as either synchronous or asynchronous
|
|
depending on how much time they take to respond.
|
|
<p>Here are some things to consider while making
|
|
that decision:</p>
|
|
|
|
<ul>
|
|
<li>As explained in the solution of asynchronous solicited RIL requests,
|
|
because the requests take considerable time, RIL Java releases the wakelock
|
|
after receiving ack from vendor code. This might cause the application
|
|
processor to go from idle to suspend state. When the response is available
|
|
from vendor code, RIL Java (the application processor) will re-acquire the
|
|
wakelock and process the response, and later go to idle state again. This
|
|
process of moving from idle to suspend state and back to idle can consume
|
|
a lot of power.</li>
|
|
|
|
<li>If the response time isn't long enough then holding the wakelock and
|
|
staying in idle state for the entire time it takes to respond can be more
|
|
power efficient than going in suspend state by releasing the wakelock and
|
|
then waking up when the response arrives. So vendors should use
|
|
platform-specific power measurement to find out the threshold value of time 't' when
|
|
power consumed by staying in idle state for the entire time 't' consumes
|
|
more power than moving from idle to suspend and back to idle in same time
|
|
't'. When that time 't' is discovered, RIL commands that take more than time
|
|
't' can be classified as asynchronous, and the rest of the RIL commands can
|
|
be classified as synchronous.</li>
|
|
</ul>
|
|
</li>
|
|
|
|
<li>Understand the RIL communications scenarios described in the <a
|
|
href="#ril-comm-scenarios">RIL communication scenarios</a> section.</li>
|
|
|
|
<li>Follow the solutions in the scenarios by modifying your code to handle
|
|
RIL solicited and unsolicited requests.</li>
|
|
</ol>
|
|
|
|
<h4 id="ril-comm-scenarios">RIL communication scenarios</h4>
|
|
|
|
<p>For implementation details of the functions used in the
|
|
following diagrams, see the source code of <code>ril.cpp</code>:
|
|
<code>acquireWakeLock()</code>, <code>decrementWakeLock()</code>,
|
|
<code>clearWakeLock(</code>)</p>
|
|
|
|
<h5>Scenario 1: RIL request from Java APIs and solicited asynchronous response
|
|
to that request</h5>
|
|
|
|
<p><img src="images/ril-refactor-scenario-1.png"></p>
|
|
|
|
<h6>Problem</h6>
|
|
|
|
<p>If the RIL solicited response is expected to take considerable time (for
|
|
example, <code>RIL_REQUEST_GET_AVAILABLE_NETWORKS</code>), then wakelock
|
|
is held for a long time on the Application processor side, which is a
|
|
problem. Also, modem problems result in a long wait.</p>
|
|
|
|
<h6>Solution part 1</h6>
|
|
|
|
<p>In this scenario, wakelock equivalent is held by Modem code (RIL request
|
|
and asynchronous response back).</p>
|
|
|
|
<p><img src="images/ril-refactor-scenario-1-solution-1.png"></p>
|
|
|
|
<p>As shown in the above sequence diagram:</p>
|
|
|
|
<ol>
|
|
<li>RIL request is sent, and the modem needs to acquire wakelock to process
|
|
the request.</li>
|
|
|
|
<li>The modem code sends acknowledgement that causes the Java side to decrement
|
|
the wakelock counter and release it if the wakelock counter value is 0.</li>
|
|
|
|
<li>After the modem processes the request, it sends an interrupt to the
|
|
vendor code that acquires wakelock and sends a response to ril.cpp. ril.cpp
|
|
then acquires wakelock and sends a response to the Java side.</li>
|
|
|
|
<li>When the response reaches the Java side, wakelock is acquired and response
|
|
is sent back to caller.</li>
|
|
|
|
<li>After that response is processed by all modules, acknowledgement is
|
|
sent back to <code>ril.cpp</code> over a socket. <code>ril.cpp</code> then
|
|
releases the wakelock that was acquired in step 3.</li>
|
|
</ol>
|
|
|
|
<p>Note that the wakelock timeout duration for the request-ack sequence
|
|
would be smaller than the currently used timeout duration because the ack
|
|
should be received back fairly quickly.</p>
|
|
|
|
<h6>Solution part 2</h6>
|
|
|
|
<p>In this scenario, wakelock is not held by modem and response is quick
|
|
(synchronous RIL request and response).</p>
|
|
|
|
<p><img src="images/ril-refactor-scenario-1-solution-2.png"></p>
|
|
|
|
<p>As shown in the above sequence diagram:</p>
|
|
|
|
<ol>
|
|
<li>RIL request is sent by calling <code>acquireWakeLock()</code> on the
|
|
Java side.</li>
|
|
|
|
<li>Vendor code doesn't need to acquire wakelock and can process the request
|
|
and respond quickly.</li>
|
|
|
|
<li>When the response is received by the Java side,
|
|
<code>decrementWakeLock()</code> is called, which decreases wakelock counter
|
|
and releases wakelock if the counter value is 0.</li>
|
|
</ol>
|
|
|
|
<p>Note that this synchronous vs. asynchronous behavior is hardcoded for a
|
|
particular RIL command and decided on a call-by-call basis.</p>
|
|
|
|
<h5>Scenario 2: RIL unsolicited response</h5>
|
|
|
|
<p><img src="images/ril-refactor-scenario-2.png"></p>
|
|
|
|
<p>As shown in the above diagram, RIL unsolicited responses have a wakelock
|
|
type flag in the response that indicates whether a wakelock needs to be
|
|
acquired or not for the particular response received from the vendor. If
|
|
the flag is set, then a timed wakelock is set and response is sent over a
|
|
socket to the Java side. When the timer expires, the wakelock is released.</p>
|
|
|
|
<h6>Problem</h6>
|
|
|
|
<p>The timed wakelock illustrated in Scenario 2 could be too long or too
|
|
short for different RIL unsolicited responses.</p>
|
|
|
|
<h6>Solution</h6>
|
|
|
|
<p><img src="images/ril-refactor-scenario-2-solution.png"></p>
|
|
|
|
<p>As shown, the problem can be solved by sending an acknowledgement from
|
|
the Java code to the native side (<code>ril.cpp</code>), instead of holding
|
|
a timed wakelock on the native side while sending an unsolicited response.</p>
|
|
|
|
<h2 id="validation">Validation</h2>
|
|
|
|
<p>The following sections describe how to validate the implementation of
|
|
the RIL refactoring feature's subfeatures.</p>
|
|
|
|
<h3 id="validate-error">Validating enhanced RIL error codes</h3>
|
|
|
|
<p>After adding new error codes to replace the <code>GENERIC_FAILURE</code>
|
|
code, verify that the new error codes are returned by the RIL call instead
|
|
of <code>GENERIC_FAILURE</code>.</p>
|
|
|
|
<h3 id="validate-version">Validating enhanced RIL versioning</h3>
|
|
|
|
<p>Verify that the RIL version corresponding to your RIL code is returned
|
|
during <code>RIL_REGISTER</code> rather than the <code>RIL_VERSION</code>
|
|
defined in <code>ril.h</code>.</p>
|
|
|
|
<h3 id="validate-wakelocks">Validating redesigned wakelocks</h3>
|
|
|
|
<p>Verify that RIL calls are identified as synchronous or asynchronous.</p>
|
|
|
|
<p>Because battery power consumption can be hardware/platform dependent,
|
|
vendors should do some internal testing to find out if using the new wakelock
|
|
semantics for asynchronous calls leads to battery power savings.</p>
|
|
|
|
</body>
|
|
</html>
|