《深入理解Android:Wi-Fi,NFC和GPS》章节连载[节选]--第八章 深入理解NFC

时间:2014-03-22 22:50:36   收藏:0   阅读:919

首先感谢各位兄弟姐妹们的耐心等待。根据今天得到的消息,本书预计在下周各大网店提供预订。注意,此处连载的是未经出版社编辑的原始稿件,所以样子会有些非专业。

注意,如下是本章目录,本文节选8.1~8.2.2.2,8.3.2.1和8.5

 

为了方便读者深入学习,本系列连载都会将作者研究过

  

程中所学习的参考文献列出来

 

第8章  深入理解NFC

bubuko.com,布布扣

本章主要内容:

8.1  概述

NFC,全称是Near Field Communication,中译为近场通信,也叫做近距离无线通信技术。该技术最早由PhilipsSony两家公司于2002年末联合推出。2004年,NokiaPhilipsSony等公司还共同组建了一个名为NFC Forum的非盈利性组织来推广和发展NFC技术。NFC Forum的职责和Wi-Fi Alliance类似,它制定NFC相关的技术标准,同时还通过NFC认证测试[1]来保证各厂家的NFC产品符合NFC规范。

从原理上说,NFCWi-Fi类似,二者都利用无线射频技术来实现设备之间的通信。不过,和Wi-Fi相比,NFC的工作频率为13.56MHz,有效距离为4cm左右,目前所支持的数据传输速率有106Kbps212Kbps424Kbps三种。

通过对上述NFC无线射频参数相关的介绍可知,NFC所针对的应用场景和Wi-Fi明显不同。以NFC有效距离为4cm为例,这么短的有效距离本身就要求交互双方必须有某种程度的相互信任。否则,一个用户不会随便让另外一个用户的设备这么近得靠近自己的设备。

NFC还有其他非常多和广泛的应用场景,感兴趣的读者请阅读参考资料[1]

NFC技术从创建到现在已超过10年,在技术层面上已相当完善。但NFC至今未能像Wi-Fi一样被普及,其中一个重要原因就是大众消费者没有一个合适的载体来使用它。显然,随着越来越多携带NFC功能的Android智能终端的出现,NFC这种有价无市的状况有望很快得以改善。

很多专家预测20142015年是NFC技术推广和普及爆发的元年。但奇怪的是智能移动终端三巨头中最重要的iPhone却迟迟没有支持NFC,这不免给它的前景蒙上了一层阴影。不过,最近也有消息称苹果秘密申请了一项和NFC相关的专利。总之,笔者希望那些方便广大群众的技术不要因为某些利益集团的纠葛而不能得到推广和应用。

本章将从以下几个方面来介绍NFC以及它在Android平台中的实现:

先来看NFC基础知识。

8.2  基础知识介绍

简而言之,NFC是从多种不同技术基础上综合发展而来,图8-1[2]展示了NFC技术的演化历程。

8.2.1  概述

bubuko.com,布布扣

8-1  NFC技术演化历程

通过图8-1所示的NFC技术演化历程可知,NFC融合了三条主要的技术发展路线[2]

了解NFC技术的演化历程之后,我们来看看NFC现在的样子。图8-2所示为NFC技术框架[3]

bubuko.com,布布扣

8-2  NFC技术框架

由图8-2可知:

由于NFC是从多种技术综合发展而来,所以读者在学习NFC时将会碰到很多规范,如上文所提到的ISO 18092以及ISO 14443Felica等。除了ISO等标准组织制订的规范外,NFC Forum也制订了一系列的标准和规范。

由于篇幅问题,本章仅打算介绍NFC Forum定义的一些规范。对ISO相关规范感兴趣的读者可在本章基础之上再自行阅读它们。

8-3所示为与NFC技术框架相对应的NFC Forum所定义的规范框架[3]

bubuko.com,布布扣

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]

8.2.3  运行模式介绍

以支持NFC功能的智能终端为例,NFC R/W运行模式所包含的组件如图8-4[6]所示:

bubuko.com,布布扣

8-4  R/W运行模式组件

8-4展示了一个包含NFC芯片的智能终端与NFC Tag交互所涉及到的组件,其中:

我们先来看NFC 4种不同TypeTag有何区别,如表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 AType B

常见芯片名

Topaz

MIFARE

Felica

