[NFC]Tag设备响应流程

本文详细解析了NFC设备发现流程,从applyRouting()开始,深入到Tag消息分发和处理,包括notifyNdefMessageListeners()、notifyLlcpLinkActivation()等关键函数。接着,介绍了Tag设备的Framework流程,特别是findAndReadNdef()函数,该函数根据芯片能力读取并转换Tag内容。此外,文章还涉及了Handover流程,如Bluetooth和Wi-Fi的Handover,以及尝试Ndef和Tech的处理步骤。整个处理流程复杂,建议分次阅读理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        接上部分的分析,当前系统已经进入到applyRouting()阶段,后续应该是需要一直去监听当前是否有NFC设备进入通讯范围。如果有适合的NFC设备,则底层会先进行沟通,并将消息通知给上层。


进入NFC设备发现流程

        下面从applyRouting()函数开始分析,可以参考系统注释:

void applyRouting(boolean force) {
	synchronized (this) {
		//@paul: 如果NFC没有打开或者已经关闭,则直接发挥
		if (!isNfcEnabledOrShuttingDown()) {
			return;
		}
		...
		if (mInProvisionMode) {
			mInProvisionMode = Settings.Secure.getInt(mContentResolver,
					Settings.Global.DEVICE_PROVISIONED, 0) == 0;
			if (!mInProvisionMode) {
				//@paul: 原生的Android里面Provision只做了一件事,就是写入一个DEVICE_PROVISIONED标记。
				//@paul: 不过这个标记作用很大,这个标记只会在系统全新升级(双清)的时候写入一次,代表了Android系统升级准备完成,可以正常工作。
				mNfcDispatcher.disableProvisioningMode();
				mHandoverManager.setEnabled(true);
			}
		}
		
		//@paul: 如果有tag正在通讯时,delay一段时间再更新参数
		// Special case: if we're transitioning to unlocked state while
		// still talking to a tag, postpone re-configuration.
		if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED && isTagPresent()) {
			Log.d(TAG, "Not updating discovery parameters, tag connected.");
			mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESUME_POLLING),
					APPLY_ROUTING_RETRY_TIMEOUT_MS);
			return;
		}

		try {
			watchDog.start();
			//@paul: 依据前面初始化的参数来更新NfcDiscoveryParameters
			// Compute new polling parameters
			NfcDiscoveryParameters newParams = computeDiscoveryParameters(mScreenState);
			if (force || !newParams.equals(mCurrentDiscoveryParameters)) {
				//@paul: 判断条件为:mTechMask != 0 || mEnableHostRouting
				//@paul:mTechMask一般不为0,mEnableHostRouting一般为false
				if (newParams.shouldEnableDiscovery()) {
					boolean shouldRestart = mCurrentDiscoveryParameters.shouldEnableDiscovery();
					//@paul:系统一般会进入enableDiscovery()
					mDeviceHost.enableDiscovery(newParams, shouldRestart);
				} else {
					mDeviceHost.disableDiscovery();
				}
				mCurrentDiscoveryParameters = newParams;
			} else {
				Log.d(TAG, "Discovery configuration equal, not updating.");
			}
		} finally {
			watchDog.cancel();
		}
	}
}

        由于系统调用到enableDiscovery()函数,此函数不论是nxp还是nci,都会调用到native函数doEnableDiscovery(),继续追踪此函数(后续都已NXP为例),最终调用到com_android_nfc_NativeNfcManager.cpp中的:

   {"doEnableDiscovery", "(IZZZ)V",
      (void *)com_android_nfc_NfcManager_enableDiscovery},

        继续追踪com_android_nfc_NfcManager_enableDiscovery():

static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o, jint modes,
        jboolean, jboolean reader_mode, jboolean restart)
{
	...

   /* Register callback for remote device notifications.
    * Must re-register every time we turn on discovery, since other operations
    * (such as opening the Secure Element) can change the remote device
    * notification callback*/
	//@paul: 注册侦听到NFC设备时的回调函数,后续的流程从此开始
   REENTRANCE_LOCK();
   ret = phLibNfc_RemoteDev_NtfRegister(&nat->registry_info, nfc_jni_Discovery_notification_callback, (void *)nat);
   REENTRANCE_UNLOCK();
   
	...
	//@paul: 启动discovery流程
    nfc_jni_start_discovery_locked(nat, restart);
clean_and_return:
    CONCURRENCY_UNLOCK();
}

        此处的两个函数nfc_jni_start_discovery_locked()和nfc_jni_Discovery_notification_callback()都需要在深入一点,一个一个的看:

static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume)
{
	...
configure:
   /* Start Polling loop */
   TRACE("******  Start NFC Discovery ******");
   REENTRANCE_LOCK();
   //@paul: nfc_jni_discover_callback()是discover后消息notify的开始
   ret = phLibNfc_Mgt_ConfigureDiscovery(resume ? NFC_DISCOVERY_RESUME : NFC_DISCOVERY_CONFIG,
      nat->discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data);
   REENTRANCE_UNLOCK();

   ...
   
clean_and_return:
   nfc_cb_data_deinit(&cb_data);
}

        一旦上面进入了nfc_jni_discover_callback(),后续就会进入nfc_jni_Discovery_notification_callback(),此函数就会把底层看到的信息开始一层一层的notify:

static void nfc_jni_Di
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值