NFC基本原理
# 近場通訊NFC(Near
Field Communication)是無線射頻辨識 (Radio Frequency IDentification,RFID)的一種延伸技術
具有以下特點:
# 非接觸式點對點資料傳輸
# 10 公分 (3.9 英吋) 內
# 由RFID演變而來
# 13.56MHz運行於20公分內
# 傳輸速度106 Kbit / 秒 或 212 Kbit/秒 或 425
Kbit/秒
# ISO/IEC IS 18092 國際標準
# EMCA-340標準
# EMCA-340標準
# ETSI TS 102 190 標準
# 讀取模式 : 主動 / 被動
# 讀取模式 : 主動 / 被動
|
NFC
|
Bluetooth
|
Bluetooth
Low Energy
|
ISO
18000-3
|
active
|
active
|
|
標準化機構
|
ISO/IEC
|
Bluetooth
SIG
|
Bluetooth
SIG
|
網路標準
|
ISO
13157 etc.
|
IEEE
802.15.1
|
IEEE
802.15.1
|
網路類型
|
Point-to-point
|
WPAN
|
WPAN
|
加密
|
not
with RFID
|
available
|
available
|
範圍
|
<
0.2 m
|
~10
m (class 2)
|
~1
m (class 3)
|
頻率
|
13.56 MHz
|
2.4-2.5 GHz
|
2.4-2.5 GHz
|
Bit
rate
|
424
kbit/s
|
2.1
Mbit/s
|
~1.0
Mbit/s
|
設定程式
|
<
0.1 s
|
<
6 s
|
<
0.006 s
|
功耗
|
<
15mA (read)
|
varies
with class
|
<
15 mA (xmit)
|
NFC的資料通訊模式分為主動模式與被動模式兩種:
(1) 主動模式
(有源標籤)
在主動模式下,NFC的兩端設備都必須要支援全雙向的資料交換,
接收端需要有電源供應,稱為有源標籤.
(2) 被動模式
(無源標籤)
在被動模式下,NFC的啟動端,將要傳輸的訊息發送到NFC的接收端,接收端本身不需要有電源的供應,就像是我們的悠遊卡一樣,接收端利用發送端所產生的電場回應訊息給NFC的啟動端。
# 在每張NFC卡在出廠時都會配有一組UID,基本上是不可更改的.
使用Android
Mobile作為NFC模擬卡:
在一部配備NFC功能的手機實現NFC卡的模擬,目前有兩種方式.
一種是基於硬體的,稱為虛擬卡模式(Virtual
Card Mode).
一種是基於軟體的,被稱為主機卡模式(Host
Card Mode).
在硬體的虛擬卡實現中,需要有SE模組的支援(Secure Elemen),而SE模組的實施有以下方案:
#內嵌於 SIM 卡
#內嵌於 SD 卡
#內嵌於 NFC 晶片
在2013年10月31日,google發布android 4.4系統,其中包含一種叫HCE(Host Card Emulation)的技術.HCE能使用軟體的方式使行動裝置能使用NFC卡模擬的功能.
HCE技術是模擬NFC和SE通信的協議和實現。但是HCE並沒有實現SE,只是用NFC與SE通信的方式告訴NFC讀卡器後面有SE的支持,從而以虛擬SE的方式完成NFC業務的安全保證.
Android4.4系統使用NFC論壇制定的的ISO-DEP標準協議(基於ISO/IEC14443-4(ISO-DEP)標準)進行數據傳輸,傳輸的數據單元被稱為應用協議數據單元(APDUs)。
權限:
<uses-feature
android:name="android.hardware.nfc.hce"
android:required="true" />
<uses-permission
android:name="android.permission.NFC" />
服務註冊:
<!--
Service for handling communication with NFC terminal. -->
<service android:name=".CardService"
android:exported="true"
android:permission="android.permission.BIND_NFC_SERVICE">
<!-- Intent filter indicating that we support card emulation. -->
<intent-filter>
<action
android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
<category
android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<!-- Required XML configuration file, listing the AIDs that we are emulating
cards
for. This defines what protocols our card emulation service supports.
-->
<meta-data
android:name="android.nfc.cardemulation.host_apdu_service"
android:resource="@xml/aid_list"/>
</service>
<!-- END_INCLUDE(CardEmulationManifest) -->
AID註冊:
<!-- BEGIN_INCLUDE(CardEmulationXML) -->
<host-apdu-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/service_name"
android:requireDeviceUnlock="false">
<!--
If
category="payment" is used for any aid-groups, you must also add an
android:apduServiceBanner
attribute
above, like so:
android:apduServiceBanner="@drawable/settings_banner"
apduServiceBanner should be 260x96 dp. In pixels, that works out to...
-
drawable-xxhdpi: 780x288 px
-
drawable-xhdpi: 520x192 px
-
drawable-hdpi: 390x144 px
-
drawable-mdpi: 260x96 px
The
apduServiceBanner is displayed in the "Tap & Pay" menu in the
system Settings app, and
is only
displayed for apps which implement the "payment" AID category.
Since
this sample is implementing a non-standard card type (a loyalty card,
specifically), we
do not
need to define a banner.
Important: category="payment"
should only be used for industry-standard payment cards. If you are
implementing a closed-loop payment system (e.g. stored value cards for a
specific merchant
or
transit system), use category="other". This is because only one
"payment" card may be
active at a time, whereas all "other" cards are active
simultaneously (subject to AID
dispatch).
-->
<aid-group android:description="@string/card_title"
android:category="other">
<aid-filter android:name="F222222222"/>
</aid-group>
<!-- END_INCLUDE(CardEmulationXML) -->
</host-apdu-service>
繼承 and 複寫:
public class CardService extends HostApduService
{
...
//
BEGIN_INCLUDE(processCommandApdu)
@Override
public
byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
Log.i(TAG, "Received APDU: " +
ByteArrayToHexString(commandApdu));
// If
the APDU matches the SELECT AID command for this service,
//
send the loyalty card account number, followed by a SELECT_OK status trailer
(0x9000).
if
(Arrays.equals(SELECT_APDU, commandApdu)) {
String account = AccountStorage.GetAccount(this);
byte[] accountBytes = account.getBytes();
Log.i(TAG, "Sending account number: " + account);
return ConcatArrays(accountBytes, SELECT_OK_SW);
}
else {
return UNKNOWN_CMD_SW;
}
}
//
END_INCLUDE(processCommandApdu)
...
}
Android官方範例:
使用Android
Mobile 作為NFC讀卡機:
連線至讀卡機後,傳送SELECT
AID的指令,
在NFC 模擬卡的部分,我們設定AID (Application ID) = F222222222,
因此傳送此指令:
00A4040005F222222222
參考資料:
5.http://www.slideshare.net/NFC-Forum/android-hce-an-intro-into-the-world-of-nfc-presentation-by-6. neel-rao-of-google-at-andevcon-2014-andevcon-android-app-developers-hce-nfc-tech-technologyan-7. devcon-presentation