gpt4 book ai didi

android - 有没有办法检查终端是否收到主机卡仿真中的最后一条消息?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:11:49 27 4
gpt4 key购买 nike

在我的 Android 应用程序中,我实现了 HostApduService。这是它的一个实现 fragment :

public final class MyHostApduService extends HostApduService {

private boolean disconnected = false;

@Override
public byte[] processCommandApdu(byte[] commandApdu, @Nullable Bundle extras) {
//process apdu in a background thread and call sendResponseApdu() when ready
Single.fromCallable(() -> processInternal(commandApdu))
.subscribeOn(nfcScheduler)
.subscribe(this::sendResponseApdu, t -> Log.e("could not create response", t));
return null;
}

...
@Override
public void onDeactivated(int reason) {
disconnected = true;
}


private void processInternal(byte[] apdu) {
//business logic
if(!disconnected) {
//last message was probably received by the terminal
}
}
}

所以根据我的观察,onDeactivated() 回调可以恰好出现在 processCommandApdu() 的中间,即便如此,操作系统似乎更早地认识到调用 onDeactivated() 后 NFC 字段丢失。

这是一个在通信过程中丢失字段的例子:

16:21:16.808 I/MyHostApduService : processApdu[request|13bytes] 0A4040007A000000004306000
16:21:16.811 D/MyHostApduService : do business logic
16:21:16.890 D/HostEmulationManager: notifyHostEmulationDeactivated
16:21:16.890 D/HostEmulationManager: Unbinding from service ComponentInfo{app.debug/internal.MyHostApduService}
16:21:16.890 I/MyHostApduService : onDeactivated LINK_LOSS
16:21:16.898 I/MyHostApduService : processApdu[response|2bytes|90ms] 6A82

问题是我需要自信地检查最后一条消息是收到还是丢弃,因为必须执行一些重要的终结代码(但前提是终端收到消息)。有没有比使用 onDeactivated()(它的时间似乎非常不确定)更好的方法来检查是否收到消息?

最佳答案

你不能。相反,如果您确实需要可靠地检测这种情况,则需要调整您的通信协议(protocol)。

问题不在于 Android,而在于底层通信协议(protocol)(ISO/IEC 7816-4 优于 ISO/IEC 14443-4)。这些协议(protocol)是为与常规智能卡通信而构建的。智能卡是完全无源的设备,当从读卡器中拔出或远离 NFC 射频场时无法继续处理(由于缺乏能量)。

协议(protocol)栈专为询问器驱动的通信而设计(询问器是终端)。通信以命令-响应顺序执行。原则上,每个命令-响应序列都包含以下步骤(还有一些额外的极端情况):

  1. 终端发送命令。
  2. 智能卡接收并处理命令。
  3. 智能卡发送响应数据并以状态字结尾。

应用协议(protocol) (ISO/IEC 7816-4) 和传输协议(protocol)(ISO/IEC 14443-4 又名 ISO-DEP)均未通过任何形式的确认来确认智能卡响应。一旦智能卡发送了它的响应,它就被认为已经完成了处理。

实际上,这对于经典智能卡(接触式或非接触式)来说不是问题。中断的通信会导致卡重新通电(因为链路丢失也意味着断电,或者因为终端执行明确的重置)。因此,此时智能卡将无法依赖清理序列。

然而,这并不意味着没有办法克服这个限制。经典智能卡即使在电源循环期间也能保持持久状态。关键操作作为原子事务执行。在断电的情况下,清理/回滚通常在重置(启动)时执行。然而,这并不容易映射到 Android,因为链接丢失不会导致 HCE 端的执行中断。因此,在将响应发送回读卡器之前,无法检测到 HCE 智能卡是否已拔出。尽管如此,也没有会被链接丢失中断的原子事务。因此,重置(即接收选择您的应用程序的 SELECT(按 DF 名称)命令)仍然是执行清理(例如重置应用程序状态)的正确位置。

关于您的特定要求,典型的方法是调整应用程序级协议(protocol)并添加确认命令以确认收到(然后是第二次)最后一个响应。 IE。如果您目前有类似的东西:

T--->  SELECT APPLICATION<---C  FCI | 9000T--->  PERFORM CRITICAL OPERATION<---C  CRITICAL OPERATION RESULT

您可以调整协议(protocol)以包含最终确认:

T--->  SELECT APPLICATION<---C  FCI | 9000T--->  PERFORM CRITICAL OPERATION<---C  CRITICAL OPERATION RESULTT--->  CONFIRM RECEPTION OF RESULT<---C  9000

现在您不会真正关心最终响应 (9000) 是否在发送到终端的途中丢失了。

关于android - 有没有办法检查终端是否收到主机卡仿真中的最后一条消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48119004/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com