- Android Looper 和 Handler 分析
- Android MediaScanner 详尽分析
- Android 深入浅出之 Binder 机制
- 第一部分 AudioTrack 分析
- 第二部分 AudioFlinger 分析
- Android 深入浅出之 Audio 第三部分 Audio Policy
- Android 深入浅出之 Zygote
- Android 深入浅出之 Surface
- Linux Kernel 系列一 开篇和 Kernel 启动概要
- Linux Kernel 系列二 用户空间的初始化
- Linux Kernel 系列三 Kernel 编译和链接中的 linker script 语法详解
- 第五章 深入理解常见类
- linux kernel 系列四 嵌入式系统中的文件系统以及 MTD
- 随笔之 Android 平台上的进程调度探讨
- Android 4.0 External 下功能库说明
- 随笔之 Android 不吐不快
- Android Rom 移植知识普及
- 深入理解 Android 系列书籍的规划路线图
- Android 4.1 初识 - 7月12号
- Android 4.1 初识 - 7月13号
- Android 4.1 Surface 系统变化说明
- Android BSP 成长计划随笔之虚拟设备搭建和 input 系统
- 深入理解 Android 写作背后的故事
- 随笔之 GoldFish Kernel 启动过程中 arm 汇编分析
- Android Project Butter 分析
- Android Says Bonjour
- MTP in Android
- DRM in Android
- Tieto 公司 Android 多窗口解决方案展示
- 深入理解 SELinux SEAndroid 之二
- 深入理解 SELinux SEAndroid(最后部分)
- 前言
- 附录
- 第一章 准备工作
- 第二章 深入理解 Netd
- 第三章 Wi-Fi 基础知识
- 第四章 深入理解 wpa_supplicant
- 第五章 深入理解 WifiService
- 第六章 深入理解 wi-Fi Simple Configuration
- 第七章 深入理解 Wi-Fi P2P
- 第八章 深入理解 NFC
- 第九章 深入理解 GPS
- Google I/O 2014 之 Android 面面观
- 深入理解 Android 之 Java Security 第一部分
- 深入理解 Android 之 Java Security 第二部分(Final)
- 深入理解 Android 之设备加密 Device Encryption
- 第一章 阅读前的准备工作
- 第二章 深入理解 JNI
- 第三章 深入理解 init
- 第四章 深入理解 Zygote
- 第五章 深入理解常见类
- 第六章 深入理解 Binder
- 第七章 深入理解 Audio 系统
- 第八章 深入理解 Surface 系统
- 第九章 深入理解 Vold 和 Rild
- 第十章 深入理解 MediaScanner
- 第一章 开发环境部署
- 第二章 深入理解 Java Binder 和 MessageQueue
- 第三章 深入理解 SystemServer
- 第四章 深入理解 PackageManagerService
- 第五章 深入理解 PowerManagerService
- 第六章 深入理解 ActivityManagerService
- 第七章 深入理解 ContentProvider
- 第八章 深入理解 ContentService 和 AccountManagerService
- 第一章 开发环境部署
- 第二章 深入理解 Java Binder 和 MessageQueue
- 第三章 深入理解 AudioService
- 第四章 深入理解 WindowManagerService
- 第五章 深入理解 Android 输入系统
- 第六章 深入理解控件(ViewRoot)系统
- 第七章 深入理解 SystemUI
- 第八章 深入理解 Android 壁纸
- 边缘设备、系统及计算杂谈(16)——Apache 学习
- 边缘设备、系统及计算杂谈(17)——Ansible 学习
- ZFS 和 LVM
- Android 4.2 蓝牙介绍
- 了解一下 Android 10 中的 APEX
- 关于 Android 学习的三个终极问题
- 深入理解 Android 之 AOP
- Android 系统性能调优工具介绍
- 深入理解 SELinux SEAndroid(第一部分)
- Android Wi-Fi Display(Miracast)介绍
- 深入理解 Android 之 Gradle
第八章 深入理解 NFC
本章主要内容:
- 介绍NFC基础知识;
- 介绍Android中NFC实现。
8.1 概述
NFC,全称是Near Field Communication,中译为近场通信,也叫做近距离无线通信技术。该技术最早由Philips和Sony两家公司于2002年末联合推出。2004年,Nokia、Philips、Sony等公司还共同组建了一个名为NFC Forum的非盈利性组织来推广和发展NFC技术。NFC Forum的职责和Wi-Fi Alliance类似,它制定NFC相关的技术标准,同时还通过NFC认证测试[1]来保证各厂家的NFC产品符合NFC规范。
从原理上说,NFC和Wi-Fi类似,二者都利用无线射频技术来实现设备之间的通信。不过,和Wi-Fi相比,NFC的工作频率为13.56MHz,有效距离为4cm左右,目前所支持的数据传输速率有106Kbps、212Kbps和424Kbps三种。
通过对上述NFC无线射频参数相关的介绍可知,NFC所针对的应用场景和Wi-Fi明显不同。以NFC有效距离为4cm为例,这么短的有效距离本身就要求交互双方必须有某种程度的相互信任。否则,一个用户不会随便让另外一个用户的设备这么近得靠近自己的设备。
NFC还有其他非常多和广泛的应用场景,感兴趣的读者请阅读参考资料[1]。
NFC技术从创建到现在已超过10年,在技术层面上已相当完善。但NFC至今未能像Wi-Fi一样被普及,其中一个重要原因就是大众消费者没有一个合适的载体来使用它。显然,随着越来越多携带NFC功能的Android智能终端的出现,NFC这种有价无市的状况有望很快得以改善。
很多专家预测2014或2015年是NFC技术推广和普及爆发的元年。但奇怪的是智能移动终端三巨头中最重要的iPhone却迟迟没有支持NFC,这不免给它的前景蒙上了一层阴影。不过,最近也有消息称苹果秘密申请了一项和NFC相关的专利。总之,笔者希望那些方便广大群众的技术不要因为某些利益集团的纠葛而不能得到推广和应用。
本章将从以下几个方面来介绍NFC以及它在Android平台中的实现:
- 首先将介绍NFC基础知识,它是本章的核心内容。相比Wi-Fi而言,本章介绍的NFC理论知识相对比较简单。相信读者能轻松掌握它们。
- 然后将介绍Android平台中NFC实现,这部分内容包括NFC客户端示例以及NFC系统模块。
- 最后将探讨目前一些开源NFC相关模块的实现情况。
先来看NFC基础知识。
8.2 基础知识介绍
简而言之,NFC是从多种不同技术基础上综合发展而来,图8-1[2]展示了NFC技术的演化历程。
8.2.1 概述
图8-1 NFC技术演化历程
通过图8-1所示的NFC技术演化历程可知,NFC融合了三条主要的技术发展路线[2]:
- 最左边一条为RFID技术路线,即无线射频识别技术。该技术路线发源于条形码(Barcodes),然后发展出了RFID,最终出现了NFC中的两个重要组件NFC Tag(标签)和NFC Reader。NFC Tag的作用和Barcodes类似,它是一种用于存储数据的被动式(Passive)RFID Tag,其最重要的特征就是NFC Tag自身不包含电源组件,所以它工作时必须依靠其他设备(比如NFC Reader)通过电磁感应的方式向其输送电能。和NFC Tag相对应的组件是NFC Reader,它首先通过电磁感应向NFC Tag输送电能使其工作,然后再根据相关的无线射频通信协议来存取NFC Tag上的数据。
- 最右边一条为磁条卡(Magnetic Strip Cards)技术路线,该路线最终演化出了NFC使用的Proximity Coupling Smart Card(有效距离在10cm之内,对应的规范为ISO/IEC 14443。注意,图8-1中的Close Coupling Smart Card的有效距离为1cm之内,对应的规范为ISO/IEC 10536。Vicinity Coupling Smart Card的有效距离为1m之内,对应的规范为ISO/IEC 15693)技术。粗看上去Smart Card和RFID Tag类似,例如二者都只存储一些数据,而且自身都没有电源组件,但Smart Card在安全性上的要求远比RFID Tag严格。另外,Smart Card上还能运行一些小的嵌入式系统(如Java Card OS)或者应用程序(Applets)以完成更为复杂的工作。
- 中间一条技术路线为移动终端,它演化出了携带NFC功能的终端设备。随着移动终端越来越智能,NFC和这些设备也融合得更加紧密,使得NFC的应用场景得到了较大的拓展。本书第六章在介绍Wi-Fi Simple Configuration时(第6章6.1“概述”一节)曾介绍过一个例子,即智能手机可通过NFC来和AP交换安全配置信息。一个与之类似的例子是NFC Connection Handover技术,它描述了两台智能终端如何通过NFC相关协议来选择合适的数据传输方式(例如是Bluetooth还是Wi-Fi。受限于传输速率以及有效距离,NFC本身不适合大数据量传输)。
了解NFC技术的演化历程之后,我们来看看NFC现在的样子。图8-2所示为NFC技术框架[3]:
图8-2 NFC技术框架
由图8-2可知:
- 从用户角度(即图中的Applications层之上)来看,NFC有三种运行模式(operation mode),分别是Reader/Write模式(简称R/W,和NFC Tag/NFC Reader相关)、Peer-to-Peer模式(简称P2P,它支持两个NFC设备交互)以及NFC Card Emulation Mode(简称CE,它能把携带NFC功能的设备模拟成Smart Card,这样就能实现诸如手机支付、门禁卡之类的功能)。
- Application之下的三个箭头描述了三种运行模式所使用的协议栈。这部分内容将留待下文再分析。
- NFC使用的是无线射频技术。在RF层,与之相关的规范是ISO 18092(NFC Interface and Protocol I,简称NFCIP-1,该规范定义了NFC RF层的工作流程)和ISO 14443 Type A,Type B和Felica。ISO 14443全称为非接触式IC卡标准,它从RF层面定义了如何与不同的非接触式IC卡(其实物可以是NFC Tag、RFID Tag、Smart Cards)交互。ISO 14443定义了Type A和Type B两种非接触式IC卡。其中,Type A最早由Philips公司制订(其生产的芯片商标名为MIFARE,现在由从Philips独立出来的NXP公司拥有,目前世界上70%左右的非接触式IC卡都使用了MIFARE芯片,例如北京市的公交卡),Type B(主要用在法国市场)由其他公司制订,二者最终都成为ISO标准。Felica(也被称为Type F)由Sony开发,它最终没有成为ISO标准,而是成为日本工业标准JIS X6319-4,所以Felica主要用于日本市场。Type A、B和F主要区别在于RF层的信号调制解调方法、传输速率及数据编码方式上。关于ISO 14443和Felica之间的区别,请读者阅读参考资料[4]。
- RF层之上是Mode Switch,它用于确定对端NFC Device的类型并选择合适的RF层协议与之通信。
由于NFC是从多种技术综合发展而来,所以读者在学习NFC时将会碰到很多规范,如上文所提到的ISO 18092以及ISO 14443、Felica等。除了ISO等标准组织制订的规范外,NFC Forum也制订了一系列的标准和规范。
由于篇幅问题,本章仅打算介绍NFC Forum定义的一些规范。对ISO相关规范感兴趣的读者可在本章基础之上再自行阅读它们。
图8-3所示为与NFC技术框架相对应的NFC Forum所定义的规范框架[3]。
图8-3 NFC Forum规范框架
由图8-3所示的NFC Forum规范框架可知:
- NFC Forum本身只定义了P2P模式和R/W模式相关的规范。规范的细节将留待下文再详细介绍。CE模式比较复杂,下文也会讨论和它相关的一些知识。
- 在RF层,NFC Forum定义了三个主要规范,即Analog Specifications(该规范描述了NFC设备RF层的电气特性)、Digital Protocal Specification(该规范在ISO 18092、ISO 14443及JIS X6319-4之上定义了NFC设备之间的数字通信协议,它使得基于不同底层协议例如Type A或Type F的NFC设备之间或者NFC设备与其他使用ISO 18092等规范的设备之间能够交互)和NFC Activities Specification(该规范为各运行模式对应的协议栈提供支持,例如P2P模式下两个NFC设备如何建立链接,R/W模式下NFC Device如何操作NFC Tag)。
- 图8-3最上层所示的Reference Applications表示NFC Forum在应用层面所定义的一些规范。目前有两个规范,一个是Connection Handover(两个NFC设备通过它来协商用蓝牙或Wi-Fi来开展后续的数据传输工作),另一个是Personal Health Device Commnuication(该规范定义了如何利用NFC技术在个人健康设备之间交换数据信息)。
另外,除了图8-3所示的规范外,NFC还制订了一个名为NFC Controller Interface(简写为NCI)的规范,该规范制订了一套交互接口,使得主机设备(Device Host,以手机为例,NFC芯片被集成到某个手机中,那么手机就是Device Host)能够使用这套接口来和NFC芯片交互。
下面,我们将先讨论NFC三种运行模式,而NCI相关知识将留待本节最后再来介绍。
提示:关于NFC Forum制订的各种规范及简要说明,请读者参考资料[5]。
8.2.3 运行模式介绍
以支持NFC功能的智能终端为例,NFC R/W运行模式所包含的组件如图8-4[6]所示:
图8-4 R/W运行模式组件
图8-4展示了一个包含NFC芯片的智能终端与NFC Tag交互所涉及到的组件,其中:
- 先看最左边的智能终端,它扮演NFC Reader角色。位于其内部的NFC芯片包含NFC Controller(NFC控制器,它可和Device Host或Secure Element安全单元交互)、Antenna(天线)和Contactless Front-End(非接触式前端,简称CLF,负责射频信号的调制解调等工作)三个部分。注意,图中所示的SWP等内容将留待8.2.4节再介绍。
- 在R/W模式中,交互操作的发起方只能是NFC Reader,故它也被称为Initiator或Active Device。
- 再来看最右边的NFC Tag,由于它需要NFC Reader通过电磁感应为其提供电能,所以在R/W模式中,NFC Tag只能作为交互操作的Target(也被称为Passive Device)。NFC Forum定义了四种类型的Tag,分别为Type 1、Type 2、Type 3和Type 4。这四种类型NFC Tag的区别在于存储空间大小,数据传输率以及底层使用的协议上。下文的表8-1列举了它们的不同点。
- NFC Forum定义了两个通用的数据结构用于在NFC Device之间(包括R/W模式中的NFC Reader和NFC Tag)传递数据。这两个通用数据结构分别是NFC Data Exchange Format(简写为NDEF)以及NFC Record。
我们先来看NFC 4种不同Type的Tag有何区别,如表8-1[7]所示:
表8-1 NFC Tag Type说明
参数 | Type 1 | Type 2 | Type 3 | Type 4 |
对应规范 | ISO 14443 Type A | ISO 14443 Type A | Felica | ISO 14443 Type A,Type B |
常见芯片名 | Topaz | MIFARE | Felica | MIFARE-DESFire |
存储容量 | 最大1KB | 最大2KB | 最大1MB | 最大64KB |
读写速率 | 106kbps | 106kbps | 212kbps | 106-424kbps |
价格 | 低 | 低 | 高 | 中等/高 |
安全性 | 数字签名保护 | 不安全 | 数字签名保护 | 可选 |
说明 | Topaz由Innovision公司推出 | MIFARE由NXP公司推出 | 由Sony公司推出,价格比较贵 | 这类芯片在出厂时就被配置好是否只读或可读写 |
这里需要特别指出的一点是:虽然NFC Froum只有四种Type的Tag,但由于NFC本身源自RFID技术,二者在一些底层协议上也相互兼容,所以很多RFID Tag也能被NFC Reader识别和操作。为了书写方便,除非特别说明,本章所指的NFC Tag也包括那些和NFC相关规范兼容的RFID Tag。
虽然NFC Tag有四种不同类型(由上文可知,实际上能被NFC Reader读写的RFID Tag还远不止四种),但为了保证最大得兼容性,NFC Forum建议NFC设备之间尽量使用通用数据结构NDEF和NFC Record来交换信息。
NFC R/W模式涉及到的规范比较多,包括:
- NFC Reader如何与不同Type的Tag交互,这部分内容涉及到非常底层的一些协议。
- NDEF和一些常用数据类型定义。
出于篇幅和实用性考虑,笔者拟仅介绍NDEF和相关的数据类型,感兴趣的读者可自行研究NFC Reader和Tag之间的交互协议。
1 NDEF和NFC Record介绍
(1) NDEF和NFC Record[8][9]
根据NFC Forum的定义,R/W模式下,NFC设备之间每一次交互的数据都会封装在一个NDEF Message中,而一个NDEF Message可以包含多个NFC Record,真正的数据则封装在NFC Record中。图8-5展示了NDEF Message和NFC Record之间的关系。
图8-5 NDEF Message和NFC Record的关系
由图8-5可知:
- 一个NDEF Message可包含一个或多个NFC Record。
- 在一个NDEF Message中,第一个NFC Record需设置其MB位(Message Begin)为1,表示它是该消息中第一个NFC Record,最后一个NFC Record需设置ME位(Message End)位为1,表示它是此消息中最后一个NFC Record。
NFC Record本身的组织结构则如图8-6所示:
图8-6 NFC Record组织结构
由图8-6可知:
- NFC Record分为NFC Record Header(头部信息)和Payload(数据载荷)两大部分。
- Record Header中最重要的是其第一个字节。该字节有6个标志信息,它们分别是MB(Message Begin标志)、ME(Message End标志)、CF(Chunk Flag标志,表示该Record是否为分片Record)、SR(Short Record标志。如果该标志被设置,则图8-6中的4个PayLoad Length字段仅需一个,这表明PayLoad数据长度将限制在255个字节以内)、IL(ID_LENGTH标志,它用于指明Header中是否包含ID Length和ID这两个字段)、TNF(Type Name Format标志,用于指明PayLoad的类型,NFC Forum定义了一些常用的PayLoad类型,详情见下文分析)。
- Type Length指明Record Header中Type字段的长度。
- PayLoad Length 3到PayLoad Length 0这4个字段共同指明PayLoad字段的长度。如果SR标志被设置,则Record Header仅包含一个PayLoad Length字段。
- ID Length指明ID字段的长度。如图IL标志未设置,则ID Length和ID字段都不存在。
- Type字段表明PayLoad的类型,NFC Forum定义了诸如URI、MIME等类型的Type,其目的是为了方便不同的应用来处理不同Type的数据,例如URI类型的数据就交给浏览器来处理。
- ID:ID需要配合URI类型的PayLoad一起使用,它使得一个NFC Record能通过ID来指向另外一个NFC Record。
NFC Record中,常令初学者感到困惑的是TNF字段,其作用是什么?来看下文。
=====================略略略=============
8.3.2 系统模块介绍
正如本节一开始所介绍的那样,Android平台中,NFC系统模块运行在一个名为“com.android.nfc”的进程中,该进程对应的应用程序文件名为Nfc.apk。NFC系统模块包含的组件非常多,所以笔者拟通过三条分析路线来向读者介绍它:
- 首先介绍NFC系统模块的核心NfcService和一些重要成员的作用及之间的关系。
- 然后介绍R/W模式下,NFC Tag的处理。
- 介绍Android Beam的实现。
- 最后将介绍CE模式相关的处理。
马上来看NfcService。
1. NfcService介绍
Nfc.apk源码中包含一个NfcApplication类。当该应用启动时,NfcApplication的onCreate函数将被调用。正是在这个onCreate函数中,NFC系统模块的核心成员NfcService得以创建。我们直接来看NfcService的构造函数:
[-->NfcService.java::NfcService]
public NfcService(Application nfcApplication) {
//NFC系统模块重要成员:
mNfcTagService = new TagService();//TagService用于和NFC Tag交互
//NfcAdapterService用于和Android系统中其他使用NfcService的客户端交互
mNfcAdapter = new NfcAdapterService();
//NfcAdapterExtrasService用于和Android系统中使用Card Emulation模式的客户端交互
mExtrasService = new NfcAdapterExtrasService();
sService = this; mContext = nfcApplication;
//NativeNfcManager由dhimpl模块实现,用于和具体芯片厂商提供的NFC模块交互
mDeviceHost = new NativeNfcManager(mContext, this);
//HandoverManager处理Connection Handover工作
HandoverManager handoverManager = new HandoverManager(mContext);
//NfcDispatcher用于向客户端派发NFC Tag相关的通知
mNfcDispatcher = new NfcDispatcher(mContext, handoverManager);
//P2pLinkManager用于处理LLCP相关的工作
mP2pLinkManager = new P2pLinkManager(mContext, handoverManager,
mDeviceHost.getDefaultLlcpMiu(),
mDeviceHost.getDefaultLlcpRwSize());
//NativeNfcSecureElement用于和SE交互,它也由dhimpl模块实现
mSecureElement = new NativeNfcSecureElement(mContext);
mEeRoutingState = ROUTE_OFF;
//NfceeAccessControl用于判断哪些应用程序有权限操作NFCEE。它将读取/etc/nfcee_access.xml文件的
//内容。nfcee_access.xml内容比较简单,请读者参考Nfc目录下的etc/sample_nfcee_access.xml来学习
mNfceeAccessControl = new NfceeAccessControl(mContext);
......
//向系统注册一个名为“nfc”的服务。注意,SERVICE_NAME的值为“nfc”。该服务对应的对象为mNfcAdapter
ServiceManager.addService(SERVICE_NAME, mNfcAdapter);
//注册广播事件监听对象。NfcService对屏幕状态、应用程序安装和卸载等广播事件感兴趣。这部分内容请读者
//自行研究
......
//EnableDisableTask为一个AsyncTask,TASK_BOOT用于NfcService其他初始化工作
new EnableDisableTask().execute(TASK_BOOT);
}
由上述代码可知,NfcService在其构造函数中:
- 首先创建了NFC系统模块的几个核心成员。下文将详细介绍它们的作用及之间的关系。
- NfcService向Binder系统添加了一个名为“nfc”的服务,该服务对应的Binder对象为mNfcAdapter,类型为NfcAdapter。
- 通过一个AysncTask(代码中的EnableDisableTask)完成NfcService其他初始化工作。
下面马上来看NFC系统模块核心成员。
(1) NfcService核心成员介绍
图8-35所示为NfcAdapter、TagService等相关成员的类信息
图8-35 NfcAdapter、TagService及相关类成员结构图
图8-35中:
- 左上角的NfcAdapter包含一个类型为INfcAdapter的sService成员变量,该变量通过Android Binder机制来和NfcService内部类NfcAdapter的实例(即上述代码中的mAdapter)交互。NfcService内部的NfcAdapter对象即是注册到Android系统服务中的那个名为“nfc”的Binder服务端对象。
- 左上角的NfcAdapter还包含一个类型为INfcTag的sTagService成员变量,该变量通过Android Binder机制来和NfcService内部类TagService的实例(即上述代码中的mNfcTagService)交互。INfcTag接口封装了对Tag操作相关的函数。注意,前面所示的Nfc客户端示例中并没有直接使用INfcTag接口的地方,但表8-12“android.nfc.tech支持的Tag种类”所列的各种Tech类内部需要通过ITag接口来操作NFC Tag。
- 图中下方的NfcAdapterExtras包含一个类型为INfcAdapterExtras的sService成员变量,它也通过Android Binder机制来和NfcService内部类NfcAdapterService的实例(即上述代码中的mExtrasService)交互。
接着来看NfcService和NativeNfcManager,它们的类家族如图8-36所示:
图8-36 NativeNfcManager和NfcService类家族
图8-36中:
- Android NFC系统模块通过接口类DeviceHost和其内部的接口类LlcpServerSocket、DeviceHostListener、LlcpSocket、LlcpConnectionlessSocket、NfcDepEndpoint、TagEndpoint将NFC系统模块中那些与NFC芯片无关的处理逻辑与那些和芯片相关的处理逻辑进行了有效解耦。图8-36中那些以“Native”开头的类均定义在packages/app/Nfc/nxp目录下,所以它们和NXP公司的NFC芯片相关。
- DeviceHost这些接口中,DeviceHost类用于和底层NFC芯片交互,TagEndpoint用于和NFC Tag交互、NfcDepEndpoint用于和P2P对端设备交互、LlcpSocket和LlcpServerSocket分别用于LLCP中有链接数据传输服务的客户端和服务端、LlcpConnectionlessSocket用于LLCP中无连接数据传输服务。另外,DeviceHostListener也非常重要,它用于NativeNfcManager往NfcService传递NFC相关的通知事件。例如其中的onRemoteEndpointDiscovered代表搜索到一个NFC Tag、onLlcpActivited代表本机和对端NFC设备进入Link Activation(链路激活)阶段。
- NativeNfcManager实现了DeviceHost接口,以NXP公司的NativeNfcManager为例,它将通过libnfc_jni及libnfc和NXP公司的NFC芯片交互。
- NativeNfcSecureElement用来和Secure Element交互。
接下来要出场得是HandoverManager以及P2pLinkManager,它们的家族关系如图8-37所示:
图8-37 P2pLinkManager家族关系图
图8-37所示的P2pLinkManager家族关系图非常复杂,图中的各成员说明如下:
- P2pLinkManager包含三个和传输相关的Server,分别是SnepServer、NdefPushServer以及HandoverServer。每一个Server都定义了相关的回调接口类(如SnepServer.callback),这些回调接口类的实现均由P2pLinkManager的内部类来实现。
- HandoverServer负责处理NFC Connection Handover协议,而具体的数据传输则由HandoverManager来实现。由图中HandoverMangar的mBluetoothAdapter可知,Android默认使用蓝牙来传输数据。提示:这部分内容请读者学完本章后自行研究
- P2pEventManager用于处理NFC P2P中和用户交互相关的逻辑。例如当搜索到一个P2P设备时,手机将会震动并发出提示音。
- SendUi实现了类似图8-29“Beam示例”左图的界面及用户触摸事件处理。在Android平台中,当两个设备LLCP链路被激活时,SendUi将显示出来。其界面组成部分包括两个部分,一个是SendUi界面显示之前手机的截屏图像,另外一个是“触摸即可发送”的文本提示信息。当用户触摸SendUi界面时,数据将被发送出去。
介绍完NfcService的几个核心成员后,马上来看NfcService构造函数中最后创建的那个EnableDisableTask,由于设置了参数为TASK_BOOT,故最终被执行的函数为enableInternal。
(2) enableInternal分析
[-->NfcService.java::EnableDisableTask: enableInternal]
boolean enableInternal() {
......
//启动一个WatchDog线程用来监视NFC底层操作是否超时
WatchDogThread watchDog = new WatchDogThread("enableInternal", INIT_WATCHDOG_MS);
watchDog.start();
try {
mRoutingWakeLock.acquire();
try {
//初始化NFC底层模块,这部分内容请读者自行阅读
if (!mDeviceHost.initialize()) {......}
} finally {
mRoutingWakeLock.release();
}
} finally {
watchDog.cancel();
}
synchronized(NfcService.this) {
mObjectMap.clear();
// mIsNdefPushEnabled判断是否启用NPP协议,可在Settings中设置
mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true);
updateState(NfcAdapter.STATE_ON);
}
initSoundPool();//创建SoundPool,用于播放NFC相关事件的通知音
applyRouting(true);//启动NFC Polling流程,一旦搜索到周围的NFC设备,相关回调将被调用
return true;
}
我们重点关注上面代码中和P2pLinkManager相关的enableDisable函数,其代码如下所示:
[-->P2pLinkManager.java::enableDisable]
public void enableDisable(boolean sendEnable, boolean receiveEnable) {
synchronized (this) {//假设参数sendEnable和receiveEnable为true
if (!mIsReceiveEnabled && receiveEnable) {
/*
启动SnepServer、NdefPushServer和HandoverServer
下面这三个成员变量均在P2pLinkManager的构造函数中被创建,这部分内容请读者自行阅读
本章将只分析SnepServer
*/
mDefaultSnepServer.start();
mNdefPushServer.start();
mHandoverServer.start();
if (mEchoServer != null) //EchoServer用于测试,以后代码分析将忽略它
mHandler.sendEmptyMessage(MSG_START_ECHOSERVER);
}......
mIsSendEnabled = sendEnable;
mIsReceiveEnabled = receiveEnable;
}
}
(3) SnepServer start分析
SnepServer的start函数将创建一个ServerThread线程对象,其run函数代码如下所示:
[-->SnepServer.java:: ServerThread:run]
public void run() {//注意:为了方便阅读,此处代码去掉了synchronized和try/catch等一些代码逻辑
boolean threadRunning;
threadRunning = mThreadRunning;
while (threadRunning) {
//创建一个LlcpServerSocket,其中mServiceSap值为0x04,mServiceName为“urn:nfc:sn:sne”
//mMiu和mRwSize为本机NFC LLCP层的MIU和RW大小。1024为内部缓冲区大小,单位为字节
mServerSocket = NfcService.getInstance().createLlcpServerSocket(mServiceSap,
mServiceName, mMiu, mRwSize, 1024);
LlcpServerSocket serverSocket;
serverSocket = mServerSocket;
//等待客户端的链接
LlcpSocket communicationSocket = serverSocket.accept();
if (communicationSocket != null) {
//获取客户端设备的MIU
int miu = communicationSocket.getRemoteMiu();
/*
判断分片大小。mFragmentLength默认为-1。MIU非常重要。例如本机的MIU为1024,而对端设备
的MIU为512,那么本机在向对端发送数据时,每次发送的数据不能超过对端MIU即512个字节
*/
int fragmentLength = (mFragmentLength == -1) ?
miu : Math.min(miu, mFragmentLength);
//每一个连接成功的客户端对应一个ConnectionThread,其内容我们留待下文再详细分析
new ConnectionThread(communicationSocket, fragmentLength).start();
}
}
mServerSocket.close();
}
}
NfcService初始化完毕后,手机中的NFC模块就进入工作状态,一旦有Tag或其他设备进入其有效距离,NFC模块即可开展相关工作。
下面先来分析NFC Tag的处理流程。
================略略略============8.5 本章总结和参考资料说明
8.5.1 本章总结
本章对NFC进行了详细介绍,主要内容包括:
- NFC理论知识,这部分内容主要围绕NFC三种运行模式进行了相关讨论。
- 介绍了Android系统中NFC模块的结构并通过三个示例程序向读者展示了Android中NFC API的一些知识
- 最后,我们对NFC系统模块NfcService及其它重要成员进行了介绍,并详细分析了NFC Tag分发以及Android Beam的实现细节。
最后,希望读者在本章的基础上,完成下列的一些任务:
- 学习NFC Forum中的其他规范。
- 结合NFC Forum中的Connection Handover规范,分析Android中NFC Handover的实现代码。
8.5.2 参考资料说明
概述
[1] Near Field Communication From Theory to Practice第1章“Executive Summary”和第2章“Towards NFC Era”。
这本书是笔者目前所阅读的关于NFC最为详尽的资料,建议初学者仔细阅读它,尤其是前三章。
NFC基础知识介绍
NFC概述
[2] Near Field Communication From Theory to Practice第2章“Towards NFC Era”图2-1,略有修改。
[3] NFC Technology Overview
下载地址为http://www.nfc-forum.org/resources/presentations/NFCForum_Technical_WIMA09.pdf。该资料为NFC Forum官方提供,概要性得介绍了NFC技术。
[4] NFC vs ISO 14443 vs Felica
该文档介绍了目前NFC、ISO 14443和Felica之间的区别,文档下载地址为
http://developer.nokia.com/Community/Blogs/resources/300066/Philips-NFC-vs-ISO14443-vs-Felica-SLIDES.pdf
[5] http://www.nfc-forum.org/specs/spec_list/
该网页介绍了当前NFC Forum官方各个技术文档的主要内容,建议读者下载NFC Forum技术文档前先阅读此网页。
NFC Reader/Write运行模式介绍
[6] Near Field Communication From Theory to Practice第3章3.5节“Reader/Writer Operating Mode Essentials”
该节对NFC R/W运行模式进行了相关介绍
[7] http://www.nfc-forum.org/resources/white_papers/NXP_BV_Type_Tags_White_Paper-Apr_09.pdf
该文档可在NFC Forum官网上下载,属于NXP公司的一篇介绍NFC Tag Type的白皮书,通熟易懂,建议不熟悉的读者仔细研究它。
NDEF和NFC Record介绍
[8] NFC Data Exchange Format Technical Specification
[9] NFC Record Type Definition Technical Specification
[10] URI Record Type Definition Technical Specification
[11] Text Record Type Definition Technical Specification
NFC Forum官方文档,难度都比较小。
NFC P2P运行模式介绍
[12] Logical Link Control Protocol Technical Specification
LLCP的官方协议,建议读者先阅读本章相关章节后再去看它。
[13] NFC Digital Protocol Technical Specification
阅读此规范前,最好看看ISO 18092(http://www.docin.com/p-586980527.html)。
[14] Simple NDEF Exchange Protocol Technical Specification
SNEP官方协议,非常简单。
NFCCE运行模式介绍
[15] Near Field Communication From Theory to Practice第3章3.7节“Card Emulation Operating Mode Essentials”
[16] Near Field Communication From Theory to Practice第3章3.3节“General Architecture of NFC Enabled Mobile Phones”
这两个资料详细介绍了NFC Enabled Phone和Card Emulation Mode,读者可在阅读完本节基础上再去看它。
[17] http://www.nfc.cc/technology/nxp-nfc-chips/
NXP公司pn65 NFC系列芯片模块图
[18] http://www.chinaz.com/biz/2011/0827/207232.shtml
[19] http://kan.weibo.com/con/3616344461572955
中国市场上运营商和银联这两大利益集团联合推广NFC-SIM卡方案
NCI介绍
[20] NFC Controller Interface (NCI) Specification
NCI官方文档,长达140多页。不过读者无需了解其细节,只要掌握NCI架构及相关模块的功能即可。
[21] https://github.com/charsyam/linux-kernel-3.8/blob/master/Documentation/networking/nfc.txt
Linux kernel 3.8中关于NFC Subsystem的介绍
NFC规范列表
[22] Professional NFC Application Development for Android第1章“Overview of NFC”表1-2
此书由[1]同一团队编写,对Android上如何开发NFC应用进行了详细介绍。
NFC CE示例介绍
[23] http://stackoverflow.com/questions/15065172/nfcee-execution-environment-hardware-or-library-module
这个资料介绍了Android中如何操作NFC EE。读者不妨看看
[24] http://nelenkov.blogspot.jp/2012/08/accessing-embedded-secure-element-in.html
[25] http://nelenkov.blogspot.de/2012/08/android-secure-element-execution.html
上面这两个资料非常详尽得介绍了Android SE方面的知识,文章质量非常高。不过需要翻墙才能看。
NFC HAL层探讨
[26] http://elinux.org/images/d/d1/Near_Field_Communication_with_Linux.pdf
内容和[21]类似。
关于NFC认证测试,请参考http://www.nfc-forum.org/certification/certification-testing/。
2013年5月起,北京可用支持NFC功能的手机当公交卡乘坐地铁和公交,该措施无疑为NFC的推广起到了积极作用。
注意,图8-26对应的Android版本为4.2。
根据审稿专家的意见,NFC Tag Technologies分为supported和optional supported 两种。optional supported表示某些Tag Technology在某些平台上不受支持。笔者此处采用的是Android SDK关于Tag Technology的解释,详情见 http://developer.android.com/reference/android/nfc/tech/package-summary.html 。如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论