Υ

Υ٤δ

ƥꡧ FeliCa/NFC

Android4.4Ѳǽˤʤäۥȥ١ɥߥ졼
®ȤäƤߤޤ
ʲҤNexus7ĿͻXperiaVL4.4ˤʤϡġĤ⤦̵ΤǤ礦)

ɥߥ졼ħ
üISO14443Aɤο򤵤
ʥ꡼饤鸫ȡΥɤǤ
̥åʤƤȿ
Υߥ󥰤򥢥ץǤ
AndroidBeamξ硢桼Υåˤ
ǥץ쥤ŸäƤʤȿʤ
ʥХFeliCaϥǥץ쥤üŸäƤʤƤư

ݡ
ISO14443A 106kbpsݡ󥰤üªǤޤ
SELRES6bitܤˤꥫɥߥ졼βݤȽǤǤޤ)
Android4.4̤üǤ⡢SIMɤƤSELRES6bitܤ1ˤʤޤ
ξϡҤSELECT FILEˤбγǧԤޤ

ISO7816-4 SELECT FILEޥˤ
Υץ(ServiceȤƼ)ưǤ

0x00 0xA4 0x04 0x00 0x07 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x00
0x00(CLA)
0xA4(SELECT FILE)
0x04(DF-name)
0x00(First record)
0x07(ץ꼱̻ҤĹ)
0x01 0x01(ץ꼱̻ҡ˰פ륢ץ꤬ưޤ)
0x00(쥹ݥ󥹥ǡĹ)

ꤷץ꤬󥹥ȡ뤵Ƥʤ
Android4.4̤ξ
FileNotFound(0x6A 0x82)쥹ݥ󥹤ޤ
SIM˥ץ꼱̻ҤΰפΤбΤȻפޤ

ץ꤬ư
꡼饤ȥץ꤬ꥢ̿ǽʾ֤Ȥʤ
ʥɤ̿뤳ȤϤǤޤ󤫤顢˥꡼¦饳ޥɤˤʤޤ)

ڥΤޤ뤿ᡢREADWRITEϤޤطޤ

Android4.4ξܺ٤ȯɽޤ
http://gigazine.net/news/20131101-new-function-android-os-kitkat/

OSRAM̤Ǥ硩
ŤüǤư͡
ȤɾȽäΤǤ򳫤ȶäοǽޤ

NFCɥߥ졼



꡼åơ̥åΤAndroidNFCġ
꡼饤ʥ쥸ˤʤǤ褤ΤϡܤΤե

ȤʬǤϤʤäǤ

Android4.4
եεǽȤʤƤ⡢ʤ̿ǽʤΡ

ġ
FeliCaͥƤޤäΤǤϤʤǤ


ʤߤˤեƤFeliCaͥåȥҤ
եǽȤʥץ򥤥󥹥ȡ뤷ưܡ
˥ץۿҤ120ߡ250ߤݶ⤹ӥͥ򤷤Ƥޤ

ޥɥʥɤΤեץ
1000˥󥹥ȡ뤵Ƥ뤽Ǥ
250*1000=25
줬23ǯǵѹȹͤ
ǯ1020ߤ夲ˤʤΤǤ礦

ˡɥȤȤλҲҤʤΤ
礷˼ǤϤʤΤ⤷ޤ󤬡

եפˤʤäƤޤȡܤNFCڤΰѤôäƤFeliCaͥåȥҤäƤޤ⤷ޤ

ޤץ곫ȯԤ餹
̵ץˤNFCǽȤ߹褦ˤʤ櫓Ǥ顢ɤȤǤɤ

󶡤ƤFeliCaMifare饤֥Υɤޤ

Ƥͽ򸵤ˤΤʤΤǡ饤󥹥ե꡼Ǥ
(RC-S330ReadWithoutEncryption(WriteWithoutEncryption)ˤĤƤϡ
ˡҤNDAȤꤷ󤬸ˤʤäƤפФȤޤ
RC-S380ˤĤƤϡΤߤǼƤΤꤢޤ)

ɤ򸫤ФΤޤޤʤΤǤġ
http://www.nxp.com/documents/data_sheet/MF1S50YYX.pdf
Ȥ
http://www.sony.co.jp/Products/felica/business/tech-support/data/card_usersmanual_2.0.pdf
˽񤫤Ƥ륳ޥɡ쥹ݥ󥹤򤽤Τޤ޼ΤǤ

