private void Llcp_ConnectionChanged(object sender, LLCPLinkActivatedEventArgs e)
 {
     if (e.Connected)
     {
         lock (Pinning.SpiLock)
         {
             Console.WriteLine("LLCP open");
             LLCP llcp = (LLCP)sender;
             SnepServiceManager snepServiceManager = llcp.SnepServiceManager;
             if (snepServiceManager != null)
             {
                 Console.WriteLine("Snep service found");
                 NdefLibrary.Ndef.NdefMessage   message   = new NdefLibrary.Ndef.NdefMessage();
                 NdefLibrary.Ndef.NdefUriRecord uriRecord = new NdefLibrary.Ndef.NdefUriRecord();
                 uriRecord.Uri = "http://www.koolecontrols.nl";
                 //NdefLibrary.Ndef.NdefTextRecord textRecord = new NdefLibrary.Ndef.NdefTextRecord();
                 //textRecord.LanguageCode = "en";
                 //textRecord.Text = "Wat een geweldige test is dit";
                 message.Add(uriRecord);
                 byte[] ndef = message.ToByteArray();
                 snepServiceManager.SendNdefMessage(ndef);
             }
         }
     }
     else
     {
         Console.WriteLine("LLCP closed");
     }
 }
Beispiel #2
0
            public bool SendMessage(byte[] message, out byte[] response)
            {
                bool result = false;

                response = new byte[0];
                if (LinkManager != null)
                {
                    byte[] llcp = LLCP.GetFrame(DSAP, LLCP.PTYPES.I, SSAP, 0, message);
                    if (LinkManager.Tranceive(llcp, out response))
                    {
                        //check response
                        result = true;
                    }
                }
                return(result);
            }
Beispiel #3
0
            public bool Disconnect()
            {
                bool result = false;

                if (LinkManager != null)
                {
                    byte[] disconnectRequest = LLCP.GetFrame(DSAP, LLCP.PTYPES.DISC, SSAP, 0, new byte[0]);
                    byte[] response          = new byte[0];
                    if (LinkManager.Tranceive(disconnectRequest, out response))
                    {
                        // check response
                        result = true;
                    }
                }
                return(result);
            }
Beispiel #4
0
        void MainFormFormClosed(object sender, FormClosedEventArgs e)
        {
            if (llcp != null)
            {
                llcp.Stop();
                llcp = null;
            }

            ReleaseReader();

            Settings s = new Settings();

            s.SelectedMode = Settings.MODE_SEND_AND_RECV;
            if (rbRecvOnly.Checked)
            {
                s.SelectedMode = Settings.MODE_RECV_ONLY;
            }
            else
            if (rbSendOnly.Checked)
            {
                s.SelectedMode = Settings.MODE_SEND_ONLY;
            }
            else
            if (rbRecvThenSend.Checked)
            {
                s.SelectedMode = Settings.MODE_RECV_THEN_SEND;
            }
            else
            if (rbSendThenRecv.Checked)
            {
                s.SelectedMode = Settings.MODE_SEND_THEN_RECV;
            }
            else
            if (rbSendAndRecv.Checked)
            {
                s.SelectedMode = Settings.MODE_SEND_AND_RECV;
            }

            s.SelectedType = cbNdefType.SelectedIndex;

            s.Save();
        }
Beispiel #5
0
            public bool Connect(byte ssap, LLCPParameters parameters)
            {
                bool result = false;

                if (LinkManager != null)
                {
                    this.SSAP = ssap;
                    byte[] payload        = parameters.GetParams();
                    byte[] connectRequest = LLCP.GetFrame((byte)WelKnownServiceAccessPoints.ServiceDiscoveryProtocolService, LLCP.PTYPES.CONNECT, ssap, 0, payload);
                    byte[] response       = new byte[0];
                    if (LinkManager.Tranceive(connectRequest, out response))
                    {
                        if (response.Length > 2)
                        {
                            this.DSAP = (byte)(response[2] & 0x3F);
                            // check response
                            Connected = true;
                        }
                    }
                }
                return(result);
            }
