From 78b832187a9090a2132bf9e978f1baf9ba72bb62 Mon Sep 17 00:00:00 2001 From: Jannis Rieger Date: Fri, 18 Sep 2020 02:04:58 +0200 Subject: [PATCH] implemented NFC on iOS --- Borepin.sln | 100 ++++++++++++------------- Borepin/Borepin.iOS/Borepin.iOS.csproj | 15 +++- Borepin/Borepin.iOS/CNFC/Card.cs | 66 ++++++++++++++++ Borepin/Borepin.iOS/CNFC/Hardware.cs | 24 ++++++ Borepin/Borepin.iOS/CNFC/Reader.cs | 67 +++++++++++++++++ NFC/NFC.csproj | 23 +++--- 6 files changed, 231 insertions(+), 64 deletions(-) create mode 100644 Borepin/Borepin.iOS/CNFC/Card.cs create mode 100644 Borepin/Borepin.iOS/CNFC/Hardware.cs create mode 100644 Borepin/Borepin.iOS/CNFC/Reader.cs diff --git a/Borepin.sln b/Borepin.sln index da929dd..f2e2b0c 100644 --- a/Borepin.sln +++ b/Borepin.sln @@ -15,9 +15,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Borepin.GTK", "Borepin\Bore EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Borepin.macOS", "Borepin\Borepin.macOS\Borepin.macOS.csproj", "{3EC23FE7-395E-4BBC-B56B-9455354BDA34}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NFC", "NFC\NFC.csproj", "{72DAC306-D4B2-4DBF-9C32-317203FD5D61}" +Project("{9344BDBB-3E7F-41FC-A0DD-8665D75EE146}") = "NFC_Test", "NFC_Test\NFC_Test.csproj", "{41EC0C17-B456-42AE-89F2-79DDB8ED9858}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFC_Test", "NFC_Test\NFC_Test.csproj", "{0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NFC", "NFC\NFC.csproj", "{9C2ED2EB-D91C-4D80-9580-6A135C05AF11}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -227,54 +227,54 @@ Global {3EC23FE7-395E-4BBC-B56B-9455354BDA34}.Release|x64.Build.0 = Release|Any CPU {3EC23FE7-395E-4BBC-B56B-9455354BDA34}.Release|x86.ActiveCfg = Release|Any CPU {3EC23FE7-395E-4BBC-B56B-9455354BDA34}.Release|x86.Build.0 = Release|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Debug|Any CPU.Build.0 = Debug|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Debug|ARM.ActiveCfg = Debug|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Debug|ARM.Build.0 = Debug|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Debug|iPhone.Build.0 = Debug|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Debug|x64.ActiveCfg = Debug|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Debug|x64.Build.0 = Debug|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Debug|x86.ActiveCfg = Debug|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Debug|x86.Build.0 = Debug|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|Any CPU.ActiveCfg = Release|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|Any CPU.Build.0 = Release|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|ARM.ActiveCfg = Release|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|ARM.Build.0 = Release|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|iPhone.ActiveCfg = Release|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|iPhone.Build.0 = Release|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|x64.ActiveCfg = Release|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|x64.Build.0 = Release|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|x86.ActiveCfg = Release|Any CPU - {72DAC306-D4B2-4DBF-9C32-317203FD5D61}.Release|x86.Build.0 = Release|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|ARM.ActiveCfg = Debug|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|ARM.Build.0 = Debug|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|iPhone.Build.0 = Debug|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|x64.ActiveCfg = Debug|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|x64.Build.0 = Debug|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|x86.ActiveCfg = Debug|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Debug|x86.Build.0 = Debug|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|Any CPU.Build.0 = Release|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|ARM.ActiveCfg = Release|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|ARM.Build.0 = Release|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|iPhone.ActiveCfg = Release|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|iPhone.Build.0 = Release|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|x64.ActiveCfg = Release|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|x64.Build.0 = Release|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|x86.ActiveCfg = Release|Any CPU - {0DC42C5F-FB5D-48E1-81C2-25AF23F3916A}.Release|x86.Build.0 = Release|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Debug|Any CPU.Build.0 = Debug|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Debug|ARM.ActiveCfg = Debug|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Debug|ARM.Build.0 = Debug|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Debug|iPhone.Build.0 = Debug|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Debug|x64.ActiveCfg = Debug|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Debug|x64.Build.0 = Debug|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Debug|x86.ActiveCfg = Debug|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Debug|x86.Build.0 = Debug|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Release|Any CPU.ActiveCfg = Release|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Release|Any CPU.Build.0 = Release|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Release|ARM.ActiveCfg = Release|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Release|ARM.Build.0 = Release|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Release|iPhone.ActiveCfg = Release|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Release|iPhone.Build.0 = Release|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Release|x64.ActiveCfg = Release|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Release|x64.Build.0 = Release|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Release|x86.ActiveCfg = Release|Any CPU + {41EC0C17-B456-42AE-89F2-79DDB8ED9858}.Release|x86.Build.0 = Release|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Debug|ARM.ActiveCfg = Debug|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Debug|ARM.Build.0 = Debug|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Debug|iPhone.Build.0 = Debug|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Debug|x64.ActiveCfg = Debug|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Debug|x64.Build.0 = Debug|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Debug|x86.ActiveCfg = Debug|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Debug|x86.Build.0 = Debug|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Release|Any CPU.Build.0 = Release|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Release|ARM.ActiveCfg = Release|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Release|ARM.Build.0 = Release|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Release|iPhone.ActiveCfg = Release|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Release|iPhone.Build.0 = Release|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Release|x64.ActiveCfg = Release|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Release|x64.Build.0 = Release|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Release|x86.ActiveCfg = Release|Any CPU + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Borepin/Borepin.iOS/Borepin.iOS.csproj b/Borepin/Borepin.iOS/Borepin.iOS.csproj index d59a79f..33b6ba5 100644 --- a/Borepin/Borepin.iOS/Borepin.iOS.csproj +++ b/Borepin/Borepin.iOS/Borepin.iOS.csproj @@ -15,6 +15,7 @@ true NSUrlSessionHandler automatic + true true @@ -46,11 +47,12 @@ prompt 4 ARM64 - Apple Development: jannis@rieger-kaulsdorf.de (T4279FN3P6) + iPhone Developer true Entitlements.plist - None + Full -all + --optimize=experimental-xforms-product-type none @@ -61,6 +63,8 @@ ARM64 iPhone Developer Entitlements.plist + --optimize=experimental-xforms-product-type + Full @@ -68,6 +72,9 @@ + + + @@ -132,5 +139,9 @@ {F93856BD-0C8D-4469-A8DB-6E513002BFD7} Borepin + + {9C2ED2EB-D91C-4D80-9580-6A135C05AF11} + NFC + \ No newline at end of file diff --git a/Borepin/Borepin.iOS/CNFC/Card.cs b/Borepin/Borepin.iOS/CNFC/Card.cs new file mode 100644 index 0000000..1758062 --- /dev/null +++ b/Borepin/Borepin.iOS/CNFC/Card.cs @@ -0,0 +1,66 @@ +using System; +using System.Threading; +using CoreNFC; +using Foundation; +using NFC; + +namespace Borepin.iOS.CNFC +{ + public class Card : ICard + { + private NFCTagReaderSession _session; + private INFCMiFareTag _tag; + + public Card(NFCTagReaderSession session, INFCMiFareTag tag) + { + _session = session; + _tag = tag; + } + + public void Connect() + { + var counter = new CountdownEvent(1); + NSError err = null; + + _session.ConnectTo(_tag, (error) => + { + err = error; + counter.Signal(); + }); + + counter.Wait(); + + if (err != null) + { + throw new Exception(err.LocalizedDescription); + } + } + + public void Disconnect() + { + // TODO: decide on which should be used + //_session.RestartPolling(); + _session.InvalidateSession("card disconnect"); + } + + public APDUResponse Transmit(APDUCommand cmd) + { + var counter = new CountdownEvent(1); + byte[] buf = null; + + _tag.SendMiFareIso7816Command(new NFCIso7816Apdu(NSData.FromArray(cmd.Data)), (response, sw1, sw2, NSError) => + { + // reassembly the original apdu message + buf = new byte[response.Length + 2]; + response.ToArray().CopyTo(buf, 0); + buf[response.Length + 0] = sw1; + buf[response.Length + 1] = sw2; + counter.Signal(); + }); + + counter.Wait(); + + return new APDUResponse(buf); + } + } +} diff --git a/Borepin/Borepin.iOS/CNFC/Hardware.cs b/Borepin/Borepin.iOS/CNFC/Hardware.cs new file mode 100644 index 0000000..e523b9e --- /dev/null +++ b/Borepin/Borepin.iOS/CNFC/Hardware.cs @@ -0,0 +1,24 @@ +using System; +using CoreNFC; +using NFC; + +namespace Borepin.iOS.CNFC +{ + public class Hardware : IHardware + { + public bool IsAvailable() + { + return NFCReaderSession.ReadingAvailable; + } + + public String[] GetReaders() + { + return new String[] { "main" }; + } + + public IReader OpenReader(String readerID) + { + return new Reader(); + } + } +} diff --git a/Borepin/Borepin.iOS/CNFC/Reader.cs b/Borepin/Borepin.iOS/CNFC/Reader.cs new file mode 100644 index 0000000..2623290 --- /dev/null +++ b/Borepin/Borepin.iOS/CNFC/Reader.cs @@ -0,0 +1,67 @@ +using System; +using CoreFoundation; +using CoreNFC; +using Foundation; +using NFC; + +namespace Borepin.iOS.CNFC +{ + public class Reader : NFCTagReaderSessionDelegate, IReader + { + public event ReaderEventHandler CardDiscovered; + public event ReaderEventHandler CardLost; + + private NFCReaderSession _session = null; + private DispatchQueue _queue; + + public void Start() + { + _queue = new DispatchQueue("NFC Reader Queue", true); + + // sessions cannot be reused + _session = new NFCTagReaderSession(NFCPollingOption.Iso14443, this, _queue) + { + AlertMessage = "TODO", + }; + + if (_session == null) + { + Console.WriteLine("Oh no! The session is null!"); + } + + _session.BeginSession(); + } + + public void Stop() + { + _session?.InvalidateSession(); + _session = null; + } + + public override void DidDetectTags(NFCTagReaderSession session, INFCTag[] tags) + { + Console.WriteLine("Did detect tags"); + + Console.WriteLine(tags[0].Type); + + //INFCIso7816Tag tag = tags[0].GetNFCIso7816Tag(); + INFCMiFareTag tag = tags[0].GetNFCMiFareTag(); + if (tag != null) + { + Console.WriteLine("Card ist valid"); + CardDiscovered?.Invoke(this, new Card(session, tag)); + } + else + { + Console.WriteLine("Card is not ISO7816"); + } + } + + public override void DidInvalidate(NFCTagReaderSession session, NSError error) + { + // TODO: decide what to do + Console.WriteLine("reader session invalidated"); + } + + } +} diff --git a/NFC/NFC.csproj b/NFC/NFC.csproj index 3c87e5e..519a331 100644 --- a/NFC/NFC.csproj +++ b/NFC/NFC.csproj @@ -1,12 +1,11 @@ - - - - netcoreapp3.1 - - - - - - - - + + + + netstandard2.1 + + + + + + +