首先感谢各位兄弟姐妹们的耐心等待。根据今天得到的消息,本书预计在下周各大网店提供预订。注意,此处连载的是未经出版社编辑的原始稿件,所以样子会有些非专业。
注意,如下是本章目录,本文节选8.1~8.2.2.2,8.3.2.1和8.5
为了方便读者深入学习,本系列连载都会将作者研究过
程中所学习的参考文献列出来
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基础知识。
简而言之,NFC是从多种不同技术基础上综合发展而来,图8-1[2]展示了NFC技术的演化历程。
图8-1 NFC技术演化历程
通过图8-1所示的NFC技术演化历程可知,NFC融合了三条主要的技术发展路线[2]:
了解NFC技术的演化历程之后,我们来看看NFC现在的样子。图8-2所示为NFC技术框架[3]:
图8-2 NFC技术框架
由图8-2可知:
由于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规范框架可知:
另外,除了图8-3所示的规范外,NFC还制订了一个名为NFC Controller Interface(简写为NCI)的规范,该规范制订了一套交互接口,使得主机设备(Device Host,以手机为例,NFC芯片被集成到某个手机中,那么手机就是Device Host)能够使用这套接口来和NFC芯片交互。
下面,我们将先讨论NFC三种运行模式,而NCI相关知识将留待本节最后再来介绍。
提示:关于NFC Forum制订的各种规范及简要说明,请读者参考资料[5]。
以支持NFC功能的智能终端为例,NFC R/W运行模式所包含的组件如图8-4[6]所示:
图8-4 R/W运行模式组件
图8-4展示了一个包含NFC芯片的智能终端与NFC Tag交互所涉及到的组件,其中:
我们先来看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模式涉及到的规范比较多,包括:
出于篇幅和实用性考虑,笔者拟仅介绍NDEF和相关的数据类型,感兴趣的读者可自行研究NFC Reader和Tag之间的交互协议。
根据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可知:
NFC Record本身的组织结构则如图8-6所示:
图8-6 NFC Record组织结构
由图8-6可知:
NFC Record中,常令初学者感到困惑的是TNF字段,其作用是什么?来看下文。
=====================略略略=============
正如本节一开始所介绍的那样,Android平台中,NFC系统模块运行在一个名为“com.android.nfc”的进程中,该进程对应的应用程序文件名为Nfc.apk。NFC系统模块包含的组件非常多,所以笔者拟通过三条分析路线来向读者介绍它:
马上来看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系统模块核心成员。
图8-35所示为NfcAdapter、TagService等相关成员的类信息
图8-35 NfcAdapter、TagService及相关类成员结构图
图8-35中:
接着来看NfcService和NativeNfcManager,它们的类家族如图8-36所示:
图8-36 NativeNfcManager和NfcService类家族
图8-36中:
接下来要出场得是HandoverManager以及P2pLinkManager,它们的家族关系如图8-37所示:
图8-37 P2pLinkManager家族关系图
图8-37所示的P2pLinkManager家族关系图非常复杂,图中的各成员说明如下:
介绍完NfcService的几个核心成员后,马上来看NfcService构造函数中最后创建的那个EnableDisableTask,由于设置了参数为TASK_BOOT,故最终被执行的函数为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;
}
}
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的处理流程。
本章对NFC进行了详细介绍,主要内容包括:
最后,希望读者在本章的基础上,完成下列的一些任务:
[1] Near Field Communication From Theory to Practice第1章“Executive Summary”和第2章“Towards NFC Era”。
这本书是笔者目前所阅读的关于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技术文档前先阅读此网页。
[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的白皮书,通熟易懂,建议不熟悉的读者仔细研究它。
[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官方文档,难度都比较小。
[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官方协议,非常简单。
[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卡方案
[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的介绍
[22] Professional NFC Application Development for Android第1章“Overview of NFC”表1-2
此书由[1]同一团队编写,对Android上如何开发NFC应用进行了详细介绍。
[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方面的知识,文章质量非常高。不过需要翻墙才能看。
[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。《深入理解Android:Wi-Fi,NFC和GPS》章节连载[节选]--第八章 深入理解NFC,布布扣,bubuko.com
《深入理解Android:Wi-Fi,NFC和GPS》章节连载[节选]--第八章 深入理解NFC
原文:http://blog.csdn.net/innost/article/details/21827091