Exemple #1
0
 public void StopListening(bool Dummy)
 {
     WriteMode = false;
     Enabled   = false;
     NfcSession?.InvalidateSession();
     NfcSession = null;
 }
        /// <summary>
        /// NFC読取セッションがタグを検知されたら呼び出される。
        /// </summary>
        /// <param name="session">NFC読取セッション</param>
        /// <param name="tags">検知タグ</param>
        public override void DidDetectTags(NFCTagReaderSession session, INFCTag[] tags)
        {
            Debug.WriteLine($"DidDetectTags");

            // タグに接続する。
            if (tags.Length <= 0)
            {
                return;
            }
            session.ConnectTo(tags[0], connectErr =>
            {
                // 接続エラー時はメッセージを表示してNFC読取セッションを終了する、
                if (connectErr != null)
                {
                    Debug.WriteLine($"Connect Error = [{connectErr}]");
                    session.InvalidateSession("タグ接続失敗。");
                    return;
                }

                // FeliCa準拠のタグプロトコルを取得する。
                _felicaTag = tags[0].GetNFCFeliCaTag();
                if (_felicaTag == null)
                {
                    return;
                }

                // FeliCaのRequest Serviceコマンドを実行し、
                // サービスコード0x090Fを指定し、カード種別およびカード残額情報サービスに接続する。
                // (サービスコードはリトルエンディアンで)
                _felicaTag.RequestService(ServiceCodes, OnCompletedRequestService);
            });
        }
Exemple #3
0
        protected override async Task OnTagDetected(NFCTagReaderSession session, INFCTag tag)
        {
            var amiibo = await TryReadAmiibo(session, tag);

            if (amiibo != null)
            {
                await OnAmiibo(amiibo, false);
            }
        }
        /// <summary>
        /// Suica読取開始。
        /// </summary>
        /// <param name="onScanAction">Suica検知デリゲート。引数はSuicaから読み取った残高と日付。</param>
        public void StartScanningSuica(Action <int, DateTime> onScanAction)
        {
            // Suica検知デリゲートを保存。
            _onScanAction = onScanAction;

            // NFC読取セッションを開始する。
            _session = new NFCTagReaderSession(NFCPollingOption.Iso18092, this, DispatchQueue.CurrentQueue);
            _session.AlertMessage = "Suica/Kitacaをかざして";
            _session.BeginSession();
        }
        public void BeginSession()
        {
            TryInvalidateSession();

            Session = new NFCTagReaderSession(
                NFCPollingOption.Iso14443,
                GetSessionDelegate(),
                DispatchQueue.MainQueue);

            Session.BeginSession();
        }
Exemple #6
0
 /// <summary>
 /// Invalidate the session
 /// </summary>
 /// <param name="session"><see cref="NFCTagReaderSession"/></param>
 /// <param name="message">Message to show</param>
 void Invalidate(NFCTagReaderSession session, string message = null)
 {
     _customInvalidation = true;
     if (string.IsNullOrWhiteSpace(message))
     {
         session.InvalidateSession();
     }
     else
     {
         session.InvalidateSession(message);
     }
 }
Exemple #7
0
        /// <summary>
        /// Starts tags detection
        /// </summary>
        public void StartListening()
        {
            _customInvalidation = false;
            _isWriting          = false;
            _isFormatting       = false;

            NfcSession = new NFCTagReaderSession(NFCPollingOption.Iso14443 | NFCPollingOption.Iso15693, this, DispatchQueue.CurrentQueue)
            {
                AlertMessage = UIMessages.NFCDialogAlertMessage
            };
            NfcSession?.BeginSession();
        }
Exemple #8
0
 /// <summary>
 /// Invalidate the session
 /// </summary>
 /// <param name="session"><see cref="NFCTagReaderSession"/></param>
 /// <param name="message">Message to show</param>
 void Invalidate(NFCTagReaderSession session, string message = null)
 {
     _customInvalidation = true;
     if (string.IsNullOrWhiteSpace(message))
     {
         session.InvalidateSession();
     }
     else
     {
         session.InvalidateSession(message);
     }
     OnTagListeningStatusChanged?.Invoke(false);
 }
Exemple #9
0
        public bool IsAvailable()
        {
            NfcSession = new NFCTagReaderSession(NFCPollingOption.Iso14443, this, null)
            {
                AlertMessage = "NFC not available."
            };

            if (NfcSession != null)
            {
                NfcSession.InvalidateSession();
                return(true);
            }
            return(false);
        }