MIFARE-DESFire

存储容量

最大1KB

最大2KB

最大1MB

最大64KB

读写速率

106kbps

106kbps

212kbps

106-424kbps

价格

中等/

安全性

数字签名保护

不安全

数字签名保护

可选

说明

TopazInnovision公司推出

MIFARENXP公司推出

Sony公司推出,价格比较贵

这类芯片在出厂时就被配置好是否只读或可读写

这里需要特别指出的一点是:虽然NFC Froum只有四种TypeTag,但由于NFC本身源自RFID技术,二者在一些底层协议上也相互兼容,所以很多RFID Tag也能被NFC Reader识别和操作。为了书写方便,除非特别说明,本章所指的NFC Tag也包括那些和NFC相关规范兼容的RFID Tag

虽然NFC Tag有四种不同类型(由上文可知,实际上能被NFC Reader读写的RFID Tag还远不止四种),但为了保证最大得兼容性,NFC Forum建议NFC设备之间尽量使用通用数据结构NDEFNFC Record来交换信息。

NFC R/W模式涉及到的规范比较多,包括:

出于篇幅和实用性考虑,笔者拟仅介绍NDEF和相关的数据类型,感兴趣的读者可自行研究NFC ReaderTag之间的交互协议。

1 NDEF和NFC Record介绍

1  NDEFNFC Record[8][9]

根据NFC Forum的定义,R/W模式下,NFC设备之间每一次交互的数据都会封装在一个NDEF Message中,而一个NDEF Message可以包含多个NFC Record,真正的数据则封装在NFC Record中。图8-5展示了NDEF MessageNFC Record之间的关系。

bubuko.com,布布扣

8-5  NDEF MessageNFC Record的关系

由图8-5可知:

NFC Record本身的组织结构则如图8-6所示:

bubuko.com,布布扣

8-6  NFC Record组织结构

由图8-6可知:

NFC Record中,常令初学者感到困惑的是TNF字段,其作用是什么?来看下文。



 

 =====================略略略=============

8.3.2  系统模块介绍

正如本节一开始所介绍的那样,Android平台中,NFC系统模块运行在一个名为“com.android.nfc”的进程中,该进程对应的应用程序文件名为Nfc.apkNFC系统模块包含的组件非常多,所以笔者拟通过三条分析路线来向读者介绍它:

  • 首先介绍NFC系统模块的核心NfcService和一些重要成员的作用及之间的关系。
  • 然后介绍R/W模式下,NFC Tag的处理。
  • 介绍Android Beam的实现。
  • 最后将介绍CE模式相关的处理。

马上来看NfcService

1.  NfcService介绍

Nfc.apk源码中包含一个NfcApplication类。当该应用启动时,NfcApplicationonCreate函数将被调用。正是在这个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系统模块的几个核心成员。下文将详细介绍它们的作用及之间的关系。
  • NfcServiceBinder系统添加了一个名为“nfc”的服务,该服务对应的Binder对象为mNfcAdapter,类型为NfcAdapter
  • 通过一个AysncTask(代码中的EnableDisableTask)完成NfcService其他初始化工作。

下面马上来看NFC系统模块核心成员。

1  NfcService核心成员介绍

8-35所示为NfcAdapterTagService等相关成员的类信息

bubuko.com,布布扣

8-35  NfcAdapterTagService及相关类成员结构图

8-35中:

  • 左上角的NfcAdapter包含一个类型为INfcAdaptersService成员变量,该变量通过Android Binder机制来和NfcService内部类NfcAdapter的实例(即上述代码中的mAdapter)交互。NfcService内部的NfcAdapter对象即是注册到Android系统服务中的那个名为“nfc”的Binder服务端对象。
  • 左上角的NfcAdapter还包含一个类型为INfcTagsTagService成员变量,该变量通过Android Binder机制来和NfcService内部类TagService的实例(即上述代码中的mNfcTagService)交互。INfcTag接口封装了对Tag操作相关的函数。注意,前面所示的Nfc客户端示例中并没有直接使用INfcTag接口的地方,但表8-12android.nfc.tech支持的Tag种类”所列的各种Tech类内部需要通过ITag接口来操作NFC Tag
  • 图中下方的NfcAdapterExtras包含一个类型为INfcAdapterExtrassService成员变量,它也通过Android Binder机制来和NfcService内部类NfcAdapterService的实例(即上述代码中的mExtrasService)交互。