NFCʤƴñʤ
äƻפäƤ館йǤ

ޤǤե꡼եȤƤΤǤ
ɤzipեˤdropboxθǥ쥯ȥ֤ƤᡢɤؤλϤǤޤǤ

github˥åץɤȤǡɤʤˤǤ⼫ͳԽ(clone)ĺȤǽˤʤޤ
ɤФ륳Ȥ⼫ͳ˹Ԥޤ

https://github.com/tijins/NfcLib

ҤηӤڤʤʤäΤ(ȯѤäƤäNexusSŸǥء
ʪXperiaVL˵ѹƤޤ

ڤ
¸ΰ16GBRAM1GB
ΤΥڥåϡȤƤ­

ǡѹŪȤʤäNFCȡBluetooth4.0
̳οʥǥХåѤʤǤġ

NFC
󤤡Ĵ٤ƤȤP2P̿NfcA/106kbpsΤߡ

ޤͽ̤ꡣ
äȵʤʬäƤޤä˾


ʤ
MifareClassicMifareUltralight
б

ϡɥʤǤб񤷤MifareClassicϻʤȤ
NFC Type2 tag ȸߴǤMifareaUltralightбƤʤȤΤ
餫ʤǤ͡ġ

MifareFeliCa10ܰʾв٤Ƥ롢ǤŪܿICɤǤ
GoogleΥեüNexusSȤGalaxu꡼ǤбƤޤ

NDEFȥ졼ȤǧʤΤǤϡmifareѤۤǤޤ͡
ġ

NDEF(NFC Data Exchange Format)ϡܿICɤ˥ǡ¸뤿εʤǤ

AndroidޡȥեWindows8бƤꡢɤ򤫤ǡURL򳫤ꡢɥ쥹ĢؤϿǽǤ

NFCȤϡFeliCa Lite(Type3)䡢Mifare Ultralight(Type2)Ūʤ櫓ǤMifare ClassicȤʤ櫓Ǥ⤢ޤ

Mifare Classicħ
FeliCa LiteMifare UltralightˤϤʤդΰ褬ޤ
(6Byte)ꤹǡɤ߽񤭤ɻ߲ǽǤ
ɤ߽񤭡ɹߤΤ꤬ǽ

NDEF¸
MAD(Mifare Application Directory)
0ˡMAD(Ƥɽإå)񤭹ߤޤ
MADˤϡ115줾(AID=Application ID)򵭺ܤޤ

NDEFɽAID0x03E1Ǥ

NDEF
AID0x03e1ȤˤϡҤȤİʾTLV֥åݴɤޤ
TLV=Type LengthValue

TYPE
NDEFåɽType0x03Ǥ

LENGTH
Ǽǡ00xFEޤǤǤ1byteǡ0xFFʾǤ3Byte(0xFF 0xSIZE 0xSIZE)dzǼޤ

Value
NDEF ForumNDEF MessageǼޤ

ߥ͡TLV
ǸTLV֥åϡߥ͡TLVˤޤ
T=0xFE




ΥեޥåȤǥɤ˽񤭹ǡAndroidǧޤ

MADˤNDEFʳꤷˤϡꤷǤդΥǡ¸ǽǤ
ϡTypeType3ˤ̵åȤǤ

Ĵ٤ƤߤȡʤFeliCa߷פˤʤäƤ뤳Ȥʬޤ
NFC-ICΥƥꥢ˼ñʵޤġ
FelicaNetworksʤȤȤʤΤǡޤѥѵǽ˹äƤΤǤ礦)

FeliCaɤȤƻȤ
ɤΤΤȤưޤġ
AndroidüInitiatorȤʤäƤ֤ϡR/W̿ޤ

PN532Ѥ硢ǥեȤΥॢ(102ms)Ǥϡ빽٤Initiatorδ֤ꡢݡ󥰤˼Ԥޤ
ॢͤ25msˤۤȤɼԤʤʤޤ

NFC⡼
NfcA(106kbps)PassiveΤбǤ
Nexus7Galaxy꡼212kbps424kbpsбƤ뤳ȤͤȡʤǰǤ