Exemple #10
0
        /// <summary>
        /// Starts tag publishing (writing or formatting)
        /// </summary>
        /// <param name="clearMessage">Format tag</param>
        public void StartPublishing(bool clearMessage = false)
        {
            if (!IsAvailable)
            {
                throw new InvalidOperationException(UIMessages.NFCWritingNotSupported);
            }

            _customInvalidation = false;
            _isWriting          = true;
            _isFormatting       = clearMessage;

            NfcSession = new NFCTagReaderSession(NFCPollingOption.Iso14443 | NFCPollingOption.Iso15693, this, DispatchQueue.CurrentQueue)
            {
                AlertMessage = UIMessages.NFCDialogAlertMessage
            };
            NfcSession?.BeginSession();
        }
Exemple #11
0
        protected override async Task OnTagDetected(NFCTagReaderSession session, INFCTag tag)
        {
            if (SelectedAmiibo == null)
            {
                session.AlertMessage = "Select an amiibo to clone.";
                return;
            }

            if (SelectedAmiibo != null)
            {
                session.AlertMessage = $"Writing {SelectedAmiibo.Metadata.Name} to this tag...";

                await WriteAmiibo(session, tag.GetNFCMiFareTag(), SelectedAmiibo);

                return;
            }
        }
Exemple #12
0
        /// <summary>
        /// Event raised when an error happened during detection
        /// </summary>
        /// <param name="session">iOS <see cref="NFCTagReaderSession"/></param>
        /// <param name="error">iOS <see cref="NSError"/></param>
        public override void DidInvalidate(NFCTagReaderSession session, NSError error)
        {
            var readerError = (NFCReaderError)(long)error.Code;

            if (readerError != NFCReaderError.ReaderSessionInvalidationErrorFirstNDEFTagRead && readerError != NFCReaderError.ReaderSessionInvalidationErrorUserCanceled)
            {
                var alertController = UIAlertController.Create("Session Invalidated", error.LocalizedDescription, UIAlertControllerStyle.Alert);
                alertController.AddAction(UIAlertAction.Create("Ok", UIAlertActionStyle.Default, null));
                DispatchQueue.MainQueue.DispatchAsync(() =>
                {
                    GetCurrentController().PresentViewController(alertController, true, null);
                });
            }
            else if (readerError == NFCReaderError.ReaderSessionInvalidationErrorUserCanceled && !_customInvalidation)
            {
                OniOSReadingSessionCancelled?.Invoke(null, EventArgs.Empty);
            }
        }
        /// <summary>
        /// Event raised when NFC tags are detected
        /// </summary>
        /// <param name="session">iOS <see cref="NFCTagReaderSession"/></param>
        /// <param name="tags">Array of iOS <see cref="INFCTag"/></param>
        public override void DidDetectTags(NFCTagReaderSession session, INFCTag[] tags)
        {
            var _tag = tags.First();

            var connectionError = string.Empty;

            session.ConnectTo(_tag, (error) =>
            {
                if (error != null)
                {
                    connectionError = error.LocalizedDescription;
                    return;
                }
            });

            var nMifareTag = _tag.GetNFCMiFareTag();
            //nMifareTag.SendMiFareCommand();
        }
Exemple #14
0
        /// <summary>
        /// Event raised when NFC tags are detected
        /// </summary>
        /// <param name="session">iOS <see cref="NFCTagReaderSession"/></param>
        /// <param name="tags">Array of iOS <see cref="INFCTag"/></param>
        public override void DidDetectTags(NFCTagReaderSession session, INFCTag[] tags)
        {
            var _tag = tags.First();

            var connectionError = string.Empty;

            session.ConnectTo(_tag, (error) =>
            {
                if (error != null)
                {
                    connectionError = error.LocalizedDescription;
                    return;
                }
            });

            var nMifareTag = _tag.GetNFCMiFareTag();

            var t = WriteMode ? Task.Run(() => HandleWiteTag(nMifareTag)):
                    Task.Run(() => HandleReadTag(nMifareTag));
        }
