Exemple #1
0
        public void WriteTag(NdefLibrary.Ndef.NdefMessage message)
        {
            int messageSize = 0;

            foreach (NdefRecord record in message)
            {
                messageSize += record.Payload.Length;
                if (!record.CheckIfValid())
                {
                    throw new Exception("A record on NDEFMessage is not valid");
                }
            }

            if (!isTagPresent)
            {
                throw new Exception("No Tag present or Tag is incompatible ");
            }

            if (!nfcTag.IsWriteable)
            {
                throw new Exception("Tag is write locked ");
            }

            if (nfcTag.MaxSize < messageSize)
            {
                throw new Exception("Tag is too small for this message");
            }

            RaiseTagConnected(nfcTag);

            nfcDevice.PublishBinaryMessage("NDEF:WriteTag", message.ToByteArray().AsBuffer(), writerHandler);
        }
Exemple #2
0
        /// <summary>
        /// Deletes any details currently stored in the Smart Poster
        /// and re-initializes them by parsing the contents of the payload.
        /// </summary>
        private void ParsePayloadToData(byte[] payload)
        {
            InitializeData();
            if (payload == null || payload.Length == 0)
            {
                return;
            }

            var message = NdefMessage.FromByteArray(payload);

            foreach (NdefRecord record in message)
            {
                var specializedType = record.CheckSpecializedType(false);
                if (specializedType == null)
                {
                    continue;
                }

                if (specializedType == typeof(NdefUriRecord))
                {
                    // URI
                    RecordUri = new NdefUriRecord(record);
                }
                else if (specializedType == typeof(NdefTextRecord))
                {
                    // Title
                    var textRecord = new NdefTextRecord(record);
                    if (Titles == null)
                    {
                        Titles = new List <NdefTextRecord>();
                    }
                    Titles.Add(textRecord);
                }
                else if (specializedType == typeof(NdefSpActRecord))
                {
                    // Action
                    _recordAction = new NdefSpActRecord(record);
                }
                else if (specializedType == typeof(NdefSpSizeRecord))
                {
                    // Size
                    _recordSize = new NdefSpSizeRecord(record);
                }
                else if (specializedType == typeof(NdefSpMimeTypeRecord))
                {
                    // Mime Type
                    _recordMimeType = new NdefSpMimeTypeRecord(record);
                }
                else if (specializedType == typeof(NdefMimeImageRecordBase))
                {
                    // Image
                    _recordImage = new NdefMimeImageRecordBase(record);
                }
                else
                {
                    Debug.WriteLine("Sp: Don't know how to handle this record: " +
                                    BitConverter.ToString(record.Type));
                }
            }
        }
        /// <summary>
        /// Create the payload based on the data stored in the properties. Usually called
        /// automatically when changing properties, but you might need to call this manually
        /// if you modify the list of alternative carrier records directly without using
        /// accessor method provided by this class.
        /// </summary>
        /// <exception cref="NdefException">Thrown if unable to assemble the payload.
        /// The exception message contains further details about the issue.</exception>
        public void AssemblePayload()
        {
            if (_handoverVersion == null)
            {
                throw new NdefException(NdefExceptionMessages.ExHandoverInvalidVersion);
            }

            // Convert child records to message
            var childMsg = new NdefMessage();

            if (_handoverAlternativeCarrierRecords != null)
            {
                childMsg.AddRange(_handoverAlternativeCarrierRecords);
            }
            if (_handoverErrorRecord != null)
            {
                childMsg.Add(_handoverErrorRecord);
            }

            var childBytes = childMsg.ToByteArray();

            var newPayload = new byte[childBytes.Length + 1];

            // Frist byte: handover version
            newPayload[0] = _handoverVersion.Version;

            // Rest of the payload: child message containing Alternative Carrier records + Error record
            Array.Copy(childBytes, 0, newPayload, 1, childBytes.Length);

            _payload = newPayload;
        }
