Exemple #1
0
        private void btnSend_Click(object sender, EventArgs e)
        {
            try
            {
                RespApdu respApdu = mPcscReader.Exchange(txtAPDU.Text);

                ml.NewLine();
                ml.AddLine("Send: " + txtAPDU.Text);
                if (respApdu.Data != null && respApdu.Data.Length > 0)
                {
                    //ml.AddLine("Resp: " + HexFormatting.ToHexString(respApdu.Data, true));
                    ml.AddLine(String.Format("Resp({0}B): {1}", respApdu.Data.Length,
                                             HexFormatting.ToHexString(respApdu.Data, true)));
                }
                else
                {
                    ml.AddLine("Resp: (None)");
                }

                ml.AddLine("Status: " + respApdu.SW1SW2.Value.ToString("X4"));

                txtMessage.Text = ml.Text;
            }
            catch (WinSCardException ex)
            {
                txtMessage.Text = ml.AddLine(ex.WinSCardFunctionName + " Error 0x" +
                                             ex.Status.ToString("X08") + ": " + ex.Message);
            }
            catch (Exception ex)
            {
                txtMessage.Text = ml.AddLine(ex.Message);
            }
        }
        /// <summary>
        /// Convert byte sequence to HEX representation.
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="formatting">HEX string formatting.</param>
        /// <param name="upperCase">Should hex litteral be in upper case.</param>
        /// <returns>Formatted HEX representation of bytes.</returns>
        public static string ToHexString(this ArraySegment <byte> bytes, HexFormatting formatting = HexFormatting.Default, bool upperCase = true)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException(nameof(bytes));
            }

            var prefix = GetFilteredPrefixes(formatting).FirstOrDefault();
            var offset = prefix?.Length ?? 0;

            var c = new char[offset + bytes.Count * 2];

            for (var i = 0; i < offset; i++)
            {
                c[i] = prefix[i];
            }

            byte      b;
            var       letterOffset = upperCase ? 0x37 : 0x57;
            const int digitOffset  = 0x30;

            for (int bx = 0, cx = 0; bx < bytes.Count; ++bx, ++cx)
            {
                b = (byte)(bytes[bx] >> 4);
                c[offset + cx] = (char)(b > 9 ? b + letterOffset : b + digitOffset);

                b = (byte)(bytes[bx] & 0x0F);
                c[offset + (++cx)] = (char)(b > 9 ? b + letterOffset : b + digitOffset);
            }

            return(new string(c));
        }
        static void write_to_tag(String bytes_in)
        {
            string command  = "FF D6 00 ";
            int    byte_num = 0;
            int    value;
            //string address = String.Format("{0:X}", value);
            String Hex_address;

            Byte[] Input_bytes = hex_string_to_byte_array(string_to_hex_string(bytes_in));
            byte[] send_chunk  = new byte[4];

            RespApdu write_four_bytes;

            for (int i = 0; i < Input_bytes.Length; i = i + 4)
            {
                for (int j = 0; j < 4; j++)
                {
                    if (j + i < Input_bytes.Length)
                    {
                        send_chunk[j] = Input_bytes[j + i];
                    }
                }

                value            = Convert.ToInt32(byte_num);
                Hex_address      = String.Format("{0:X}", value);
                command          = command + Hex_address + " 04 " + HexFormatting.ToHexString(send_chunk, true);
                write_four_bytes = reader.Exchange(command);
                byte_num         = byte_num + 1;
            }
        }
        /// <summary>
        /// The SCardTransmit function sends a service request to the smart card and expects to receive data back from the card.
        /// </summary>
        /// <param name="sendBuffer">
        /// The actual data to be written to the card.
        /// </param>
        /// <param name="sendLength">
        /// The length, in bytes, of the sendBuffer parameter.
        /// </param>
        /// <param name="responseBuffer">
        /// Returned data from the card.
        /// </param>
        /// <param name="responseLength">
        /// Supplies the length, in bytes, of the responseBuffer parameter and receives the actual
        /// number of bytes received from the smart card.
        /// </param>
        public void Transmit(byte[] sendBuffer, int sendLength, byte[] responseBuffer, ref int responseLength)
        {
            SCARD_IO_REQUEST SCARD_PCI;

            SCARD_PCI.dwProtocol  = (uint)activeSCardProtocol;
            SCARD_PCI.cbPciLength = 8;

            Trace.WriteLineIf(this.scardTrace, HexFormatting.Dump("--> C-APDU: 0x", sendBuffer, sendLength, 16, ValueFormat.HexASCII));

            int ret = WinSCardAPIWrapper.SCardTransmit(phCARD, ref SCARD_PCI, sendBuffer,
                                                       sendLength,
                                                       IntPtr.Zero,
                                                       responseBuffer,
                                                       ref responseLength);

            if (ret == 0)
            {
                RespApdu respApdu = new RespApdu(responseBuffer, responseLength);
                Trace.WriteLineIf(scardTrace, respApdu.ToString());
            }
            else
            {
                throw new WinSCardException(scardTrace, "SCard.Transmit", ret);
            }
        }