Exemple #15
0
        public void StartListening(bool Write)
        {
            if (!IsAvailable())
            {
                throw new InvalidOperationException("NFC not available");
            }

            if (!IsEnabled()) // todo: offer possibility to open dialog
            {
                throw new InvalidOperationException("NFC is not enabled");
            }

            WriteMode = Write;

            NfcSession = new NFCTagReaderSession(NFCPollingOption.Iso14443, this, null)
            {
                AlertMessage = "Present your NFC tag"
            };

            NfcSession?.BeginSession();
            Enabled = true;
        }
        public async Task <byte[]> ReadTagData(
            NFCTagReaderSession session, INFCTag tag)
        {
            await session.ConnectToAsync(tag);

            var mifare = tag.GetNFCMiFareTag();

            if (mifare is null)
            {
                return(new byte[0]); // not a mifare tag
            }
            var tagData =
                await mifare.DoFastRead(
                    from : 0x0, to : 0x86,
                    batchSize : 0x43
                    );

            Debug.WriteLine(
                "Tag Data:\r\n" +
                Utils.HexDump(tagData, 8));

            return(tagData);
        }
Exemple #17
0
        public async Task WriteAmiibo(NFCTagReaderSession session, INFCMiFareTag tag, DetectedAmiibo amiibo)
        {
            var dynamicLockBytes = new byte[] { 0x01, 0x00, 0x0F, 0xBD };
            var staticLockBytes  = new byte[] { 0x0F, 0xE0, 0x0F, 0xE0 };

            var dump = amiibo.TagData;

            // this is ille🚨al so i took it out, but the flow is:
            // 1. make a copy of the tag dump
            // 2. decrypt the encrypted part of the tag dump using the original tag uid and secret nintendo key material
            // 3. reencrypt the now decrypted parts of the tag dump using the uid of the target tag and secret nintendo key material
            // 4. write the tag dump (not the lock bits) to the tag
            // 5. write the dynamic lock bits to 0x82
            // 6. write the static lock bits to 0x2
            // 7. draw the amiibo on the card for good luck

            // check https://www.3dbrew.org/wiki/Amiibo for amiibo data structure
            // check https://github.com/AcK77/AmiiBomb-uino for a good cloning reference

            await Task.Yield();

            session.AlertMessage = "Various implementation details removed and left to the reader (check the source).";
        }
Exemple #18
0
        void MakeTagReadOnly(NFCTagReaderSession session, INFCTag tag, INFCNdefTag ndefTag)
        {
            session.ConnectTo(tag, (error) =>
            {
                if (error != null)
                {
                    Console.WriteLine(error.LocalizedDescription);
                    return;
                }

                ndefTag.WriteLock((error) =>
                {
                    if (error != null)
                    {
                        Console.WriteLine("Error when locking a tag on iOS: " + error.LocalizedDescription);
                    }
                    else
                    {
                        Console.WriteLine("Locking Successful!");
                    }
                });
            });
        }
 public override void DidInvalidate(NFCTagReaderSession session, NSError error)
 => _DidInvalidate?.Invoke(session, error);
 public override void DidDetectTags(NFCTagReaderSession session, INFCTag[] tags)
 => _DidDetectTags?.Invoke(session, tags);
 public override void DidBecomeActive(NFCTagReaderSession session)
 => _DidBecomeActive?.Invoke(session);
Exemple #22
0
 public override void DidInvalidate(NFCTagReaderSession session, NSError error)
 {
     MainTabViewModel.Current.cbNFCRead  = false;
     MainTabViewModel.Current.cbNFCWrite = false;
 }
