依据前文中介绍SNEP中封装的是NEDF消息,而NDEF消息最终会用到RTD的格式进行封装,此文章会依序介绍NDEF和RTD的specification。
NDEF简介
NDEF(NFC data exchange format)是在LLCP链路被激活时使用到。
NDEF spec的主要目的有:
- 封装任意形式的文件和实体(如加密数据,XML文件等)
- 封装未知大小的文件和实体
- 组合按某种顺序出现的多个文件和实体(如含有附件的标准文件)
- 同时需要注意小负载的封装不应该增加系统的负荷。
使用场景:
上层应用产生由一个或多个文件生成的NDEF信息,该消息交由底层LLC层传送给对方,对方可以接受后直接处理或作为中间阶段写入Tag中。当其他设备接近该tag时,会读到该tag中的内容,并把读到的NDEF消息传给上层应用分析和处理。
NDEF协议
消息格式:
- NDEF消息由一个或多个NEDF Record组成
- 首个消息中MB标记置1,最后一个消息中ME标记置1
Record是NDEF消息中的最小单元。为避免发送端发送数据过大导致接收端无法处理,需要对record进行分片处理,并将第一个record中的CF标记置1,中间的record也要设置CF为1,且type_length和IL都为0,TNF为0x6(unchanged),结束的record中CF清零,且type_length和IL都为0。
NDEF完整封包格式如下:
如果Short Flag为1时,对应的封包格式如下:
其中各标记说明如下:
Flag | 说明 | 补充说明 |
MB | Message Begin | 第一个NDEF record设置,1bit |
ME | Message End | 最后一个NDEF record设置,1bit |
CF | Chunk Flag | 当负载被截断时,第一个和中间的负载会设置此Flag,1bit |
SR | Short Record | 负载长度小于255,设置此Flag;否则负载长度大于255,1bit |
IL | Id Length Exist | 表示后续ID域是否存在,1bit |
TNF | Type Name Format | 设置type中的类型,3bits |
TYPE_LENGTH | Type field length | 表示Type域长度,8bits |
ID_LENGTH | ID field length | 表示ID域长度,8bits |
PAYLOAD_LENGTH | Payload field length | 表示Payload域长度,若SR为1为8bits,为0则为4Bytes |
TYPE | Type field | TYPE信息,与TYPE_LENGTH对应 |
ID | ID field | ID信息,与TYPE_LENGTH对应 |
PAYLOAD | Payload filed | 有效负载信息,与PAYLOADTYPE_LENGTH对应 |
关于TNF,具体值信息如下:
TNF | Value | 说明 |
Empty | 00 | 空负载 |
NFC Well-known type | 01 | 参考RTD信息 |
Media type | 02 |
|
Obsolute URI | 03 | 绝对URI |
External type | 04 |
|
Unknown | 05 | 无法解析的格式 |
Unchanged | 06 | 用于Chunked消息 |
Reserve | 07 | 保留,暂无使用 |
RTD简介
名词简介:
RTD: record typedefinition
NID:namespace indentifier
NSS:namespace specific string
URI:uniform resourceindentifier
URN:uniform resource name
MIME: multipurpose internet mailextension
Record type简介:
NFC中well known type设置为TNF为0x01,则其NID为”nfc”,NSS前缀含“wkt”,例如:“urn:nfc:wkt:a”被编码成”a”。
若设置TNF为0x04,表示external type时,说明第三方希望能自行分配namespace,则其NID为”nfc”,NSS前缀含“ext”,例如:“urn:nfc:ext:<domain>:<servicename>”被编码成” <domain>:<service name>”。
协议规定全局变量需以大写字母开头,局部变量使用小写字母或者数据开头。
编码简介
编码结果中,不应该出现URN NID以及NSS prefix。
在比较type名称时,两个well know type的名字区分大小写,但是两个external type的名字不区分大小写。例子请参考Spec。
对于编码,协议还有规定一些error handling部分,简单的说就是忽略错误信息:
- 出现非法字符(Spec定义以外的字符)时,直接忽略
- 忽略无法识别的wkt和ext时,直接忽略
由于NDEF 和RTD部分的协议比较简单,就不过多介绍。其实针对RTD的部分,每种格式都有规定其具体的封包信息(例如text格式,sig格式以及smart post等),这里就不多具体说明,需要使用要对应协议的,请直接参考就好。
补充一下个人对于LLCP SNEP NEDF以及RTD的理解示意图:
+-------------------------------------------+
| +--------------------------------+ |
| | +--------------------+ | |
| | | +-------+ | | |
| LLCP | SNEP | DNEF | RTD | | | |
| | | +-------+ | | |
| | +--------------------+ | |
| +--------------------------------+ |
+-------------------------------------------+