Search code examples
.netvb.netmagnetic-cards

How to Use MSR206 MagStripe R/W in


There were quite a few questions out there regarding how to interface with these devices and very few useful answers. I have written an application that uses this device for both read and write purposes. I will briefly highlight the methods needed to interact with this serial device.


Solution


  • Treat this a normal serial device and send it all commands individually. I have written an application that reads/writes badges using this device. Create a serial port and and a DataReceived event handler and a ReceivedText method to process the data being read.

    Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs)
        System.Threading.Thread.Sleep(700)'delay to try to wait till all datareceived
        ReceivedText(SerialPort1.ReadExisting)
    End Sub
    

    You will then need to send the device the read command so that it goes into read mode (when in read mode it will trigger the DataReceived event when you swipe a card).

    Public Sub SendReadCommad()
    
        Dim bytes() As Byte = {&H1B, &H72} 'Hex command to put device in read mode
    
        SerialPort1.Write(bytes, 0, 2) 'Sends command to device.
    End Sub
    

    At that point, when you swipe a card the datareceived event will fire and pass the string data to your method to handle the data. In my case, I'm appending the received text into a hidden textbox (It's appended like this because it's very possible that the received text event fires multiple times on one swipe with pieces of the data being received on each trigger. Of course you would want to combine this data into the final result.

    Public Sub ReceivedText(ByVal [text] As String)
        If Not tbxHiddenInput.Dispatcher.CheckAccess() Then
            tbxHiddenInput.Dispatcher.BeginInvoke(New SetTextCallBack(AddressOf ReceivedText), ([text]))
    
        Else
            Dim charArray As Char() = [text].ToCharArray
            Dim commandArray As String() = Nothing
            Dim i As Int16 = 0
            Dim hexVal As String = ""
            For Each c As Char In charArray
                hexVal = Convert.ToString(Convert.ToInt32(c), 16)
                tbxHiddenInput.AppendText(hexVal)
            Next
            'this section below is used to evaluate the Chars read to determine what type of data 
            'the device sent.  This is need because the device sends status information with 
            'the result of things like a badge Write attempt.
            If charArray(0) = Chr(27) Then 
                Select Case charArray(1)
                    Case Chr(115)
                        ReadTrackData(charArray) 'Method where I actually parse the track data out in the way I wan't for my app.  This will be custom for you.
                    Case Chr(48)
                        MessageBox.Show("Badge write status: Success!")
                    Case Else
                        If isWriteCommand = True Then
                            MessageBox.Show("Badge write status: Failure!")
                            SendResetCommad()
                            myMagWindow.WriteToMagStripe(myMagWindow.tbxTrack1.Text, myMagWindow.tbxTrack2.Text, myMagWindow.tbxTrack3.Text)
                            myMagWindow.PictureBox3.Visibility = Windows.Visibility.Visible
                        Else
                            MessageBox.Show("Badge read status: Failure!")
                            SendResetCommad() 'Indentical to SendReadCommand, except the Hex data sent.  This puts device in normal mode.
                            SendReadCommad()
                        End If
    
                End Select
            End If
        End If
    End Sub
    

    Lastly, writing to a magstripe is along the same lines...

    Public Sub WriteToMagStripe(ByVal track1 As String, track2 As String, track3 As String)
        isWriteCommand = True
        Dim commandHeader() As Byte = {&H1B, &H77, &H1B, &H73, &H1B, &H1} 'Series of hex chars that tell the reader to enter write mode.
    
        Dim bytes(4096) As Byte
        Dim b As Int16 = 0
    'Build the byte array beginning with the write header
        For Each c As Byte In commandHeader
            bytes(b) = c
            b += 1
        Next
    'Append track data to the byte array
        For Each c As Char In track1
            bytes(b) = Convert.ToInt16(c)
            b += 1
        Next
    'at end of track1 data append track seperator char sequence
        bytes(b) = &H1B
        b += 1
        bytes(b) = &H2
        b += 1
        For Each c As Char In track2
            bytes(b) = Convert.ToInt16(c)
            b += 1
        Next
    'at end of track2 data append track seperator char sequence
        bytes(b) = &H1B
        b += 1
        bytes(b) = &H3
        b += 1
        For Each c As Char In track3
            bytes(b) = Convert.ToInt16(c)
            b += 1
        Next
    'at end of track1 data append data end char sequence
        bytes(b) = &H3F
        b += 1
        bytes(b) = &H1C
        ReDim Preserve bytes(b)
    
    
        SerialPort1.Write(bytes, 0, bytes.Length)
    End Sub
    

    Keep in mind that once the card has been swiped (succesfull or not) the device with trigger the datareceived event with a result. It will either send a char sequence reflecting success or it will send that of a failure. The Programmer's manual that's out there on the internet for this device is extremely useful.

    Please realize that what I have posted isn't something you will be able to copy/paste into your code and suddenly have a working device. Although you may be able to do that with portions of it (for instance the write function), you will need to customize the procedures for your circumstances. I simply wanted to show you the transactional sequence for using the device.