[NFC]P2P设备响应流程

本文详细分析了NFC P2P设备从onLlcpLinkActivated()开始的响应流程,涉及SNEP、NDEFPUSH、HANDOVER和ECHOSERVER的处理。在接收到连接激活消息后,NFC服务通过UI主线程处理底层状态更新,并与上层应用交互,包括发送数据的确认、NDEF消息发送、Handover协议和SNEP协议的执行。整个过程旨在深入理解NFC中的P2P通信机制。
摘要由CSDN通过智能技术生成

        前文[NFC]Tag设备响应流程中有提到P2P设备的发现的函数始于:onLlcpLinkActivated().


        本文将基于onLlcpLinkActivated()开始后文的分析,进而引出P2P流程中的SNEP,NDEFPUSH,HANDOVER以及ECHOSERVER的响应过程.


        程序进入 onLlcpLinkActivated() 后,有点类似notify,开始同时上层,有P2P设备靠近了,解析一下,是什么格式,看看要做什么操作.

    @Override
    public void onLlcpLinkActivated(NfcDepEndpoint device) {
        sendMessage(NfcService.MSG_LLCP_LINK_ACTIVATION, device);
    }


        消息MSG_LLCP_LINK_ACTIVATION被NfcService.java自身注册的NfcServiceHandler进行处理

case MSG_LLCP_LINK_ACTIVATION:
	if (mIsDebugBuild) {
		//@paul: 发送LLCP_UP的广播
		Intent actIntent = new Intent(ACTION_LLCP_UP);
		mContext.sendBroadcast(actIntent);
	}
	//@paul: 解析底层传递上来的NfcDepEndpoint信息
	llcpActivated((NfcDepEndpoint) msg.obj);
	break;

        在进入llcpActivated()之后,系统会区分Target和Initiator,这两种角色的流程基本上相同,差异点是在Target端会先执行connect(),此connect()是进行数据链路层的连接,保证底层已经是发现对方并且是可以连接的。


        对于我们来说,需要关注的是llcp链路建立成功后的操作,插播一下P2pLinkManager.java中的一些状态变化函数:

<span style="font-size:12px;">public void onLlcpActivated()
public void onLlcpFirstPacketReceived() 
public void onLlcpDeactivated()
void onSendComplete(NdefMessage msg, long elapsedRealtime)</span>

       这些函数必须在UI main thread 调用,用于接收到底层连接的各种状态的更新。各个函数的意义依照名字基本上就能理解了。

       直接分析onLlcpActivated()函数:

/**
 * Must be called on UI Thread.
 */
public void onLlcpActivated() {
	Log.i(TAG, "LLCP activated");

	synchronized (P2pLinkManager.this) {
		...
		mLlcpConnectDelayed = false;
		//@paul: 初始状态mLinkState为LINK_STATE_DOWN
		switch (mLinkState) {
			case LINK_STATE_DOWN:
				if (DBG) Log.d(TAG, "onP2pInRange()");
				mLinkState = LINK_STATE_WAITING_PDU;
				//@paul: 通知UI,发现P2P设备
				mEventListener.onP2pInRange();
				//@paul: 初始状态mSendState为SEND_STATE_NOTHING_TO_SEND
				if (mSendState == SEND_STATE_PENDING) {
					if (DBG) Log.d(TAG, "Sending pending data.");
					mHandler.removeMessages(MSG_WAIT_FOR_LINK_TIMEOUT);
					mSendState = SEND_STATE_SENDING;
					onP2pSendConfirmed(false);
				} else {
					mSendState = SEND_STATE_NOTHING_TO_SEND;
					//@paul: 依据APP设置的信息,准备发送的信息
					prepareMessageToSend(true);
					if (mMessageToSend != null ||
							(mUrisToSend != null && mHandoverManager.isHandoverSupported())) {
						if ((mSendFlags & NfcAdapter.FLAG_NDEF_PUSH_NO_CONFIRM) != 0) {
							mSendState = SEND_STATE_SENDING;
							//@paul: 不需要UI确认
							onP2pSendConfirmed(false);
						} else {
							mSendState = SEND_STATE_NEED_CONFIRMATION;
							if (DBG) Log.d(TAG, "onP2pSendConfirmationRequested()");
							//@paul: 需要UI上确认过才能发送
							mEventListener.onP2pSendConfirmationRequested();
						}
					}
				}
				break;
		...
		}
	}
}
        上述函数的重点就是:prepareMessageToSend() 以及mEventListener.onP2pSendConfirmationRequested(); 分析完需要确认的流程,那不需要确认的流程也就打通了。

         由于NFC APP(例如Gallery,Calendar,联系簿等)在使用NFC发送数据时,都需要先设置要发送的数据的格式。设置的主要内容存放在变量:mMessageToSend ,mUrisToSend 中。此处涉及到APP部分,后续在单独开一节说明这部分。


        先说明一下prepareMessageToSend(),此函数流程在注释中说明:

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值