Beispiel #6
0
        void ReaderStatusChanged(uint ReaderState, CardBuffer CardAtr)
        {
            /* The ReaderStatusChanged function is called as a delegate (callback) by the SCardReader object    */
            /* within its backgroung thread. Therefore we must use the BeginInvoke syntax to switch back from   */
            /* the context of the background thread to the context of the application's main thread. Overwise   */
            /* we'll get a security violation when trying to access the window's visual components (that belong */
            /* to the application's main thread and can't be safely manipulated by background threads).         */
            if (InvokeRequired)
            {
                this.BeginInvoke(new ReaderStatusChangedInvoker(ReaderStatusChanged), ReaderState, CardAtr);
                return;
            }

            string s = SCARD.ReaderStatusToString(ReaderState);

            Trace.WriteLine("ReaderStatusChanged: " + s);
            eReaderStatus.Text = s;

            if (CardAtr != null)
            {
                s             = CardAtr.AsString(" ");
                eCardAtr.Text = s;
                Trace.WriteLine("\t" + s);
            }
            else
            {
                eCardAtr.Text = "";
            }

            if (ReaderState == SCARD.STATE_UNAWARE)
            {
                if (llcp != null)
                {
                    llcp.Stop();
                    llcp = null;
                }

                MessageBox.Show("The reader we were working on has disappeared from the system. This application will terminate now.",
                                "The reader has been removed",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Exclamation);

                Application.Exit();
            }
            else if ((ReaderState & SCARD.STATE_UNAVAILABLE) != 0)
            {
                Trace.WriteLine("Card unavailable");
            }
            else if ((ReaderState & SCARD.STATE_MUTE) != 0)
            {
                Trace.WriteLine("Card mute");
            }
            else if ((ReaderState & SCARD.STATE_INUSE) != 0)
            {
                Trace.WriteLine("Card in use");
            }
            else if ((ReaderState & SCARD.STATE_EMPTY) != 0)
            {
                Trace.WriteLine("Card absent");

                if (llcp != null)
                {
                    Trace.WriteLine("*** Target lost ***");

                    llcp.Stop();
                    llcp = null;

                    PerformStatusChange();
                }

                pControl.Enabled = true;
            }
            else if ((ReaderState & SCARD.STATE_PRESENT) != 0)
            {
                Trace.WriteLine("Card present");

                if ((llcp == null) && ((ReaderState & SCARD.STATE_INUSE) == 0))
                {
                    /* Try to work with this card, it may be a LLCP peer */
                    reader.StopMonitor();

                    pControl.Enabled = false;
                    Trace.WriteLine("*** Starting LLCP ***");

                    llcp = new LlcpInitiator(reader);

                    switch (status)
                    {
                    case Status.SendAndRecv_Ready:
                        /* We are both a receiver and a sender */
                        StartReceiver();
                        StartSender();
                        break;

                    case Status.RecvOnly_Ready:
                    case Status.RecvThenSend_RecvReady:
                    case Status.SendThenRecv_RecvReady:
                        /* We are a receiver */
                        StartReceiver();
                        break;

                    case Status.SendOnly_Ready:
                    case Status.RecvThenSend_SendReady:
                    case Status.SendThenRecv_SendReady:
                        /* We are a sender */
                        StartSender();
                        break;

                    default:
                        break;
                    }

                    if (!llcp.Start())
                    {
                        Trace.WriteLine("*** Failed to start LLCP ***");
                        MessageBox.Show("Failed to instantiate LLCP layer on the newly inserted card. This is likely to be caused by another application taking control of the card before us. Please close all other PC/SC-aware applications. It may also be required to instruct Windows to stop probing the card, see the paragraph pcsc_no_minidriver in the Readme of the PC/SC SDK for more informations.", "Communication error");
                        llcp             = null;
                        pControl.Enabled = true;
                    }

                    reader.StartMonitor(new SCardReader.StatusChangeCallback(ReaderStatusChanged));
                }
            }
        }
        public void ScanForISO14443TypeADevices(int scanTimeInMilliseconds)
        {
            Data106kbpsTypeA cardTypeA;
            // This will try to select the card for 1 second and will wait 300 milliseconds before trying again if none is found
            bool retok = false;

            lock (Pinning.SpiLock)
            {
                //Chip.OutputAllRegisters();
                retok = Chip.ListenToCardIso14443TypeA(TransmitterRadioFrequencyConfiguration.Iso14443A_Nfc_PI_106_106, ReceiverRadioFrequencyConfiguration.Iso14443A_Nfc_PI_106_106, out cardTypeA, scanTimeInMilliseconds);

                if (retok)
                {
                    Hold = true;
                    Console.WriteLine($"ISO 14443 Type A found:");
                    Console.WriteLine($"  ATQA: {cardTypeA.Atqa}");
                    Console.WriteLine($"  SAK: {cardTypeA.Sak}");
                    Console.WriteLine($"  UID: {BitConverter.ToString(cardTypeA.NfcId)}");

                    if (Nfcip1.IsNfcipCompliant(cardTypeA.Sak, cardTypeA.NfcId))
                    {
                        Console.WriteLine($"NFCIP1 compliant!!");
                        if ((cardTypeA.Sak & 0x20) == 0x20)
                        {
                            if (llcp != null)
                            {
                                llcp.Stop();
                            }
                            llcp = new LLCP(Chip, cardTypeA);
                            llcp.ConnectionChanged += Llcp_ConnectionChanged;
                            llcp.Start();
                        }
                    }
                    else
                    {
                        // This is where you do something with the card
                        MifareCard mifareCard = new MifareCard(Chip, cardTypeA.TargetNumber);
                        mifareCard.SetCapacity(cardTypeA.Atqa, cardTypeA.Sak);
                        mifareCard.SerialNumber = GetMifareSerialNumber(cardTypeA.NfcId);
                        mifareCard.KeyA         = new byte[6] {
                            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
                        };
                        mifareCard.KeyB = new byte[6] {
                            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
                        };

                        //http://nfc-tools.org/index.php/ISO14443A
                        if ((cardTypeA.Sak == 0x00) && (cardTypeA.Atqa == 0x0044))
                        {
                            // Mifare ultralight
                            // https://www.nxp.com/docs/en/data-sheet/NTAG210_212.pdf
                            // Seems MifareCard is not 100% compatible as Getversion is the same commeand as AuthenticationA
                            // We do need GetVersion to detect the size of the NTAG21X memmory size so we probably better create a new object for hanling NTAG21X Cards
                            // Also password handling etc is done totally different
                            int ret = 0;

                            mifareCard.Command = MifareCardCommand.Read16Bytes;

                            //note a block is 4 bytes, as we read 16 bytes there are 4 blocks in one read
                            for (byte block = 0; block < 64; block++)
                            {
                                mifareCard.BlockNumber = (byte)(block * 4);
                                mifareCard.Command     = MifareCardCommand.Read16Bytes;
                                ret = mifareCard.RunMifiCardCommand();
                                if (ret >= 0)
                                {
                                    Console.WriteLine($"Block: {block * 4}-{(block * 4) + 3}, Data: {BitConverter.ToString(mifareCard.Data)}");
                                }
                                else
                                {
                                    Console.WriteLine($"Error reading block: {block}, Data: {BitConverter.ToString(mifareCard.Data)}");
                                }
                            }
                        }
                        else if ((cardTypeA.Sak == 0x08) && (cardTypeA.Atqa == 0x0004))
                        {
                            //Mifare classic 1k
                            int ret = 0;
                            for (byte block = 0; block < 64; block++)
                            {
                                mifareCard.BlockNumber = block;
                                mifareCard.Command     = MifareCardCommand.AuthenticationA;
                                ret = mifareCard.RunMifiCardCommand();
                                if (ret >= 0)
                                {
                                    mifareCard.BlockNumber = block;
                                    mifareCard.Command     = MifareCardCommand.Read16Bytes;
                                    ret = mifareCard.RunMifiCardCommand();
                                    if (ret >= 0)
                                    {
                                        Console.WriteLine($"Block: {block}, Data: {BitConverter.ToString(mifareCard.Data)}");
                                        if (block % 4 == 3)
                                        {
                                            // Check what are the permissions
                                            for (byte j = 3; j > 0; j--)
                                            {
                                                var access = mifareCard.BlockAccess((byte)(block - j), mifareCard.Data);
                                                Console.WriteLine($"Block: {block - j}, Access: {access}");
                                            }
                                            var sector = mifareCard.SectorTailerAccess(block, mifareCard.Data);
                                            Console.WriteLine($"Block: {block}, Access: {sector}");
                                        }
                                    }
                                    else
                                    {
                                        Console.WriteLine($"Error reading block: {block}, Data: {BitConverter.ToString(mifareCard.Data)}");
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            while (Hold)
            {
                Thread.Sleep(100);
            }
        }