Exemple #5
0
        public byte[] RsReset()
        {
            try
            {
                RespApdu respApdu = mReader.Exchange("A4 0A 00 00 08"); // Get Random Number

                //Console.WriteLine("Random  = 0x" + HexFormatting.ToHexString(respApdu.Data, true));
                if (respApdu != null)
                {
                    baRandom  = respApdu.Data;
                    strRandom = HexFormatting.ToHexString(baRandom, true);
                }
                else
                {
                    baRandom = new byte[8];
                    Array.Clear(baRandom, 0, 8);
                }

                return(baRandom);
            }
            catch (WinSCardException ex)
            {
                //Console.WriteLine(ex.WinSCardFunctionName + " Error 0x" +
                //                   ex.Status.ToString("X08") + ": " + ex.Message);
                throw ex;
            }
            catch (Exception ex)
            {
                //Console.WriteLine(ex.Message);
                throw ex;
            }
        }
Exemple #6
0
 public void ConvertError(string input, HexFormatting formatting, string expectedError)
 {
     Assert.That(() => HexEncodingExtensions.FromHexString(input, formatting),
                 Throws.Exception
                 .InstanceOf <ArgumentException>()
                 .With.Message.EqualTo(expectedError));
 }
Exemple #7
0
        public void Convert(string input, HexFormatting formatting, string expected)
        {
            var bytes  = HexEncodingExtensions.FromHexString(input, formatting);
            var actual = HexEncodingExtensions.ToHexString(bytes, formatting);

            Assert.AreEqual(expected, actual);
        }