Exemple #23
0
        /// <summary>
        /// Event raised when NFC tags are detected
        /// </summary>
        /// <param name="session">iOS <see cref="NFCTagReaderSession"/></param>
        /// <param name="tags">Array of iOS <see cref="INFCTag"/></param>
        public override void DidDetectTags(NFCTagReaderSession session, INFCTag[] tags)
        {
            _customInvalidation = false;
            _tag = tags.First();

            var connectionError = string.Empty;

            session.ConnectTo(_tag, (error) =>
            {
                if (error != null)
                {
                    connectionError = error.LocalizedDescription;
                    Invalidate(session, connectionError);
                    return;
                }

                var ndefTag = GetNdefTag(_tag);

                if (ndefTag == null)
                {
                    Invalidate(session, Configuration.Messages.NFCErrorNotCompliantTag);
                    return;
                }

                ndefTag.QueryNdefStatus((status, capacity, error) =>
                {
                    if (error != null)
                    {
                        Invalidate(session, error.LocalizedDescription);
                        return;
                    }

                    var isNdefSupported = status != NFCNdefStatus.NotSupported;

                    var identifier = GetTagIdentifier(ndefTag);
                    var nTag       = new TagInfo(identifier, isNdefSupported)
                    {
                        IsWritable = status == NFCNdefStatus.ReadWrite,
                        Capacity   = Convert.ToInt32(capacity)
                    };

                    if (!isNdefSupported)
                    {
                        session.AlertMessage = Configuration.Messages.NFCErrorNotSupportedTag;

                        OnMessageReceived?.Invoke(nTag);
                        Invalidate(session);
                        return;
                    }

                    if (_isWriting)
                    {
                        // Write mode
                        OnTagDiscovered?.Invoke(nTag, _isFormatting);
                    }
                    else
                    {
                        // Read mode
                        ndefTag.ReadNdef((message, error) =>
                        {
                            // iOS Error: NFCReaderError.NdefReaderSessionErrorZeroLengthMessage (NDEF tag does not contain any NDEF message)
                            // NFCReaderError.NdefReaderSessionErrorZeroLengthMessage constant should be equals to 403 instead of 304
                            // see https://developer.apple.com/documentation/corenfc/nfcreadererror/code/ndefreadersessionerrorzerolengthmessage
                            if (error != null && error.Code != 403)
                            {
                                Invalidate(session, Configuration.Messages.NFCErrorRead);
                                return;
                            }

                            session.AlertMessage = Configuration.Messages.NFCSuccessRead;

                            nTag.Records = GetRecords(message?.Records);
                            OnMessageReceived?.Invoke(nTag);
                            Invalidate(session);
                        });
                    }
                });
            });
        }
Exemple #24
0
        /// <summary>
        /// Writes or clears a TAG
        /// </summary>
        /// <param name="session"><see cref="NFCTagReaderSession"/></param>
        /// <param name="tag"><see cref="INFCNdefTag"/></param>
        /// <param name="tagInfo"><see cref="ITagInfo"/></param>
        /// <param name="clearMessage">Clear message</param>
        void ExecuteWriteOrClear(NFCTagReaderSession session, INFCNdefTag tag, ITagInfo tagInfo, bool clearMessage = false)
        {
            tag.QueryNdefStatus((status, capacity, error) =>
            {
                if (error != null)
                {
                    Invalidate(session, error.LocalizedDescription);
                    return;
                }

                if (status == NFCNdefStatus.ReadOnly)
                {
                    Invalidate(session, UIMessages.NFCErrorReadOnlyTag);
                    return;
                }

                if (Convert.ToInt32(capacity) < NFCUtils.GetSize(tagInfo.Records))
                {
                    Invalidate(session, UIMessages.NFCErrorCapacityTag);
                    return;
                }

                NFCNdefMessage message = null;
                if (!clearMessage)
                {
                    session.AlertMessage = UIMessages.NFCSuccessWrite;

                    var records = new List <NFCNdefPayload>();
                    for (var i = 0; i < tagInfo.Records.Length; i++)
                    {
                        var record = tagInfo.Records[i];
                        if (GetiOSPayload(record) is NFCNdefPayload ndefPayload)
                        {
                            records.Add(ndefPayload);
                        }
                    }

                    if (records.Any())
                    {
                        message = new NFCNdefMessage(records.ToArray());
                    }
                }
                else
                {
                    session.AlertMessage = UIMessages.NFCSuccessClear;
                    message = GetEmptyNdefMessage();
                }

                if (message != null)
                {
                    tag.WriteNdef(message, (error) =>
                    {
                        if (error != null)
                        {
                            Invalidate(session, error.LocalizedDescription);
                            return;
                        }

                        tagInfo.Records = GetRecords(message.Records);
                        OnMessagePublished?.Invoke(tagInfo);
                        Invalidate(NfcSession);
                    });
                }
                else
                {
                    Invalidate(session, UIMessages.NFCErrorWrite);
                }
            });
        }
 /// <summary>
 /// NFC読取セッションが無効になった際に呼び出される。
 /// </summary>
 /// <param name="session">無効になったセッション</param>
 /// <param name="error">無効になった理由</param>
 public override void DidInvalidate(NFCTagReaderSession session, NSError error)
 {
     Debug.WriteLine($"DidInvalidate. error=[{error}]");
     _session.Dispose();
     _session = null;
 }
 protected async virtual Task OnTagDetected(NFCTagReaderSession session, INFCTag tag)
 {
     await ReadTagData(session, tag);
 }
 public override void DidInvalidate(NFCTagReaderSession session, NSError error)
 {
     //  throw new NotImplementedException();
 }