接着来看NfcServiceNativeNfcManager,它们的类家族如图8-36所示:

bubuko.com,布布扣

8-36  NativeNfcManagerNfcService类家族

8-36中:

  • Android NFC系统模块通过接口类DeviceHost和其内部的接口类LlcpServerSocketDeviceHostListenerLlcpSocketLlcpConnectionlessSocketNfcDepEndpointTagEndpointNFC系统模块中那些与NFC芯片无关的处理逻辑与那些和芯片相关的处理逻辑进行了有效解耦。图8-36中那些以“Native”开头的类均定义在packages/app/Nfc/nxp目录下,所以它们和NXP公司的NFC芯片相关。
  • DeviceHost这些接口中,DeviceHost类用于和底层NFC芯片交互,TagEndpoint用于和NFC Tag交互、NfcDepEndpoint用于和P2P对端设备交互、LlcpSocketLlcpServerSocket分别用于LLCP中有链接数据传输服务的客户端和服务端、LlcpConnectionlessSocket用于LLCP中无连接数据传输服务。另外,DeviceHostListener也非常重要,它用于NativeNfcManagerNfcService传递NFC相关的通知事件。例如其中的onRemoteEndpointDiscovered代表搜索到一个NFC TagonLlcpActivited代表本机和对端NFC设备进入Link Activation(链路激活)阶段。
  • NativeNfcManager实现了DeviceHost接口,以NXP公司的NativeNfcManager为例,它将通过libnfc_jnilibnfcNXP公司的NFC芯片交互。
  • NativeNfcSecureElement用来和Secure Element交互。

接下来要出场得是HandoverManager以及P2pLinkManager,它们的家族关系如图8-37所示:

bubuko.com,布布扣

8-37  P2pLinkManager家族关系图

8-37所示的P2pLinkManager家族关系图非常复杂,图中的各成员说明如下:

  • P2pLinkManager包含三个和传输相关的Server,分别是SnepServerNdefPushServer以及HandoverServer。每一个Server都定义了相关的回调接口类(如SnepServer.callback),这些回调接口类的实现均由P2pLinkManager的内部类来实现。
  • HandoverServer负责处理NFC Connection Handover协议,而具体的数据传输则由HandoverManager来实现。由图中HandoverMangarmBluetoothAdapter可知,Android默认使用蓝牙来传输数据。提示:这部分内容请读者学完本章后自行研究
  • P2pEventManager用于处理NFC P2P中和用户交互相关的逻辑。例如当搜索到一个P2P设备时,手机将会震动并发出提示音。
  • SendUi实现了类似图8-29Beam示例”左图的界面及用户触摸事件处理。在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分析

SnepServerstart函数将创建一个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模块的结构并通过三个示例程序向读者展示了AndroidNFC API的一些知识
  • 最后,我们对NFC系统模块NfcService及其它重要成员进行了介绍,并详细分析了NFC Tag分发以及Android Beam的实现细节。

最后,希望读者在本章的基础上,完成下列的一些任务:

  • 学习NFC Forum中的其他规范。
  • 结合NFC Forum中的Connection Handover规范,分析AndroidNFC Handover的实现代码。

 

8.5.2  参考资料说明

概述

[1]  Near Field Communication From Theory to Practice1章“Executive Summary”和第2章“Towards NFC Era”。

这本书是笔者目前所阅读的关于NFC最为详尽的资料,建议初学者仔细阅读它,尤其是前三章。

NFC基础知识介绍

NFC概述

[2]  Near Field Communication From Theory to Practice2章“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

该文档介绍了目前NFCISO 14443Felica之间的区别,文档下载地址为

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 Practice33.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 18092http://www.docin.com/p-586980527.html)。

[14]  Simple NDEF Exchange Protocol Technical Specification

SNEP官方协议,非常简单。

NFCCE运行模式介绍

[15]  Near Field Communication From Theory to Practice33.7节“Card Emulation Operating Mode Essentials

[16]  Near Field Communication From Theory to Practice33.3节“General Architecture of NFC Enabled Mobile Phones

这两个资料详细介绍了NFC Enabled PhoneCard 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 Android1章“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/

 20135月起,北京可用支持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

原文:http://blog.csdn.net/innost/article/details/21827091

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!