Exemple #8
0
        public static string cardProtocol()
        {
            WinSCard scard = new WinSCard();

            try
            {
                scard.EstablishContext();
                scard.ListReaders();
                string readerName = scard.ReaderNames[1];
                scard.WaitForCardPresent(readerName);


                scard.Connect(readerName);
                byte[] cmdApdu    = { 0xFF, 0xCA, 0x00, 0x00, 00 }; // Get Card UID ...
                byte[] respApdu   = new byte[10];
                int    respLength = respApdu.Length;

                scard.Transmit(cmdApdu, cmdApdu.Length, respApdu, ref respLength);

                //find a better place for this
                App.UID = HexFormatting.ToHexString(respApdu, true);

                //he wanted some kinda beeping sound when someone swipes their card
                System.Media.SystemSounds.Beep.Play();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }

            return(App.UID);
        }
        /// <summary>
        /// The SCardGetAttrib function gets the current reader attributes.
        /// It does not affect the state of the reader, driver, or card.
        /// </summary>
        /// <param name="attrId">
        /// Identifier for the attribute to get.
        /// </param>
        /// <param name="responseBuffer">
        /// The response buffer.
        /// </param>
        /// <param name="responseLength">
        /// Supplies the length of the responseBuffer in bytes, and receives the actual length
        /// of the received attribute.
        /// </param>
        public void GetAttrib(uint attrId, byte[] responseBuffer, ref int responseLength)
        {
            Trace.WriteLineIf(this.scardTrace, string.Format("    SCard.SCardGetAttrib(AttrId: {0})", (SCARD_ATTR)attrId));

            int ret = WinSCardAPIWrapper.SCardGetAttrib(phCARD, (uint)attrId, responseBuffer, ref responseLength);

            if (ret == 0)
            {
                Trace.WriteLineIf(this.scardTrace, HexFormatting.Dump("        Attr. Value: 0x", responseBuffer, responseLength, 16, ValueFormat.HexASCII));
            }
            else
            {
                throw new WinSCardException(scardTrace, "SCard.Control", ret);
            }
        }
        /// <summary>
        /// The SCardReconnect function reestablishes an existing connection between the calling application and
        /// a smart card. This function moves a card handle from direct access to general access, or acknowledges
        /// and clears an error condition that is preventing further access to the card.
        /// </summary>
        /// <param name="dwShareMode">
        /// A flag that indicates whether other applications may form connections to the card.
        /// </param>
        /// <param name="dwPrefProtocol">
        /// A bitmask of acceptable protocols for the connection. Possible values may be combined with the OR operation.
        /// </param>
        /// <param name="disconnectAction">
        /// Action to take on the card in the connected reader on close.
        /// </param>
        /// <returns>
        /// If the function succeeds, the function returns SCARD_S_SUCCESS.
        /// If the function fails, it returns an error code.
        /// </returns>
        public void Reconnect(SCARD_SHARE_MODE dwShareMode, SCARD_PROTOCOL dwPrefProtocol, SCARD_DISCONNECT disconnectAction)
        {
            int ret = WinSCardAPIWrapper.SCardReconnect(phCARD, (uint)dwShareMode, (uint)dwPrefProtocol,
                                                        (uint)disconnectAction, out activeSCardProtocol);

            if (ret == 0)
            {
                Trace.WriteLineIf(scardTrace, String.Format("    SCard.Reconnect(SHARE_MODE.{0}, SCARD_PROTOCOL.{1}, SCARD_DISCONNECT.{2} )",
                                                            dwShareMode, (SCARD_PROTOCOL)dwPrefProtocol, (SCARD_DISCONNECT)disconnectAction));
                Trace.WriteLineIf(scardTrace, String.Format("        Active Protocol: SCARD_PROTOCOL.{0} ", (SCARD_PROTOCOL)activeSCardProtocol));
                Trace.WriteLineIf(this.TraceSCard, HexFormatting.Dump("        ATR: 0x", this.Atr, this.Atr.Length, 24));
            }
            else
            {
                throw new WinSCardException(scardTrace, "SCard.Reconnect", ret);
            }
        }
        /// <summary>
        /// The SCardConnect function establishes a connection (using a specific resource manager context)
        /// between the calling application and a smart card contained by a specific reader.
        /// If no card exists in the specified reader, an error is returned.
        /// </summary>
        /// <param name="szReader">
        /// The name of the reader that contains the target card.
        /// </param>
        /// <param name="dwShareMode">
        /// A flag that indicates whether other applications may form connections to the card.
        /// </param>
        /// <param name="dwPrefProtocol">
        /// A bitmask of acceptable protocols for the connection. Possible values may be combined with the OR operation.
        /// </param>
        public void Connect(string szReader, SCARD_SHARE_MODE dwShareMode, SCARD_PROTOCOL dwPrefProtocol)
        {
            int ret = WinSCardAPIWrapper.SCardConnect(phContext, szReader, (uint)dwShareMode, (uint)dwPrefProtocol, out phCARD, out activeSCardProtocol);

            if (ret == 0)
            {
                connectedReaderName = szReader;
                Trace.WriteLineIf(scardTrace, String.Format("    SCard.Connect({0}, SHARE_MODE.{1}, SCARD_PROTOCOL.{2})",
                                                            szReader, dwShareMode, (SCARD_PROTOCOL)dwPrefProtocol));
                Trace.WriteLineIf(scardTrace, String.Format("        Active Protocol: SCARD_PROTOCOL.{0} ", (SCARD_PROTOCOL)activeSCardProtocol));
                Trace.WriteLineIf(this.TraceSCard, HexFormatting.Dump("        ATR: 0x", this.Atr, this.Atr.Length, 24));
            }
            else
            {
                connectedReaderName = null;
                throw new WinSCardException(scardTrace, "SCard.Connect", ret);
                //Trace.WriteLineIf(pcscTrace, String.Format("    Error: SCardConnect failed with 0x{0:X8}.", ret));
            }
        }
        private static byte[] InternalConvert(string str, HexFormatting formatting, int offset, int count)
        {
            if (str == null)
            {
                throw new ArgumentNullException(nameof(str));
            }

            offset = offset < 0 ? 0 : offset;
            count  = count < 0 ? str.Length : count;

            var prefix = GetFilteredPrefixes(formatting).FirstOrDefault(x => str.StartsWith(x));

            if (prefix != null)
            {
                offset += prefix.Length;
                count  -= prefix.Length;
            }
            else if (!formatting.HasFlag(HexFormatting.None))
            {
                throw new ArgumentOutOfRangeException(nameof(str), "Invalid hex format.");
            }

            if (count % 2 != 0)
            {
                throw new ArgumentOutOfRangeException(nameof(str), "Invalid hex length.");
            }

            if (count == 0)
            {
                return(Array.Empty <byte>());
            }

            var buffer = new byte[count / 2];

            for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx)
            {
                buffer[bx]  = (byte)(GetNibble(str[sx + offset]) << 4);
                buffer[bx] |= (byte)GetNibble(str[++sx + offset]);
            }

            return(buffer);
        }
