internal static FreefareTag Build(IntPtr ptrTag, bool dispose, NfcDevice device, NfcTarget target) { TagType type = NativeMethods.freefare_get_tag_type(ptrTag); Console.WriteLine(" type={0}", type); FreefareTag tag; switch (type) { case TagType.NTAG_21x: tag = new NTAG21xTag(ptrTag, dispose, device, target); Console.WriteLine(" subtype={0}", ((NTAG21xTag)tag).SubType); break; case TagType.MIFARE_CLASSIC_1K: tag = new MifareClassic1kTag(ptrTag, dispose, device, target); break; case TagType.MIFARE_CLASSIC_4K: tag = new MifareClassic4kTag(ptrTag, dispose, device, target); break; //TODO other tag types default: tag = new GenericTag(ptrTag, dispose, device, target); break; } return(tag); }
internal FreefareTag(IntPtr ptr, bool dispose, NfcDevice device, NfcTarget target) { this.m_ptr = ptr; this.m_dispose = dispose; this.m_device = device; this.m_target = target; }
internal NTAG21xTag(IntPtr ptr, bool dispose, NfcDevice device, NfcTarget target) : base(ptr, dispose, device, target) { int code = NativeMethods.ntag21x_get_info(ptr); if (code < 0) { throw new FreefareException(string.Format("Can't read tag info. ret={0} lastError={1}", code, this.LastError())); } }
public static void MainSelfLibNfc(string[] args) { Console.WriteLine("Hello"); Console.WriteLine("Using libnfc {0}", NfcContext.Version); //CancellationTokenSource cts = new CancellationTokenSource(); //Console.CancelKeyPress += (s, e) => //{ // if (cts.IsCancellationRequested) // { // //Hard break, let it go // } // else // { // //soft break, handle it // e.Cancel = true; // cts.Cancel(); // } //}; byte pollNr = 1; byte period = 1; var modulations = new[] { new NfcModulation(NfcModulationType.ISO14443A, NfcBaudRate.BR106), new NfcModulation(NfcModulationType.ISO14443B, NfcBaudRate.BR106), new NfcModulation(NfcModulationType.Felica, NfcBaudRate.BR212), new NfcModulation(NfcModulationType.Felica, NfcBaudRate.BR424), new NfcModulation(NfcModulationType.Jewel, NfcBaudRate.BR106), }; Console.WriteLine("Opening libnfc context. sizeof(NfcModulation)={0}", Marshal.SizeOf <NfcModulation>()); using (NfcContext context = new NfcContext()) { string[] devices = context.ListDevices(); Console.WriteLine("Found devices: [{0}]", string.Join(";", devices)); Console.WriteLine("Opening default device"); using (NfcDevice device = context.Open(null)) { Console.WriteLine("Device opened"); Console.WriteLine(" name={0} constring={1}", device.Name, device.ConnectionString); Console.WriteLine(" info={0}", device.GetInfo()); Console.WriteLine("Initializing as initiator"); INfcInitiator initiator = device.InitInitiator(false); Console.WriteLine("NFC reader opened"); Console.WriteLine("NFC reader name: {0}", device.Name); while (true) { PollTagsAndDisplayInfo(initiator); } } } }
static async Task Main(string[] args) { Console.WriteLine("Using libnfc {0}", NfcContext.Version); CancellationTokenSource cts = new CancellationTokenSource(); Console.CancelKeyPress += (s, e) => { if (cts.IsCancellationRequested) { //Hard break, let it go } else { //soft break, handle it e.Cancel = true; cts.Cancel(); } }; byte pollNr = 20; byte period = 2; var modulations = new[] { new NfcModulation(NfcModulationType.ISO14443A, NfcBaudRate.BR106), new NfcModulation(NfcModulationType.ISO14443B, NfcBaudRate.BR106), new NfcModulation(NfcModulationType.Felica, NfcBaudRate.BR212), new NfcModulation(NfcModulationType.Felica, NfcBaudRate.BR424), new NfcModulation(NfcModulationType.Jewel, NfcBaudRate.BR106), }; using (NfcContext context = new NfcContext()) using (NfcDevice device = context.Open(null)) { NfcInitiator initiator = device.InitInitiator(false); Console.WriteLine("NFC reader: {0} opened", device.Name); Console.WriteLine($"NFC device will poll during {pollNr * modulations.Length * period * 150}ms ({pollNr} pollings of {period * 150}ms for {modulations.Length} modulations)"); //NfcInitiatorTarget target = await initiator.PollAsync(modulations, pollNr, period); } }
public void NfcManager_ConnectAndDisconnectDevice() { var dummyAdapter = new DummyNfcAdapter(); var bm = new NfcManager(new[] { dummyAdapter }, null); var device = new NfcDevice { Id = "some-device-id", Name = "Some-device-Uuid" }; dummyAdapter.RaiseDeviceArriveddEvent(device); var devices = bm.GetDiscoveredDevices(); devices.Count().ShouldBe(1); var d = devices.First(); d.Name = device.Name; d.Id = device.Id; dummyAdapter.RaiseDeviceDepartedEvent(device); devices = bm.GetDiscoveredDevices(); devices.Count().ShouldBe(0); }
internal FreefareTagList(IntPtr ptr, NfcDevice device) : base(ptr, true) { this.m_device = device; }
public MifareClassic(NfcDevice device) { Device = device; }
static void Main(string[] args) { byte[] abtRawUid = new byte[12]; byte[] abtAtqa = new byte[2]; byte abtSak = 0; byte[] abtAts = new byte[MAX_FRAME_LEN]; uint szAts = 0; bool isoAtsSupported = false; bool forceRats = false; uint szCL = 1; try { using (var context = new NfcContext()) using (device = context.OpenDevice()) // Try to open the NFC reader { // Initialise NFC device as "initiator" device.InitiatorInit(); // Configure the CRC device.DeviceSetPropertyBool(NfcProperty.HandleCrc, false); // Use raw send/receive methods device.DeviceSetPropertyBool(NfcProperty.EasyFraming, false); // Disable 14443-4 autoswitching device.DeviceSetPropertyBool(NfcProperty.AutoIso14443_4, false); WriteLine("NFC reader: {0} opened", device.Name); WriteLine(); // Send the 7 bits request command specified in ISO 14443A (0x26) TransmitBits(abtReqa, 7); Array.Copy(abtRx, abtAtqa, 2); // Anti-collision TransmitBytes(abtSelectAll, 2); // Check answer if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) { WriteLine("WARNING: BCC check failed!"); } // Save the UID CL1 Array.Copy(abtRx, abtRawUid, 4); //Prepare and send CL1 Select-Command Array.Copy(abtRx, 0, abtSelectTag, 2, 5); Iso14443aCrcAppend(abtSelectTag, 7); TransmitBytes(abtSelectTag, 9); abtSak = abtRx[0]; #region CL // Test if we are dealing with a CL2 if ((abtSak & CASCADE_BIT) != 0) { szCL = 2; // or more // Check answer if (abtRawUid[0] != 0x88) { WriteLine("WARNING: Cascade bit set but CT != 0x88!"); } } if (szCL == 2) { // We have to do the anti-collision for cascade level 2 // Prepare CL2 commands abtSelectAll[0] = 0x95; // Anti-collision TransmitBytes(abtSelectAll, 2); // Check answer if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) { WriteLine("WARNING: BCC check failed!"); } // Save UID CL2 Array.Copy(abtRx, 0, abtRawUid, 4, 4); // Selection abtSelectTag[0] = 0x95; Array.Copy(abtRx, 0, abtSelectTag, 2, 5); Iso14443aCrcAppend(abtSelectTag, 7); TransmitBytes(abtSelectTag, 9); abtSak = abtRx[0]; // Test if we are dealing with a CL3 if ((abtSak & CASCADE_BIT) != 0) { szCL = 3; // Check answer if (abtRawUid[0] != 0x88) { WriteLine("WARNING: Cascade bit set but CT != 0x88!"); } } if (szCL == 3) { // We have to do the anti-collision for cascade level 3 // Prepare and send CL3 AC-Command abtSelectAll[0] = 0x97; TransmitBytes(abtSelectAll, 2); // Check answer if ((abtRx[0] ^ abtRx[1] ^ abtRx[2] ^ abtRx[3] ^ abtRx[4]) != 0) { WriteLine("WARNING: BCC check failed!"); } // Save UID CL3 Array.Copy(abtRx, 0, abtRawUid, 8, 4); // Prepare and send final Select-Command abtSelectTag[0] = 0x97; Array.Copy(abtRx, 0, abtSelectTag, 2, 5); Iso14443aCrcAppend(abtSelectTag, 7); TransmitBytes(abtSelectTag, 9); abtSak = abtRx[0]; } } #endregion // Request ATS, this only applies to tags that support ISO 14443A-4 if ((abtRx[0] & SAK_FLAG_ATS_SUPPORTED) != 0) { isoAtsSupported = true; } if ((abtRx[0] & SAK_FLAG_ATS_SUPPORTED) != 0 || forceRats) { Iso14443aCrcAppend(abtRats, 2); int szRx = TransmitBytes(abtRats, 4); if (szRx >= 0) { Array.Copy(abtRx, abtAts, szRx); szAts = (uint)szRx; } } WriteLine(); WriteLine("驗證Block 0"); // 驗證 Block 0 Iso14443aCrcAppend(abtAuthA, 2); TransmitBytes(abtAuthA, 4); // 自己控制 Parity bit device.DeviceSetPropertyBool(NfcProperty.HandleParity, false); var nt = abtRx.ToUInt32(); var uid = abtRawUid.ToUInt32(); Write(" Nt: "); PrintHex(abtRx, 4); var crapto1 = new Crypto1(0xFFFFFFFFFFFFu); // 初始化 crapto1 狀態 feed in uid^nt and drop keystream in the first round crapto1.Crypto1Word(uid ^ nt); // 自訂讀卡機端nonce var nr = 0x01020304u; // Ar 為 suc2(nt) var ar = PrngSuccessor(nt, 64); // 加密 Nr,suc2(Nt) 和 parity bit var enNrAr = nr.GetBytes().Concat(ar.GetBytes()).ToArray(); var enNrArParity = new byte[8]; crapto1.Encrypt(enNrAr, enNrArParity, 0, 4, true); crapto1.Encrypt(enNrAr, enNrArParity, 4, 4); Write("[Nr,suc2(Nt)]: "); PrintHex(enNrAr, 8); // 送出[Nr,suc2(Nt)] device.InitiatorTransceiveBits(enNrAr, 64, enNrArParity, abtRx, MAX_FRAME_LEN, null); var enAt = new byte[4]; Array.Copy(abtRx, enAt, 4); Write(" [suc3(Nt)]: "); PrintHex(enAt, 4); // 解密[at] var at = enAt.ToUInt32() ^ crapto1.Crypto1Word(); WriteLine("At: {0:x8} == suc3(Nt):{1:x8}", at, PrngSuccessor(nt, 96)); // 讀取 Block for (byte i = 0; i < 4; i++) { ReadBlock(crapto1, i); } WriteLine(); WriteLine("Nested驗證 Block 4"); // Nested驗證 Block 4 abtAuthA[1] = 4; Iso14443aCrcAppend(abtAuthA, 2); var enAuth = abtAuthA.ToArray(); var enAuthParity = new byte[4]; crapto1.Encrypt(enAuth, enAuthParity, 0, 4); device.InitiatorTransceiveBits(enAuth, 32, enAuthParity, abtRx, MAX_FRAME_LEN, null); // 開始Nested驗證的新crypto1密鑰 crapto1 = new Crypto1(0xFFFFFFFFFFFFu); Write(" 未解密Nt: "); PrintHex(abtRx, 4); var enNt = abtRx.ToUInt32(); // 初始化 crapto1 狀態 用加密的Nt,並解出明文nt nt = enNt ^ crapto1.Crypto1Word(uid ^ enNt, true); Write(" Nt: "); PrintHex(nt.GetBytes(), 4); // 自訂讀卡機端nonce nr = 0x01020304u; // Ar 為 suc2(nt) ar = PrngSuccessor(nt, 64); // 加密 Nr,suc2(Nt) 和 parity bit enNrAr = nr.GetBytes().Concat(ar.GetBytes()).ToArray(); enNrArParity = new byte[8]; crapto1.Encrypt(enNrAr, enNrArParity, 0, 4, true); crapto1.Encrypt(enNrAr, enNrArParity, 4, 4); Write("[Nr,suc2(Nt)]: "); PrintHex(enNrAr, 8); // 送出[Nr,suc2(Nt)] var res = device.InitiatorTransceiveBits(enNrAr, 64, enNrArParity, abtRx, MAX_FRAME_LEN, null); enAt = new byte[4]; Array.Copy(abtRx, enAt, 4); Write(" [suc3(Nt)]: "); PrintHex(enAt, 4); // 解密[at] at = enAt.ToUInt32() ^ crapto1.Crypto1Word(); WriteLine("At: {0:x8} == suc3(Nt):{1:x8}", at, PrngSuccessor(nt, 96)); // 寫入 Block4 WriteBlock(crapto1, 4, new byte[16] { 65, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }); // 讀取 Block for (byte i = 4; i < 8; i++) { ReadBlock(crapto1, i); } WriteLine(); // device.DeviceSetPropertyBool(NfcProperty.HandleParity, true); // Done, halt the tag now Iso14443aCrcAppend(abtHalt, 2); TransmitBytes(abtHalt, 4); } } catch (Exception ex) { WriteLine(ex.Message); Environment.Exit(1); } WriteLine(); WriteLine("Found tag with"); Write(" UID: "); switch (szCL) { case 1: Write("{0:x2}{1:x2}{2:x2}{3:x2}", abtRawUid[0], abtRawUid[1], abtRawUid[2], abtRawUid[3]); break; case 2: Write("{0:x2}{1:x2}{2:x2}", abtRawUid[1], abtRawUid[2], abtRawUid[3]); Write("{0:x2}{1:x2}{2:x2}{3:x2}", abtRawUid[4], abtRawUid[5], abtRawUid[6], abtRawUid[7]); break; case 3: Write("{0:x2}{1:x2}{2:x2}", abtRawUid[1], abtRawUid[2], abtRawUid[3]); Write("{0:x2}{1:x2}{2:x2}", abtRawUid[5], abtRawUid[6], abtRawUid[7]); Write("{0:x2}{1:x2}{2:x2}{3:x2}", abtRawUid[8], abtRawUid[9], abtRawUid[10], abtRawUid[11]); break; } WriteLine(); WriteLine("ATQA: {0:x2}{1:x2}", abtAtqa[1], abtAtqa[0]); WriteLine(" SAK: {0:x2}", abtSak); if (szAts > 1) { // if = 1, it's not actual ATS but error code if (forceRats && !isoAtsSupported) { WriteLine(" RATS forced"); } Write(" ATS: "); PrintHex(abtAts, szAts); } ReadLine(); }
internal MifareClassicTag(IntPtr ptr, bool dispose, NfcDevice device, NfcTarget target) : base(ptr, dispose, device, target) { }
public NfcDeviceEventArgs(NfcDevice device) { Device = device; }
internal GenericTag(IntPtr ptr, bool dispose, NfcDevice device, NfcTarget target) : base(ptr, dispose, device, target) { }
internal void RaiseDeviceDepartedEvent(NfcDevice device) { var dea = new NfcDeviceEventArgs(device); DeviceDeparted(this, dea); }
internal void RaiseDeviceArriveddEvent(NfcDevice device) { var args = new NfcDeviceEventArgs(device); DeviceArrived(this, args); }
public ProxiedNfcDevice(INfcAdapter adapter, NfcDevice device) { Device = device; Adapter = adapter; }