Exemple #4
0
        /// <summary>
        /// Go through the records stored in this message, parse them and assign
        /// them to the individual properties. This also checks if the child records
        /// are actually valid for a Handover Select message.
        /// </summary>
        public void SetAndAssignChildRecords(byte[] payloadToParse)
        {
            // Create NDEF message based on payload
            var childRecordsMsg = NdefMessage.FromByteArray(payloadToParse);

            // Clear previous child records
            _handoverAlternativeCarrierRecords = null;
            _handoverErrorRecord = null;

            // Assign new child records from the source message
            if (childRecordsMsg.Count < 1)
            {
                throw new NdefException(NdefExceptionMessages.ExHandoverSelectMsgInvalidRecords);
            }

            foreach (var curChildRecord in childRecordsMsg)
            {
                // Alternate carrier record
                if (curChildRecord.CheckSpecializedType(false) == typeof(NdefHandoverAlternativeCarrierRecord))
                {
                    if (HandoverErrorRecord != null)
                    {
                        // Error record needs to be last - there can't be an AC record
                        // after we have already found an error record.
                        throw new NdefException(NdefExceptionMessages.ExHandoverSelectMsgInvalidRecords);
                    }
                    if (_handoverAlternativeCarrierRecords == null)
                    {
                        _handoverAlternativeCarrierRecords = new List <NdefHandoverAlternativeCarrierRecord>();
                    }
                    _handoverAlternativeCarrierRecords.Add(new NdefHandoverAlternativeCarrierRecord(curChildRecord));
                }
                else if (curChildRecord.CheckSpecializedType(false) == typeof(NdefHandoverErrorRecord))
                {
                    if (_handoverErrorRecord != null)
                    {
                        // Only one error record is allowed
                        throw new NdefException(NdefExceptionMessages.ExHandoverSelectMsgInvalidRecords);
                    }
                    _handoverErrorRecord = new NdefHandoverErrorRecord(curChildRecord);
                }
                else
                {
                    // Unknown record found that should not be in this message
                    throw new NdefException(NdefExceptionMessages.ExHandoverSelectMsgInvalidRecords);
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Reverse function to parseRecords() - this one takes
        /// the information stored in the individual record instances and assembles
        /// it into the payload of the base class.
        /// </summary>
        /// <remarks>
        /// As the URI is mandatory, the payload will not be assembled
        /// if no URI is defined.
        /// </remarks>
        /// <returns>Whether assembling the payload was successful.</returns>
        private bool AssemblePayload()
        {
            // Uri is mandatory - don't assemble the payload if it's not set
            if (RecordUri == null)
            {
                return(false);
            }

            // URI (mandatory)
            var message = new NdefMessage {
                RecordUri
            };

            // Title(s) (optional)
            if (Titles != null && Titles.Count > 0)
            {
                message.AddRange(Titles);
            }

            // Action (optional)
            if (ActionInUse())
            {
                message.Add(_recordAction);
            }

            // Size (optional)
            if (SizeInUse())
            {
                message.Add(_recordSize);
            }

            // Mime Type (optional)
            if (MimeTypeInUse())
            {
                message.Add(_recordMimeType);
            }

            // Image (optional)
            if (ImageInUse())
            {
                message.Add(_recordImage);
            }

            SetPayloadAndParse(message.ToByteArray(), false);

            return(true);
        }
Exemple #6
0
        public ObservableCollection <string> ReadNdefMessage(NdefMessage message)
        {
            ObservableCollection <string> collection = new ObservableCollection <string>();

            if (message == null)
            {
                return(collection);
            }

            foreach (NdefRecord record in message)
            {
                if (record.CheckSpecializedType(false) == typeof(NdefTextRecord))
                {
                    var textRecord = new NdefTextRecord(record);
                    collection.Add(textRecord.Text);
                }
            }
            return(collection);
        }
Exemple #7
0
 public Task <WriteResult> WriteTag(NdefLibrary.Ndef.NdefMessage message, TimeSpan timeout)
 {
     return(WriteTag(message, CancellationToken.None, timeout));
 }
Exemple #8
0
 public Task <WriteResult> WriteTag(NdefLibrary.Ndef.NdefMessage message, System.Threading.CancellationToken cancellationToken)
 {
     return(WriteTag(message, cancellationToken, TimeSpan.FromTicks(0)));
 }
Exemple #9
0
        /// <summary>
        /// Returns the NDEF message parsed from the contents of <paramref name="message"/>.
        /// </summary>
        /// <remarks>
        /// The <paramref name="message"/> parameter is interpreted as the raw message format
        /// defined in the NFC Forum specifications.
        /// </remarks>
        /// <param name="message">Raw byte array containing the NDEF message, which consists
        /// of 0 or more NDEF records.</param>
        /// <exception cref="NdefException">Thrown if there is an error parsing the NDEF
        /// message out of the byte array.</exception>
        /// <returns>If parsing was successful, the NDEF message containing 0 or more NDEF
        /// records.</returns>
        public static NdefMessage FromByteArray(byte[] message)
        {
            var result = new NdefMessage();

            var seenMessageBegin = false;
            var seenMessageEnd   = false;

            var partialChunk = new MemoryStream();
            var record       = new NdefRecord();

            uint i = 0;

            while (i < message.Length)
            {
                //Debug.WriteLine("Parsing byte[] to NDEF message. New record starts at {0}", i);

                // Parse flags out of NDEF message header

                // The MB flag is a 1-bit field that when set indicates the start of an NDEF message.
                bool messageBegin = (message[i] & 0x80) != 0;
                // The ME flag is a 1-bit field that when set indicates the end of an NDEF message.
                // Note, that in case of a chunked payload, the ME flag is set only in the terminating record chunk of that chunked payload.
                bool messageEnd = (message[i] & 0x40) != 0;
                // The CF flag is a 1-bit field indicating that this is either the first record chunk or a middle record chunk of a chunked payload.
                bool cf = (message[i] & 0x20) != 0;
                // The SR flag is a 1-bit field indicating, if set, that the PAYLOAD_LENGTH field is a single octet.
                bool sr = (message[i] & 0x10) != 0;
                // The IL flag is a 1-bit field indicating, if set, that the ID_LENGTH field is present in the header as a single octet.
                // If the IL flag is zero, the ID_LENGTH field is omitted from the record header and the ID field is also omitted from the record.
                bool il             = (message[i] & 0x08) != 0;
                var  typeNameFormat = (NdefRecord.TypeNameFormatType)(message[i] & 0x07);

                //Debug.WriteLine("ShortRecord: " + (sr ? "yes" : "no"));
                //Debug.WriteLine("Id Length present: " + (il ? "yes" : "no"));

                if (messageBegin && seenMessageBegin)
                {
                    throw new NdefException(NdefExceptionMessages.ExMessageBeginLate);
                }
                else if (!messageBegin && !seenMessageBegin)
                {
                    throw new NdefException(NdefExceptionMessages.ExMessageBeginMissing);
                }
                else if (messageBegin && !seenMessageBegin)
                {
                    seenMessageBegin = true;
                }

                if (messageEnd && seenMessageEnd)
                {
                    throw new NdefException(NdefExceptionMessages.ExMessageEndLate);
                }
                else if (messageEnd && !seenMessageEnd)
                {
                    seenMessageEnd = true;
                }

                if (cf && (typeNameFormat != NdefRecord.TypeNameFormatType.Unchanged) && partialChunk.Length > 0)
                {
                    throw new NdefException(NdefExceptionMessages.ExMessagePartialChunk);
                }

                // Header length
                int headerLength = 1;
                headerLength += (sr) ? 1 : 4;
                headerLength += (il) ? 1 : 0;

                if (i + headerLength >= message.Length)
                {
                    throw new NdefException(NdefExceptionMessages.ExMessageUnexpectedEnd);
                }

                // Type length
                byte typeLength = message[++i];

                if ((typeNameFormat == NdefRecord.TypeNameFormatType.Unchanged) && (typeLength != 0))
                {
                    throw new NdefException(NdefExceptionMessages.ExMessageInvalidChunkedType);
                }

                // Payload length (short record?)
                uint payloadLength;
                if (sr)
                {
                    // Short record - payload length is a single octet
                    payloadLength = message[++i];
                }
                else
                {
                    // No short record - payload length is four octets representing a 32 bit unsigned integer (MSB-first)
                    payloadLength  = (uint)((message[++i]) << 24);
                    payloadLength |= (uint)((message[++i]) << 16);
                    payloadLength |= (uint)((message[++i]) << 8);
                    payloadLength |= (uint)((message[++i]) << 0);
                }

                // ID length
                byte idLength;
                idLength = (byte)(il ? message[++i] : 0);

                // Total length of content (= type + payload + ID)
                uint contentLength = typeLength + payloadLength + idLength;
                if (i + contentLength >= message.Length)
                {
                    throw new NdefException(NdefExceptionMessages.ExMessageUnexpectedEnd);
                }


                if ((typeNameFormat == NdefRecord.TypeNameFormatType.Unchanged) && (idLength != 0))
                {
                    throw new NdefException(NdefExceptionMessages.ExMessageInvalidChunkedId);
                }

                if (typeNameFormat != NdefRecord.TypeNameFormatType.Unchanged)
                {
                    record.TypeNameFormat = typeNameFormat;
                }

                // Read type
                if (typeLength > 0)
                {
                    record.Type = new byte[typeLength];
                    Array.Copy(message, (int)(++i), record.Type, 0, typeLength);
                    i += (uint)typeLength - 1;
                }

                // Read ID
                if (idLength > 0)
                {
                    record.Id = new byte[idLength];
                    Array.Copy(message, (int)(++i), record.Id, 0, idLength);
                    i += (uint)idLength - 1;
                }

                // Read payload
                if (payloadLength > 0)
                {
                    var payload = new byte[payloadLength];
                    Array.Copy(message, (int)(++i), payload, 0, (int)payloadLength);

                    if (cf)
                    {
                        // chunked payload, except last
                        partialChunk.Write(payload, 0, payload.Length);
                    }
                    else if (typeNameFormat == NdefRecord.TypeNameFormatType.Unchanged)
                    {
                        // last chunk of chunked payload
                        partialChunk.Write(payload, 0, payload.Length);
                        record.Payload = partialChunk.ToArray();
                    }
                    else
                    {
                        // non-chunked payload
                        record.Payload = payload;
                    }

                    i += payloadLength - 1;
                }

                if (!cf)
                {
                    // Add record to the message and create a new record for the next loop iteration
                    result.Add(record);
                    record = new NdefRecord();
                }

                if (!cf && seenMessageEnd)
                {
                    break;
                }

                // move to start of next record
                ++i;
            }


            if (!seenMessageBegin && !seenMessageEnd)
            {
                throw new NdefException(NdefExceptionMessages.ExMessageNoBeginOrEnd);
            }

            return(result);
        }
Exemple #10
0
        /// <summary>
        /// Convert all the NDEF records currently stored in the NDEF message to a byte
        /// array suitable for writing to a tag or sending to another device.
        /// </summary>
        /// <returns>The NDEF record(s) converted to an NDEF message.</returns>
        public byte[] ToByteArray()
        {
            // Empty message: single empty record
            if (Count == 0)
            {
                var msg = new NdefMessage {
                    new NdefRecord()
                };
                return(msg.ToByteArray());
            }

            var m = new MemoryStream();

            for (int i = 0; i < Count; i++)
            {
                var record = this[i];

                var flags = (byte)record.TypeNameFormat;

                // Message begin / end flags. If there is only one record in the message,
                // both flags are set.
                if (i == 0)
                {
                    flags |= 0x80;      // MB (message begin = first record in the message)
                }
                if (i == Count - 1)
                {
                    flags |= 0x40;      // ME (message end = last record in the message)
                }
                // cf (chunked records) not supported yet

                // SR (Short Record)?
                if (record.Payload == null || record.Payload.Length < 255)
                {
                    flags |= 0x10;
                }

                // ID present?
                if (record.Id != null && record.Id.Length > 0)
                {
                    flags |= 0x08;
                }

                m.WriteByte(flags);

                // Type length
                if (record.Type != null)
                {
                    m.WriteByte((byte)record.Type.Length);
                }
                else
                {
                    m.WriteByte(0);
                }

                // Payload length 1 byte (SR) or 4 bytes
                if (record.Payload == null)
                {
                    m.WriteByte(0);
                }
                else
                {
                    if ((flags & 0x10) != 0)
                    {
                        // SR
                        m.WriteByte((byte)record.Payload.Length);
                    }
                    else
                    {
                        // No SR (Short Record)
                        var payloadLength = (uint)record.Payload.Length;
                        m.WriteByte((byte)(payloadLength >> 24));
                        m.WriteByte((byte)(payloadLength >> 16));
                        m.WriteByte((byte)(payloadLength >> 8));
                        m.WriteByte((byte)(payloadLength & 0x000000ff));
                    }
                }

                // ID length
                if (record.Id != null && (flags & 0x08) != 0)
                {
                    m.WriteByte((byte)record.Id.Length);
                }

                // Type length
                if (record.Type != null && record.Type.Length > 0)
                {
                    m.Write(record.Type, 0, record.Type.Length);
                }

                // ID data
                if (record.Id != null && record.Id.Length > 0)
                {
                    m.Write(record.Id, 0, record.Id.Length);
                }

                // Payload data
                if (record.Payload != null && record.Payload.Length > 0)
                {
                    m.Write(record.Payload, 0, record.Payload.Length);
                }
            }

            return(m.ToArray());
        }
        /// <summary>
        /// Returns the NDEF message parsed from the contents of <paramref name="message"/>.
        /// </summary>
        /// <remarks>
        /// The <paramref name="message"/> parameter is interpreted as the raw message format
        /// defined in the NFC Forum specifications.
        /// </remarks>
        /// <param name="message">Raw byte array containing the NDEF message, which consists
        /// of 0 or more NDEF records.</param>
        /// <exception cref="NdefException">Thrown if there is an error parsing the NDEF
        /// message out of the byte array.</exception>
        /// <returns>If parsing was successful, the NDEF message containing 0 or more NDEF
        /// records.</returns>
        public static NdefMessage FromByteArray(byte[] message)
        {
            var result = new NdefMessage();

            var seenMessageBegin = false;
            var seenMessageEnd   = false;

            var partialChunk = new MemoryStream();
            var record       = new NdefRecord();

            uint i = 0;

            while (i < message.Length)
            {
                //Debug.WriteLine("Parsing byte[] to NDEF message. New record starts at {0}", i);
                // Parse flags out of NDEF message header
                bool messageBegin   = (message[i] & 0x80) != 0;
                bool messageEnd     = (message[i] & 0x40) != 0;
                bool cf             = (message[i] & 0x20) != 0;
                bool sr             = (message[i] & 0x10) != 0;
                bool il             = (message[i] & 0x08) != 0;
                var  typeNameFormat = (NdefRecord.TypeNameFormatType)(message[i] & 0x07);

                Debug.WriteLine("ShortRecord: " + (sr ? "yes" : "no"));
                Debug.WriteLine("Id Length present: " + (il ? "yes" : "no"));

                if (messageBegin && seenMessageBegin)
                {
                    throw new NdefException("Message Begin Late");
                }
                else if (!messageBegin && !seenMessageBegin)
                {
                    throw new NdefException("Begin Missing");
                }
                else if (messageBegin && !seenMessageBegin)
                {
                    seenMessageBegin = true;
                }

                if (messageEnd && seenMessageEnd)
                {
                    throw new NdefException("End Late");
                }
                else if (messageEnd && !seenMessageEnd)
                {
                    seenMessageEnd = true;
                }

                if (cf && (typeNameFormat != NdefRecord.TypeNameFormatType.Unchanged) && partialChunk.Length > 0)
                {
                    throw new NdefException("Partial Chunk");
                }

                int headerLength = 1;
                headerLength += (sr) ? 1 : 4;
                headerLength += (il) ? 1 : 0;

                if (i + headerLength >= message.Length)
                {
                    throw new NdefException("NdefExceptionMessages.ExMessageUnexpectedEnd");
                }

                byte typeLength = message[++i];

                if ((typeNameFormat == NdefRecord.TypeNameFormatType.Unchanged) && (typeLength != 0))
                {
                    throw new NdefException("Invalid Chunk");
                }

                uint payloadLength;
                if (sr)
                {
                    // Short record - payload length is a single octet
                    payloadLength = message[++i];
                }
                else
                {
                    // No short record - payload length is four octets representing a 32 bit unsigned integer (MSB-first)
                    payloadLength  = (uint)((message[++i]) << 24);
                    payloadLength |= (uint)((message[++i]) << 16);
                    payloadLength |= (uint)((message[++i]) << 8);
                    payloadLength |= (uint)((message[++i]) << 0);
                }
                //Debug.WriteLine("Payload length: " + payloadLength);

                byte idLength;
                idLength = (byte)(il ? message[++i] : 0);

                uint contentLength = typeLength + payloadLength + idLength;
                if (i + contentLength >= message.Length)
                {
                    throw new NdefException("Unexpected End");
                }
                //Debug.WriteLine("Content length: {0} (Start at: {1})", contentLength, i);


                if ((typeNameFormat == NdefRecord.TypeNameFormatType.Unchanged) && (idLength != 0))
                {
                    throw new NdefException("Invalid Chunk Id");
                }

                if (typeNameFormat != NdefRecord.TypeNameFormatType.Unchanged)
                {
                    record.TypeNameFormat = typeNameFormat;
                }

                if (typeLength > 0)
                {
                    record.Type = new byte[typeLength];
                    Array.Copy(message, (int)(++i), record.Type, 0, typeLength);
                    i += (uint)typeLength - 1;
                }

                if (idLength > 0)
                {
                    record.Id = new byte[idLength];
                    Array.Copy(message, (int)(++i), record.Id, 0, idLength);
                    i += (uint)idLength - 1;
                }

                if (payloadLength > 0)
                {
                    var payload = new byte[payloadLength];
                    Array.Copy(message, (int)(++i), payload, 0, (int)payloadLength);

                    if (cf)
                    {
                        // chunked payload, except last
                        partialChunk.Write(payload, 0, payload.Length);
                    }
                    else if (typeNameFormat == NdefRecord.TypeNameFormatType.Unchanged)
                    {
                        // last chunk of chunked payload
                        partialChunk.Write(payload, 0, payload.Length);
                        record.Payload = partialChunk.ToArray();
                    }
                    else
                    {
                        // non-chunked payload
                        record.Payload = payload;
                    }

                    i += payloadLength - 1;
                }

                if (!cf)
                {
                    result.Add(record);
                    record = new NdefRecord();
                }

                if (!cf && seenMessageEnd)
                {
                    break;
                }

                // move to start of next record
                ++i;
            }


            if (!seenMessageBegin && !seenMessageEnd)
            {
                throw new NdefException("No Begin Or End");
            }

            return(result);
        }
        static void Main(string[] args)
        {
            try
            {
                System.IO.StreamReader file = new System.IO.StreamReader("settings.txt");
                reader_name = file.ReadLine();
                //Console.WriteLine("SETTINGSFILE CONTENT: " + reader_name);
            }
            catch (System.IO.FileNotFoundException)
            {
                System.Environment.Exit(1);
            }


            ConsoleTraceListener consoleTraceListener = new ConsoleTraceListener();

            Trace.Listeners.Add(consoleTraceListener);
            reader = new PCSCReader();
            NdefLibrary.Ndef.NdefMessage message = new NdefLibrary.Ndef.NdefMessage();

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


                if (args[0] == "read")
                {
                    //Console.WriteLine("Initing stuff");
                    //reader.SCard.Connect(reader.SCard.ListReaders()[1], SCARD_SHARE_MODE.Direct, SCARD_PROTOCOL.Default);
                    //Console.WriteLine(reader.SCard.GetSCardCtlCode(3500));
                    reader.Connect(reader_name);
                    Console.WriteLine(reader.SCard.ListReaders()[0]);
                    reader.ActivateCard(SCARD_SHARE_MODE.Shared, SCARD_PROTOCOL.T1);
                    turn_on_antenna();

                    message = NdefLibrary.Ndef.NdefMessage.FromByteArray(find_ndef());
                    Console.WriteLine("rd: " + parse_record(message));

                    //Console.WriteLine("Please press any key...");
                    //string input_text = Console.ReadLine();
                    //turn_off_antenna();
                }
                else if (args[0] == "write" && args.Length == 2)
                {
                    Console.WriteLine("writing to tag: ", args[1]);
                    reader.Connect();
                    reader.ActivateCard(SCARD_SHARE_MODE.Shared, SCARD_PROTOCOL.T1);
                    turn_on_antenna();
                    write_to_tag(args[1]);
                    Console.WriteLine("wrote to tag:" + args[1]);
                }
                else if (args[0] == "list")
                {
                    Console.WriteLine(reader.SCard.ListReaders());
                    System.Environment.Exit(1);
                }
                else
                {
                    Console.WriteLine("Bad arguments");
                    reader.SCard.Disconnect();
                    System.Environment.Exit(1);
                }

                //WinSCard yhteys = new WinSCard();
                //yhteys.Connect(yhteys.ListReaders()[0]);
                //yhteys.Control(0, hex_string_to_byte_array(APDU_commands[]), );


                //write_to_tag(input_text = "Hassulla Tassulla kiva paijaa massua ai että kun on hassua:3");
                //reader.ActivateCard();
                //try_this();
                //set_initiator_mode();


                //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

                //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));
                 * }*/

                //message = NdefLibrary.Ndef.NdefMessage.FromByteArray(find_ndef());
                //parse_record(message);
                //set_initiator_mode();
                //string input_text = Console.ReadLine();
                //System.Environment.Exit(1);
            }
            catch (WinSCardException ex)
            {
                Console.WriteLine(ex.WinSCardFunctionName + " Error 0x" +
                                  ex.Status.ToString("X08") + ": " + ex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                //direct_command(APDU_commands["enable_picc_polling"]);
                //turn_off_antenna();
                //Console.WriteLine("Please press any key...");
                //string input_text = Console.ReadLine();
                turn_off_antenna();
                reader.SCard.Disconnect();
                System.Environment.Exit(1);
            }
        }