Exemple #13
0
        public static async Task Read()
        {
            PCSCReader reader = new PCSCReader();

            while (true)
            {
                try
                {
                    reader.Connect();
                    reader.ActivateCard();

                    RespApdu respApdu = reader.Exchange("FF CA 00 00 00"); // Get Card UID ...

                    if (respApdu.SW1SW2 == 0x9000)
                    {
                        InvokeScanned("0x" + HexFormatting.ToHexString(respApdu.Data, false));
                        await Task.Delay(1000);
                    }
                }

                catch (WinSCardException ex)
                {
                    InvokeError(ex.WinSCardFunctionName + " Error 0x" + ex.Status.ToString("X08") + ": " + ex.Message);
                    await Task.Delay(1000);
                }

                catch (Exception ex)
                {
                    InvokeError(ex.Message);
                    await Task.Delay(1000);
                }

                finally
                {
                    reader.Disconnect();
                }
            }
        }
        /// <summary>
        /// The SCardControl function gives you direct control of the reader.
        /// You can call it any time after a successful call to SCardConnect and before
        /// a successful call to SCardDisconnect. The effect on the state of the reader
        /// depends on the control code.
        /// </summary>
        /// <param name="dwControlCode">
        /// Control code for the operation. This value identifies the specific operation to be performed.
        /// </param>
        /// <param name="inBuffer">
        /// A buffer that contains the data required to perform the operation.
        /// This parameter can be null if the dwControlCode parameter specifies an operation that does
        /// not require input data.
        /// </param>
        /// <param name="inBufferLength">
        /// Length of the input buffer.
        /// </param>
        /// <param name="outBuffer">
        /// The output buffer.
        /// </param>
        /// <param name="outBufferSize">
        /// Size, in bytes, of the output buffer.
        /// </param>
        /// <param name="bytesReturned">
        /// Supplies the length, in bytes, of the outBuffer parameter.
        /// </param>
        public void Control(uint dwControlCode, byte[] inBuffer, int inBufferLength, byte[] outBuffer, int outBufferSize, ref int bytesReturned)
        {
            Trace.WriteLineIf(this.scardTrace, string.Format("    SCard.Control (Cntrl Code: 0x{0:X}", dwControlCode));
            //Trace.WriteLineIf( this.scardTrace, HexFormatting.Dump(string.Format( "--> SCard.Control (Cntrl Code: 0x{0:X} ): 0x",
            //                                                    dwControlCode ), inBuffer, inBufferLength, 16, ValueFormat.HexASCII ) );

            int ret = WinSCardAPIWrapper.SCardControl(phCARD,
                                                      dwControlCode,
                                                      inBuffer,
                                                      inBufferLength,
                                                      outBuffer,
                                                      outBufferSize,
                                                      ref bytesReturned);

            if (ret == 0)
            {
                Trace.WriteLineIf(this.scardTrace, HexFormatting.Dump("        Value: 0x", outBuffer, bytesReturned, 16, ValueFormat.HexASCII));
            }
            else
            {
                throw new WinSCardException(scardTrace, "SCard.Control", ret);
            }
        }
