Search code examples
vb.netrfid

How to write selectively to an RFID tag?


How can I efficiently write to an RFID tag without using a For loop. Right now I am looping and filling up all the blocks in the series. I want to make a program were I could fill in specific blocks with specific values. I want to know if there are other ways writing on RFID. The code below shows writing on RFID using the for loop which skips the integers.

Here's my code:

Private Sub RFIDAuth()
    Dim SkipBlock As String
    SkipBlock = ",3,7,11,15,19,23,27,31,35,39,43,47,51,55,59,"
    For i = 1 To 62
        If SkipBlock.Contains("," & CStr(i) & ",") = False Then
            Call ClearBuffers()
            SendBuff(0) = &HFF                      'CLA
            SendBuff(2) = &H0                       'P1: same for all source types
            SendBuff(1) = &H86                      'INS: for stored key input
            SendBuff(3) = &H0                       'P2: for stored key input
            SendBuff(4) = &H5                       'P3: for stored key input
            SendBuff(5) = &H1                       'Byte 1: version number
            SendBuff(6) = &H0                       'Byte 2
            SendBuff(7) = CInt(i)         'Byte 3: sectore no. for stored key input

            SendBuff(8) = &H60                  'Byte 4 : Key A for stored key input
            'SendBuff(8) = &H61                  'Byte 4 : Key B for stored key input
            SendBuff(9) = &H20                  'Byte 5 : Session key for volatile memory
            'SendBuff(9) = CDec(<INPUT>)    'Byte 5 : Session key for non-volatile memory
            SendLen = &HA
            RecvLen = &H2

            retCode = SendAPDUandDisplay(0)
            Base64StrfrmRFID = Base64StrfrmRFID & RFIDRead(i)

        End If
    Next
End Sub

Solution

  • SkipBlock: HashSet instead of string

    The SkipBlock string and Contains(…) appear strange to me, use a HashSet<int> unless there is a good reason to use the string:

    HashSet<int> SkipBlock = new HashSet<int>(){ 3, 7, 11, … };
    

    and later:

    if (SkipBlock.Contains(i)) {
    

    Structure for the RFID layout

    Use a struct to specify the layout of the RFID:

    [StructLayout (LayoutKind.Explicit, Pack=1, Size=…)]
    struct RFID_Block {
         [FieldOffset(0)] public const byte CLA = 0xFF;
         [FieldOffset(1)] public const byte INS = 0x86;
         [FieldOffset(2)] public const byte P1 = 0x0;
         …
         [FieldOffset(7)] public int SectorNumber; // Should this be an int or a byte?
    };
    
    RFID_Block block1 = new RFID_Block();
    block1.SectorNumber = i;
    …
    
    • Use const for fields that are the same for each block and non-const fields for fields that may vary.
    • If a field has different meanings in different kinds of RFID blocks, you can define fields with the same FieldOffset, i.e.:

      struct DualUseRFID_Block {
           …
           // Stored key input block
           [FieldOffset(2)] public byte P2;
           [FieldOffset(3)] public byte P3;
      
           // Some other kind of RFID Block:
           [FieldOffset(2)] public word FooBar;
      

      Note:

      • first, FooBar has the same field offset as P2;
      • second, FooBar is of a different type than P2; and
      • third, FooBar occupies the same memory space as P2 and P3 either FooBar or P2 and P3 contain valid data.
    • Check the sizes of the fields do not confuse byte and int (4 bytes); i.e. withing an int and then something with an offset of one byte more is asking for problems (e.g. SendBuff(7) = CInt(i): Sendbuf(8) = &H60).
    • Check whether C# and the RFID chip agree about "endianess".

    References