By:GentlemanTsao
文章目录
问题描述:
Case:
android.carrierapi.cts.CarrierApiTest#testIccTransmitApduBasicChannel
Failure Result:
junit.framework.ComparisonFailure:expected:<[90]00> but was:<[6f]00>
Log Print:
07-29 06:13:32.035 5453 5553 E TestRunner: failed: testIccExchangeSimIO(android.carrierapi.cts.CarrierApiTest)
07-29 06:13:32.035 5453 5553 E TestRunner: ----- begin exception -----
07-29 06:13:32.036 5453 5553 E TestRunner: junit.framework.ComparisonFailure: expected:<[90]00> but was:<[6f]00>
07-29 06:13:32.036 5453 5553 E TestRunner: at junit.framework.Assert.assertEquals(Assert.java:85)
07-29 06:13:32.036 5453 5553 E TestRunner: at junit.framework.Assert.assertEquals(Assert.java:91)
07-29 06:13:32.036 5453 5553 E TestRunner: at android.carrierapi.cts.CarrierApiTest.testIccExchangeSimIO(CarrierApiTest.java:1072)
07-29 06:13:32.036 5453 5553 E TestRunner: at java.lang.reflect.Method.invoke(Native Method)
07-29 06:13:32.036 5453 5553 E TestRunner: at junit.framework.TestCase.runTest(TestCase.java:168)
07-29 06:13:32.036 5453 5553 E TestRunner: at junit.framework.TestCase.runBare(TestCase.java:134)
07-29 06:13:32.036 5453 5553 E TestRunner: at junit.framework.TestResult$1.protect(TestResult.java:115)
07-29 06:13:32.036 5453 5553 E TestRunner: at androidx.test.internal.runner.junit3.AndroidTestResult.runProtected(AndroidTestResult.java:73)
07-29 06:13:32.036 5453 5553 E TestRunner: at junit.framework.TestResult.run(TestResult.java:118)
07-29 06:13:32.036 5453 5553 E TestRunner: at androidx.test.internal.runner.junit3.AndroidTestResult.run(AndroidTestResult.java:51)
07-29 06:13:32.036 5453 5553 E TestRunner: at junit.framework.TestCase.run(TestCase.java:124)
07-29 06:13:32.036 5453 5553 E TestRunner: at androidx.test.internal.runner.junit3.NonLeakyTestSuite$NonLeakyTest.run(NonLeakyTestSuite.java:62)
07-29 06:13:32.036 5453 5553 E TestRunner: at androidx.test.internal.runner.junit3.AndroidTestSuite$2.run(AndroidTestSuite.java:101)
07-29 06:13:32.036 5453 5553 E TestRunner: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
07-29 06:13:32.036 5453 5553 E TestRunner: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
07-29 06:13:32.036 5453 5553 E TestRunner: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
07-29 06:13:32.036 5453 5553 E TestRunner: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
07-29 06:13:32.036 5453 5553 E TestRunner: at java.lang.Thread.run(Thread.java:919)
问题分析
测试项owner及目的:
该项测试是Google新添加,目的是为了确保:
https://developer.android.com/reference/android/telephony/TelephonyManager
中对应的API得到支持。
从源码中可以看到如下commit记录:
commit 7c830e55c1bb3da5f09e6c0ac77a5426b7c8a7ca
Author: Cody Kesting <ckesting@google.com>
Date: Mon Apr 1 10:53:16 2019 -0700
Add CTS testing for TM#iccTransmitApduBasicChannel
This test makes several valid APDUs via
TelephonyManager#iccTransmitApduBasicChannel.
Bug: 122974140
Test: atest CtsCarrierApiTestCases:CarrierApiTest
Merged-In: I33128bcabbbe810e1d131d5a0fcbec5a2e53f718
Change-Id: I33128bcabbbe810e1d131d5a0fcbec5a2e53f718
(cherry picked from commit ed1c54dd425f1627c52a1512abdb78658a2beb0c)
测试用例代码段:
在下面的路径下,可以看到测试用例的参考代码段:
CarrierApiTest.java (cts\tests\tests\carrierapi\src\android\carrierapi\cts)
/**
* This test verifies that {@link TelephonyManager#iccExchangeSimIO(int, int, int, int, int,
* String)} correctly transmits iccIO commands to the UICC card. First, the MF is selected via a
* SELECT apdu via the basic channel, then a STATUS AT-command is sent.
*/
public void testIccExchangeSimIO() {
if (!hasCellular) return;
// select the MF first. This makes sure the next STATUS AT-command returns a FCP template
// for the right file.
int cla = CLA_SELECT;
int p1 = 0; // select EF by FID
int p2 = 0x0C; // requesting FCP template
int p3 = 2; // length of 'data' payload
String data = MF_FILE_ID;
String response = mTelephonyManager
.iccTransmitApduBasicChannel(cla, COMMAND_SELECT, p1, p2, p3, data);
assertEquals(STATUS_NORMAL_STRING, response); //异常发生点
。。。
测试代码解析:
发送指令:
0xA4
参数:
channel:0
cla:0x00
p1:0
p2:0x0C
p3:2
data:3F00
logcat分析
从logcat看,返回OPERATION_NOT_ALLOWED,表示该指令不被支持。
07-29 06:13:31.982 2370 2370 E PhoneInterfaceManager: [PhoneIntfMgr] iccTransmitApduBasicChannel: CommandException: com.android.internal.telephony.CommandException: OPERATION_NOT_ALLOWED
从前期分析的Exception log可以看到返回错误代号[6f]00:
07-29 06:13:32.036 5453 5553 E TestRunner: junit.framework.ComparisonFailure: expected:<[90]00> but was:<[6f]00>
该代号的涵义在如下文件中对应:
IccIoResult.java (frameworks\opt\telephony\src\java\com\android\internal\telephony\uicc)
case 0x6F:
switch(sw2) {
case 0x00: return "technical problem with no diagnostic given";
default: return "The interpretation of this status word is command dependent";
}
可以看出,它提示“technical problem with no diagnostic given”——未给出诊断的技术问题。
modem log分析
从logcat的分析推断,问题指向SIM卡或modem,因而需要抓取modem log确认。
modem log中报如下错误讯息:
User Identity Module/Error[ qmi_uim.c 10766] ADPU rejected due to security
restrictions: logical_channel doesnt belong to client
注意测试API接口是iccTransmitApduBasicChannel,而在modem log提示“ADPU rejected due to security restrictions:”。
根据高通的解释,
“
We do not allow streaming APDUs on
default channel in modem. Similarly we have restrictions for other type of
commands like manage channel etc as well on modem side.
So, the APDUs are rejected at modem
level itself and not sent to the card which leads to test case failures.
“
所以,该问题是由于modem限制了APDU造成。
解决方案:
将NV 67312 (QMI UIM APDU Security Restrictions)置0,从而解除APU的限制。
该项NV无法通过QXDM工具修改,需写入HW MBN中以生效。
我们需在modem_proc/mcfg/mcfg_gen/generic/common/Default/mcfg_hw_gen_Default.xml文件中新增一项NV:
<NvEfsItemData name="apdu_security_restrictions" id="67312" description="APDU Security Restrictions" comment="" category="UIM" mcfgAttributes="0x09" mcfgVariant="2" fullpathname="/nv/item_files/modem/qmi/uim/apdu_security_restrictions"> <Member name="apdu_security_restrictions" description="" comment="" sizeOf="1" type="uint8">0 </Member>
</NvEfsItemData>
同时,升级HW MBN version.
再重新编译Non-Hlos.bin并导入UE验证。
类关系图
如下是该项测试AP侧的类关系图: