依照学习流程,此章节主要介绍NFCForum中LLCP Spec。主要是将LLCP spec中重要的内容摘要出来,包含的内容肯定不是很全面,但基本上看代码是够用了。主要分为三部分:
1.LLC概述
2.LLC协议
3.LLCP链路
LLC:(logicallink control)按照网络协议的层次划分,就是其中的数据链层,用图表表示如下:
依据数据传输模式,可以划分为:
1. 面向连接传输
2. 无连接传输
依据连接的种类分:
Class1:无连接传输
Class2:面向连接传输
Class3:无连接传输和面向连接传输
由于LLCP Spec有49页,目前研究的是1.2版本,主要从以下几个方面进行解读:
2.1 LLC封包格式:
2.1.1 服务访问点(Service AccessPoint)
其中服务访问点(Service Access Point)表征不同的服务,具体说明如下:
细化00h-0Fh如下:
00h:用于LLC管理模块,不能用于任何SAP
01h:用于服务发现协议(Service Discovery Protocol),对应服务名urn:nfc:sn:sdp
04h:用于SNEP协议(Simple NDEF ExchangeProtocol),对应服务名:urn:nfc:sn:snep
2.1.2 类型PTYPE
其中PTYPE表征当前信息的类型,为较好说明问题,简单整理如下:
PDU TYPE |
PTYPE |
EXPLAIN |
SEQUENCE |
INFORMATION |
SYMM |
0000 |
可用于防止link timeout |
X |
X |
PAX |
0001 |
交换参数信息 |
X |
V |
AGF |
0010 |
将数据拆包后发送,至少需要2个PDU |
X |
V |
UI |
0011 |
无编号信息 |
X |
V |
CONNECT |
0100 |
连接请求 |
X |
V |
DISC |
0101 |
断开连接 |
X |
X |
CC |
0110 |
连接完成,信息域含有参数信息 |
X |
V |
DM |
0111 |
断开模式,在CONNECT命令无法执行时回复,并且带有REASON字段 |
X |
V |
FRMR |
1000 |
拒绝,会带flag说明拒绝原因 |
X |
V |
I |
1100 |
有效信息,含N(S),N(R) |
V |
V |
RR |
1101 |
可以接收数据 |
V |
X |
RNR |
1110 |
暂时无法接受数据 |
V |
X |
SNL |
1001 |
服务名查询 |
X |
V |
备注: X表示不含此field,V表示含有此field
每种TYPE的封包格式如下:
SYMM:
PAX:
AGF:
UI:
CONNECT:
DISC:
CC:
DM:
其中DM的reason字段说明如下:
FRMR:
其中information字段说明
I:
RR:
RNR:
SNL:
2.1.3 信息域(Information)
介绍完PTYPE,就到Information域中的说明了,所有information中的信息都遵循TLV格式(type,length,value),spec整理了下面的table方便大家了解:
同样,针对上面的名称,分别说明其格式:
VERSION:
MIUX:当information中的长度大于默认值128时,系统会发送IMUX给对方告知自身能力,对方会依据IMUX+128计算出实际接收的容量
WKS:依据SAP中00h-0Fh定义,每bit对应一个sap
LTO:默认为100ms,单位是10ms,表征上次收到数据和此次发送数据的时间差
RW:默认为1,表示每个I PDU都要回复,0表示不接收I PDU
SN:格式为“urn:nfc:sn:<servicename>”/“urn:nfc:xsn:<domain>:<sn>”
OPT:表征link service class(低2位)或其他(高6位)
SDREQ:
SDRES:
此部分详细过程请参考Spec第五章,抽取主要部分说明一下。
3.1 MIU说明
MIU默认值是128,发送端的信息域大小不应该大于接收端的MIU,接收端收到大于自身MIU的数据时会直接丢弃。双方各自维护自己和对方的MIU,默认值为128,且满足MIUX+128=MIU。若收到对方的MIUX,保存对应的MIU信息。
3.2 链路激活流程
当MAC层激活完成,并判断出对端节点带LLCP能力时,就会来建立LLCP连接。MAC层中交换的LLC参数,对于LLCP过程是可见的。
在LLCP链路建立过程中,会先进行version判断
1. Version判断失败,则连接过程直接断开
2. Version检查成功,继续进行MIU的检查,最后链路才建立完成
3.3 PAX流程
MAC层会知道当前的设备角色是Initiator/Target:
1. Target
a) 发送MAC中还未交换的parameter信息,等待对方回复
b) 收到回复,启动Version判断
c) Version通过,决定MIU,否则连接失败
2. Initiator
a) 等待对方先发送PAX
b) Version检查通过,决定MIU,并发送PAX PDU
3.3.1 Version检查
其中Version检查的流程如下:
1. Major&Minor 都相等 -> OK
2. Major相等,Minor不等,取Minor较小的版本 -> OK
3. Major&Minor都不相等,由major大的一端决定是否兼容,若兼容,使用Major小的版本
3.4 Intentional Link Deactivation
当DISC PDU中的SSAP和DSAP为00h时,发送端发送后,直接断开本地连接,接收端收到后,也可以直接断开本地连接。此类DISC PDU(SSAP和DSAP为00h)不需要等待回复,但其他的DISC PDU(SSAP和DSAP不为00h)需要等待DM PDU。
3.5 链路建立流程
在发送端发送CONNECT PDU,此类PDU(SSAP相同)不能在未收到CC/DM时重复发送。同时,收到CC PDU时,DSAP可能和CONNECT PDU中SSAP会不一致。
此时分两种情况:
Case1:发送端收到CC PDU,但未收到CONNECT的ACK时:
I. CC中DSAP和CONNECT中SSAP相等
*初始化V(S),V(R),V(SA),V(RA)为0
*处理CC PDU中的参数
*进入数据传输阶段
II. CC中DSAP和CONNECT中SSAP不相等
*直接放弃连接
Case2:接收端收到CONNECT PDU时:
I. 无法处理时,返回DM PDU
II. 可处理时
*处理CONNECT PDU中的参数
*通知上层,并等待上层接收或者拒绝
>拒绝时,直接放弃连接,并发送DM
>接受时,发送CC PDU,V(S),V(R),V(SA),V(RA)为0并开始数据传输
需要注意的是,在数据传输阶段,任何的CONNECT/CC PDU都会被认为是Invalid。
3.6 服务发现(Service Discover)
SDREQ一般是出现在SNL PDU中。收到SDREQ后,需要先判断Service Name是否有注册,注册过则回复SDRES,其中含有效SAP及TID,未注册时,回复SDRES中SAP为全0。
以上是该Spec大致的内容,基本上可以涵盖Android NFC中LLCP的流程。如果有描述不正确的地方,也欢迎大家指正,感谢。
依照学习流程,此章节主要介绍NFCForum中LLCP Spec。主要是将LLCP spec中重要的内容摘要出来,包含的内容肯定不是很全面,但基本上看代码是够用了。主要分为三部分:
1.LLC概述
2.LLC协议
3.LLCP链路
LLC:(logicallink control)按照网络协议的层次划分,就是其中的数据链层,用图表表示如下:
依据数据传输模式,可以划分为:
1. 面向连接传输
2. 无连接传输
依据连接的种类分:
Class1:无连接传输
Class2:面向连接传输
Class3:无连接传输和面向连接传输
由于LLCP Spec有49页,目前研究的是1.2版本,主要从以下几个方面进行解读:
2.1 LLC封包格式:
2.1.1 服务访问点(Service AccessPoint)
其中服务访问点(Service Access Point)表征不同的服务,具体说明如下:
细化00h-0Fh如下:
00h:用于LLC管理模块,不能用于任何SAP
01h:用于服务发现协议(Service Discovery Protocol),对应服务名urn:nfc:sn:sdp
04h:用于SNEP协议(Simple NDEF ExchangeProtocol),对应服务名:urn:nfc:sn:snep
2.1.2 类型PTYPE
其中PTYPE表征当前信息的类型,为较好说明问题,简单整理如下:
PDU TYPE |
PTYPE |
EXPLAIN |
SEQUENCE |
INFORMATION |
SYMM |
0000 |
可用于防止link timeout |
X |
X |
PAX |
0001 |
交换参数信息 |
X |
V |
AGF |
0010 |
将数据拆包后发送,至少需要2个PDU |
X |
V |
UI |
0011 |
无编号信息 |
X |
V |
CONNECT |
0100 |
连接请求 |
X |
V |
DISC |
0101 |
断开连接 |
X |
X |
CC |
0110 |
连接完成,信息域含有参数信息 |
X |
V |
DM |
0111 |
断开模式,在CONNECT命令无法执行时回复,并且带有REASON字段 |
X |
V |
FRMR |
1000 |
拒绝,会带flag说明拒绝原因 |
X |
V |
I |
1100 |
有效信息,含N(S),N(R) |
V |
V |
RR |
1101 |
可以接收数据 |
V |
X |
RNR |
1110 |
暂时无法接受数据 |
V |
X |
SNL |
1001 |
服务名查询 |
X |
V |
备注: X表示不含此field,V表示含有此field
每种TYPE的封包格式如下:
SYMM:
PAX:
AGF:
UI:
CONNECT:
DISC:
CC:
DM:
其中DM的reason字段说明如下:
FRMR:
其中information字段说明
I:
RR:
RNR:
SNL:
2.1.3 信息域(Information)
介绍完PTYPE,就到Information域中的说明了,所有information中的信息都遵循TLV格式(type,length,value),spec整理了下面的table方便大家了解:
同样,针对上面的名称,分别说明其格式:
VERSION:
MIUX:当information中的长度大于默认值128时,系统会发送IMUX给对方告知自身能力,对方会依据IMUX+128计算出实际接收的容量
WKS:依据SAP中00h-0Fh定义,每bit对应一个sap
LTO:默认为100ms,单位是10ms,表征上次收到数据和此次发送数据的时间差
RW:默认为1,表示每个I PDU都要回复,0表示不接收I PDU
SN:格式为“urn:nfc:sn:<servicename>”/“urn:nfc:xsn:<domain>:<sn>”
OPT:表征link service class(低2位)或其他(高6位)
SDREQ:
SDRES:
此部分详细过程请参考Spec第五章,抽取主要部分说明一下。
3.1 MIU说明
MIU默认值是128,发送端的信息域大小不应该大于接收端的MIU,接收端收到大于自身MIU的数据时会直接丢弃。双方各自维护自己和对方的MIU,默认值为128,且满足MIUX+128=MIU。若收到对方的MIUX,保存对应的MIU信息。
3.2 链路激活流程
当MAC层激活完成,并判断出对端节点带LLCP能力时,就会来建立LLCP连接。MAC层中交换的LLC参数,对于LLCP过程是可见的。
在LLCP链路建立过程中,会先进行version判断
1. Version判断失败,则连接过程直接断开
2. Version检查成功,继续进行MIU的检查,最后链路才建立完成
3.3 PAX流程
MAC层会知道当前的设备角色是Initiator/Target:
1. Target
a) 发送MAC中还未交换的parameter信息,等待对方回复
b) 收到回复,启动Version判断
c) Version通过,决定MIU,否则连接失败
2. Initiator
a) 等待对方先发送PAX
b) Version检查通过,决定MIU,并发送PAX PDU
3.3.1 Version检查
其中Version检查的流程如下:
1. Major&Minor 都相等 -> OK
2. Major相等,Minor不等,取Minor较小的版本 -> OK
3. Major&Minor都不相等,由major大的一端决定是否兼容,若兼容,使用Major小的版本
3.4 Intentional Link Deactivation
当DISC PDU中的SSAP和DSAP为00h时,发送端发送后,直接断开本地连接,接收端收到后,也可以直接断开本地连接。此类DISC PDU(SSAP和DSAP为00h)不需要等待回复,但其他的DISC PDU(SSAP和DSAP不为00h)需要等待DM PDU。
3.5 链路建立流程
在发送端发送CONNECT PDU,此类PDU(SSAP相同)不能在未收到CC/DM时重复发送。同时,收到CC PDU时,DSAP可能和CONNECT PDU中SSAP会不一致。
此时分两种情况:
Case1:发送端收到CC PDU,但未收到CONNECT的ACK时:
I. CC中DSAP和CONNECT中SSAP相等
*初始化V(S),V(R),V(SA),V(RA)为0
*处理CC PDU中的参数
*进入数据传输阶段
II. CC中DSAP和CONNECT中SSAP不相等
*直接放弃连接
Case2:接收端收到CONNECT PDU时:
I. 无法处理时,返回DM PDU
II. 可处理时
*处理CONNECT PDU中的参数
*通知上层,并等待上层接收或者拒绝
>拒绝时,直接放弃连接,并发送DM
>接受时,发送CC PDU,V(S),V(R),V(SA),V(RA)为0并开始数据传输
需要注意的是,在数据传输阶段,任何的CONNECT/CC PDU都会被认为是Invalid。
3.6 服务发现(Service Discover)
SDREQ一般是出现在SNL PDU中。收到SDREQ后,需要先判断Service Name是否有注册,注册过则回复SDRES,其中含有效SAP及TID,未注册时,回复SDRES中SAP为全0。
以上是该Spec大致的内容,基本上可以涵盖Android NFC中LLCP的流程。如果有描述不正确的地方,也欢迎大家指正,感谢。