FeliCaNFCϢΤޤȤ

PaSoRi
ˡ꡼饤RC-S380ʹߤNFCбƤ
.net frameworkб饤֥FeliCamifareؤɤ߽б)


ACR122U
ACS꡼饤
AndroidBeamߥ졼

LLCPμˡ
LLCPμˡ
LLCPμˡ
LLCPμˡ

Android
FeliCaMifareISO15693ؤɤ߽
P2P̿AndroidBeamȤOS椵Ƥ
ɥߥ졼Բ

бAndroidBeamߥ졼ޤ
https://dl.dropboxusercontent.com/u/55426081/SnepSender.zip

ϡActive⡼ɡPassive⡼ɡ̿®(106kbps,212kbps,424kbps)ꤷSNEP̿Ǥ륢ץǤ
ˤäơ¹ԤˤNFC꡼饤ACR122UɬפǤ
ɤźդƤΤǡ¾Υ꡼饤ؤбưפȻפޤ

BeamReader


ޤޤޤǤġ
üˤäб̿®٤˰㤤ΤǡǧΤˤȻפޤ

NexusSǤ
Active⡼ɡ106kbps,212kbps,424kbpsб
Passive⡼ɡ212kbpsΤб
ޤڽƤʤΤǤ᡼üǤ㤦бΤ褦Ǥ
ɤտޤǼƤΤʬޤ

Target⡼ɤˤбƤޤ
Target⡼ɤAndroidüInitiatorˤʤΤԤǡüȯƤȤμĴ٤ޤ
(NfcF424kbpsActive⡼ɡIDDID̵Ȼפޤ)

¦ϸƤޤ¦Υץޤ
https://dl.dropbox.com/u/55426081/SnepSender.zip

2013/3/15ɵ
http://blog.livedoor.jp/esper776/archives/65847214.html
бǤޤ


AndroidBeam˴ؤܻ
NfcANfcF³
LLCP̿
SNEPPUTNDEFե
Ǥ

ᥤϤʴ
LLCP_sender_diagram




private bool LlcpSession()
{
destCh = SnepHelper.DSAP;
state = LlcpStatus.WaitCC;
PDU sendTo = null;
Connect con = new Connect() { Dsap = destCh, Ssap = myCh };
byte[] ret = rw.InDataExchange(con.ToBytes());

while (!abort)
{
PDU pdu = LlcpHelper.GetPdu(ret);
if (pdu == null)
{
Release();
return false;
}

if (state == LlcpStatus.DISC)
return true;

switch (pdu.Kind)
{
case Symm.KIND:
sendTo = new Symm();
break;

case Ui.KIND:
case Connect.KIND:
case Disc.KIND:
case Frmr.KIND:
case Rnr.KIND:
default:
sendTo = new Dm() { Dsap = 0, Ssap = myCh };
abort = true;
break;

case Cc.KIND:
if (state == LlcpStatus.WaitCC)
{
destCh = pdu.Ssap;
vS = vSA = vR = vRA = 0;
sendIndex = 0;
sendTo = GetSendData();
state = LlcpStatus.SEND;
}
else
{
sendTo = new Dm() { Dsap = 0, Ssap = myCh };
abort = true;
}
break;

case Information.KIND:
if (state == LlcpStatus.SEND)
{
vR = ((Information)pdu).SeqS + 1;
vSA = ((Information)pdu).SeqR;
if (sendIndex == sendData.Length)
{
sendTo = new Rr() { Dsap = destCh, Ssap = myCh, SeqR = (byte)(vR % 0x0f) };
state = LlcpStatus.DISC;
}
else
{
sendTo = GetSendData();
}
}
else
{
sendTo = new Dm() { Dsap = 0, Ssap = myCh };
abort = true;
}
break;

case Rr.KIND:
if (state == LlcpStatus.SEND)
{
vSA = ((Rr)pdu).SeqR;
sendTo = new Symm();
}
else
{
sendTo = new Dm() { Dsap = 0, Ssap = myCh };
abort = true;
}
break;

}
ret = rw.InDataExchange(sendTo.ToBytes());
}
Debug.WriteLine("SNEP Push Complete");
Release();
return true;
}