Exemple #15
0
        public byte[] GetRandom()
        {
            try
            {
                RespApdu respApdu = mReader.Exchange("A4 0A 00 00 08"); // Get Random Number

                //Console.WriteLine("Random  = 0x" + HexFormatting.ToHexString(respApdu.Data, true));
                //if (respApdu != null && respApdu.Data != null)
                if (respApdu.SW1SW2 == 0x9000)
                {
                    baRandom  = respApdu.Data;
                    strRandom = HexFormatting.ToHexString(baRandom, true);
                }
                else
                {
                    //baRandom = new byte[8];
                    //Array.Clear(baRandom, 0, 8);
                    //return null;
                    ushort sw = respApdu.SW1SW2 ?? 0;
                    throw new Exception("GetRandom has not supported. Card's SW = " + sw.ToString("X4"));
                }
                //strRandom = HexFormatting.ToHexString(baRandom, true);

                return(baRandom);
            }
            catch (WinSCardException ex)
            {
                //Console.WriteLine(ex.WinSCardFunctionName + " Error 0x" +
                //                   ex.Status.ToString("X08") + ": " + ex.Message);
                throw ex;
            }
            catch (Exception ex)
            {
                //Console.WriteLine(ex.Message);
                throw ex;
            }
        }
        /*<summary>
         * BYTE[] find_ndef()
         * This function returns Byte array containgin all bytes from
         * starting byte of NDEF "D1" record to the termination byte "FE"
         *</summary>
         *
         * <remarks>
         * This function is naive and only tries to find the content
         * delimited by start and terminating bytes of NDEF:s
         * </remarks>
         *
         *
         */
        static Byte[] find_ndef()
        {
            RespApdu read_four_bytes;
            int      byte_num = 0;
            String   command;
            String   Hex_address;
            int      value;

            var allbytes = new List <string>();

            //Used for easy appending of all found bytes
            var hexbytes = new List <byte>();


            while (true)
            {
                value       = Convert.ToInt32(byte_num);
                Hex_address = String.Format("{0:X}", value);

                //RespApdu only accepts commands that are of type
                //"XX XX XX XX XX" so zero has to be prepended
                //for values smaller than 0x10
                if (byte_num < 16)
                {
                    Hex_address = "0" + Hex_address;
                }

                //We start from block 0 byte 0
                //Reading command: "FF B0 00 XX YY"
                //XX is reading address
                //YY is amount of bytes to read
                //Distance between each XX is 04
                command = "FF B0 00 " + Hex_address + " 04";

                read_four_bytes = reader.Exchange(command);
                if (read_four_bytes.SW1SW2 != 0x9000)
                {
                    Console.WriteLine("Reading bytes from the NFC tag failed. reader returned: ", HexFormatting.ToHexString(read_four_bytes.Data, true));
                    break;
                }

                allbytes.Add(HexFormatting.ToHexString(read_four_bytes.Data, true));
                hexbytes.AddRange(read_four_bytes.Data);


                if (HexFormatting.ToHexString(read_four_bytes.Data, true).Contains("FE"))
                {
                    Console.WriteLine("End of NDEF found");
                    break;
                }
                byte_num = byte_num + 1;
            }

            foreach (Object obj in hexbytes)
            {
                Console.Write("   {0}", String.Format("{0:X}", obj));
            }
            Console.WriteLine();

            for (int i = 0; i < hexbytes.Count; i++)
            {
                //This IS D1 in hex. It starts NDEF tags
                if (hexbytes[i] == 209)
                {
                    hexbytes.RemoveRange(0, i);
                }
                else if (hexbytes[i] == 254)
                {
                    break;
                }
            }

            return(hexbytes.ToArray());
        }
 /// <summary>
 /// Convert byte sequence to HEX representation.
 /// </summary>
 /// <param name="bytes"></param>
 /// <param name="formatting">HEX string formatting.</param>
 /// <param name="upperCase">Should hex litteral be in upper case.</param>
 /// <returns>Formatted HEX representation of bytes.</returns>
 public static string ToHexString(this byte[] bytes, HexFormatting formatting = HexFormatting.Default, bool upperCase = true)
 {
     return(ToHexString((ArraySegment <byte>)bytes, formatting, upperCase));
 }
        private static IEnumerable <string> GetFilteredPrefixes(HexFormatting formatting)
        {
            var bitMap = (uint)formatting;

            return(PossiblePrefixes.Where((x, i) => (bitMap & (1 << (i + 1))) != 0));
        }
 /// <summary>
 /// Convert HEX representation to byte array.
 /// </summary>
 /// <param name="str">Input string.</param>
 /// <param name="offset">Starting position in string.</param>
 /// <param name="count">Count of characters in string.</param>
 /// <param name="formatting"></param>
 /// <returns></returns>
 public static byte[] FromHexString(this string str, int offset, int count, HexFormatting formatting = HexFormatting.Default)
 {
     return(InternalConvert(str, formatting, offset, count));
 }
 /// <summary>
 /// Convert HEX representation to byte array.
 /// </summary>
 /// <param name="str">Input string.</param>
 /// <param name="formatting"></param>
 /// <returns></returns>
 public static byte[] FromHexString(this string str, HexFormatting formatting = HexFormatting.Default)
 {
     return(InternalConvert(str, formatting, -1, -1));
 }
        static void Main(string[] args)
        {
            ConsoleTraceListener consoleTraceListener = new ConsoleTraceListener();

            Trace.Listeners.Add(consoleTraceListener);

            reader = new PCSCReader();
            //NdefLibrary.Ndef.NdefMessage message = new NdefLibrary.Ndef.NdefMessage();



            /*WinSCard testi = new WinSCard();
             * testi.Connect(null);*/



            string input_text = "";

            while (input_text != "joo")
            {
                try
                {
                    //reader.SCard.Connect("",SCARD_SHARE_MODE.Direct, SCARD_PROTOCOL.Tx);
                    reader.Connect();

                    //set_buzzer_on();
                    //set_target_mode();

                    reader.ActivateCard();

                    //WinSCard reader = new WinSCard();
                    //testi.Connect(null);

                    //For some reason Direct commands only work after card has been activated (the command above)
                    //Also the reader resets to normal state after it's been unplugged.
                    //TODO: check if mode changes can be made permanent
                    if (!modes_changed)
                    {
                        //Console.WriteLine("YOLOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");
                        //change_modes_for_reader();
                        modes_changed = true;
                    }

                    RespApdu respApdu = reader.Exchange(APDU_commands["get_card_uid"]); // Get Card UID ...

                    if (respApdu.SW1SW2 == 0x9000)
                    {
                        Console.WriteLine("UID  = 0x" + HexFormatting.ToHexString(respApdu.Data, true));
                    }

                    use_stuff_properly();
                    //RespApdu tespApdu = reader.Exchange(String.Format(APDU_commands["direct_command_prefix"],"18", "D4 86 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00")); // Get Card UID ...
                    //RespApdu bespApdu = reader.Exchange(String.Format(APDU_commands["direct_command_prefix"], "18", "D4 40 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00")); // Get Card UID ...

                    //message = NdefLibrary.Ndef.NdefMessage.FromByteArray();
                    //message = NdefLibrary.Ndef.NdefMessage.FromByteArray(find_ndef());
                    //parse_record(message);

                    //write_to_tag("meloonis");
                }
                catch (WinSCardException ex)
                {
                    Console.WriteLine(ex.WinSCardFunctionName + " Error 0x" +
                                      ex.Status.ToString("X08") + ": " + ex.Message);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    reader.Disconnect();
                    Console.WriteLine("Please press any key...");
                    input_text = Console.ReadLine();
                }
            }
        }
        //Currently this writes plaintext to tag in NDEF format
        //TODO: Other tag types
        //      Limit to how much data can be fit to tag
        static void write_to_tag(String bytes_in)
        {
            string command_prefix = "FF D6 00 ";
            string command;
            String Hex_address;

            NdefMessage write_this = new NdefMessage {
                new NdefUriRecord {
                    Uri = bytes_in
                }
            };

            byte[]      ndef_prefix = { 0x03, (byte)write_this.ToByteArray().Length };
            List <byte> concat      = new List <byte>();

            concat.AddRange(ndef_prefix);
            concat.AddRange(write_this.ToByteArray());
            byte[] ndef_bytes = concat.ToArray();

            foreach (var item in ndef_bytes)
            {
                Console.WriteLine(HexFormatting.ToHexString(item));
            }

            //Byte[] Input_bytes = hex_string_to_byte_array(string_to_hex_string(bytes_in));
            byte[]   send_chunk = new byte[4];
            RespApdu write_four_bytes;
            int      count = 0;
            int      mod4  = ndef_bytes.Length % 4;


            for (int i = 0; i < ndef_bytes.Length; ++i)
            {
                send_chunk[count] = ndef_bytes[i];
                ++count;
                if (count == 4)
                {
                    count       = 0;
                    Hex_address = String.Format("{0:X}", Convert.ToInt32((i / 4) + 4));
                    if ((i / 4) + 4 < 16)
                    {
                        Hex_address = "0" + Hex_address;
                    }
                    Console.WriteLine(Hex_address);

                    command = command_prefix + Hex_address + " 04 " + HexFormatting.ToHexString(send_chunk, true);
                    Console.WriteLine(command);
                    write_four_bytes = reader.Exchange(command);
                }
            }

            if (count != 0)
            {
                for (int i = count; i < send_chunk.Length; i++)
                {
                    send_chunk[i] = 0x00;
                }
                send_chunk[2] = 254;
                Hex_address   = String.Format("{0:X}", Convert.ToInt32(((ndef_bytes.Length - count) / 4) + 4));
                if ((((ndef_bytes.Length - count) / 4) + 4) < 16)
                {
                    Hex_address = "0" + Hex_address;
                }
                command          = command_prefix + Hex_address + " 04 " + HexFormatting.ToHexString(send_chunk, true);
                write_four_bytes = reader.Exchange(command);
            }



            //command = command + "04" + " 04 " + hexString;
            //write_four_bytes = reader.Exchange(command);

            /*if (Input_bytes.Length % 4 != 0)
             * {
             *  int mod_of_input = Input_bytes.Length % 4;
             *  for (int i = 0; i < mod_of_input; i++)
             *  {
             *
             *
             *  }
             * }*/

/*
 *          for (int i = 0; i < Input_bytes.Length; i = i + 4)
 *          {
 *              for (int j = 0; j < 4; j++)
 *              {
 *                  if (j + i < Input_bytes.Length)
 *                  {
 *                      send_chunk[j] = Input_bytes[j + i];
 *                  }
 *              }
 *
 *              value = Convert.ToInt32(byte_num);
 *              Hex_address = String.Format("{0:X}", value);
 *              command = command + Hex_address + " 04 " + HexFormatting.ToHexString(send_chunk, true);
 *              write_four_bytes = reader.Exchange(command);
 *              byte_num = byte_num + 1;
 *          }*/
        }