Exemple #28
0
        /// <summary>
        /// Event raised when NFC tags are detected
        /// </summary>
        /// <param name="session">iOS <see cref="NFCTagReaderSession"/></param>
        /// <param name="tags">Array of iOS <see cref="INFCTag"/></param>
        public override void DidDetectTags(NFCTagReaderSession session, INFCTag[] tags)
        {
            _customInvalidation = false;
            _tag = tags.First();

            var connectionError = string.Empty;

            session.ConnectTo(_tag, (error) =>
            {
                if (error != null)
                {
                    connectionError = error.LocalizedDescription;
                    Invalidate(session, connectionError);
                    return;
                }

                var ndefTag = GetNdefTag(_tag);

                if (ndefTag == null)
                {
                    Invalidate(session, UIMessages.NFCErrorNotCompliantTag);
                    return;
                }

                ndefTag.QueryNdefStatus((status, capacity, error) =>
                {
                    if (error != null)
                    {
                        Invalidate(session, error.LocalizedDescription);
                        return;
                    }

                    if (status == NFCNdefStatus.NotSupported)
                    {
                        Invalidate(session, UIMessages.NFCErrorNotSupportedTag);
                        return;
                    }

                    var identifier = GetTagIdentifier(ndefTag);
                    var nTag       = new TagInfo(identifier)
                    {
                        IsWritable = status == NFCNdefStatus.ReadWrite
                    };

                    if (_isWriting)
                    {
                        // Write mode
                        OnTagDiscovered?.Invoke(nTag, _isFormatting);
                    }
                    else
                    {
                        // Read mode
                        ndefTag.ReadNdef((message, error) =>
                        {
                            if (error != null)
                            {
                                Invalidate(session, UIMessages.NFCErrorRead);
                                return;
                            }

                            if (message == null)
                            {
                                Invalidate(session, UIMessages.NFCErrorEmptyTag);
                                return;
                            }

                            session.AlertMessage = UIMessages.NFCSuccessRead;

                            nTag.Records = GetRecords(message.Records);
                            OnMessageReceived?.Invoke(nTag);
                            Invalidate(session);
                        });
                    }
                });
            });
        }
Exemple #29
0
        public async Task <DetectedAmiibo> TryReadAmiibo(NFCTagReaderSession session, INFCTag tag)
        {
            // dump tag data
            Debug.WriteLine($"Found a tag: {tag}");

            // get mifare representation
            var mifareTag  = tag.GetNFCMiFareTag();
            var identifier = mifareTag.Identifier.ToArray();

            // connect w h y
            await session.ConnectToAsync(tag);

            // read entire tag contents
            var tagData =
                await mifareTag.DoFastRead(
                    from : 0x0, to : 0x86,
                    batchSize : 0x20
                    );

            // dump tag data
            Debug.WriteLine($"== Raw tag data ==\r\n" +
                            $"{Utils.HexDump(tagData, 16)}");

            // extract character identifiers
            var identificationHeader = tagData.Slice(0x15 * 4, 0x2 * 4);

            var uid       = identifier.String();
            var game      = identificationHeader.SliceStr(0, 4);
            var character = identificationHeader.SliceStr(4, 4);

            // print identifiers
            Debug.WriteLine(
                $"== Identifiers ==\r\n" +
                $"Nfc Uid: {uid}\r\n" +
                $"Game Id: {game}\r\n" +
                $"Char Id: {character}\r\n");

            // get metadata from amiibo api
            session.AlertMessage = $"Looking up Amiibo...";

            var lookup = await AmiiboApi.GetAmiibo(game, character);

            var metadata = lookup.Amiibo.FirstOrDefault();

            // dump metadata
            Debug.WriteLine(
                $"== Metadata : https://www.amiiboapi.com/api/ ==\r\n" +
                metadata.ToJson());

            // we did it!
            session.AlertMessage = $"It's {metadata.Name}!";

            var imageData = await new HttpClient().GetByteArrayAsync(metadata.Image);

            return(new DetectedAmiibo
            {
                UID = uid,
                CharacterId = $"{game}-{character}",
                Metadata = metadata,
                TagData = tagData,
                ImageData = imageData,
            });
        }