Class: MIFARE::Ultralight

Inherits:
PICC
  • Object
show all
Defined in:
lib/mifare/ultralight.rb

Defined Under Namespace

Classes: CARD_VERSION

Constant Summary collapse

CMD_READ =

Reads 4 pages(16 bytes) from the PICC.

0x30
CMD_FAST_READ =

Reads pages within requested range

0x3A
CMD_WRITE =

Writes 1 page(4 bytes) to the PICC.

0xA2
CMD_COMP_WRITE =
0xA0
CMD_READ_CNT =
0x39
CMD_INCR_CNT =
0xA5
CMD_PWD_AUTH =
0x1B
CMD_3DES_AUTH =

Ultralight C 3DES Authentication.

0x1A
CMD_GET_VERSION =
0x60
CMD_READ_SIG =
0x3C
CMD_VCSL =
0x4B
CMD_CHECK_TEARING_EVENT =
0x3E
MF_ACK =

Mifare Acknowledge

0x0A

Constants inherited from PICC

PICC::CMD_ADDITIONAL_FRAME, PICC::CMD_DESELECT, PICC::CMD_PPS, PICC::CMD_RATS, PICC::FSCI_to_FSC

Instance Attribute Summary

Attributes inherited from PICC

#sak, #uid

Instance Method Summary collapse

Methods inherited from PICC

#halt, identify_model, #iso_deselect, #iso_select, #iso_transceive, #picc_transceive, #restart_communication

Constructor Details

#initialize(pcd, uid, sak) ⇒ Ultralight

Returns a new instance of Ultralight.


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/mifare/ultralight.rb', line 21

def initialize(pcd, uid, sak)
  super
  # Set transceive timeout to 15ms
  @pcd.internal_timer(50)

  # Maximum fast read range
  @max_range = ((@pcd.buffer_size - 2) / 4).to_i

  # Check if Ultralight C
  if @model_c = support_3des_auth?
    extend UltralightC
  end

  unless @version = check_version
    if version[:major_ver] == 0x01
      extend UltralightEV1
    end
  end
end

Instance Method Details

#get_versionObject


62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/mifare/ultralight.rb', line 62

def get_version
  version = transceive([CMD_GET_VERSION])

  expo = (version[6] >> 1) & 0x0F
  if version[6] & 0x01 == 0
    size = 1 << expo
  else
    size = (1 << expo) | (1 << (expo - 1))
  end

  CARD_VERSION.new(
    version[1], version[2], version[3], version[4], version[5], size, version[7]
  )
end

#model_c?Boolean

Returns:

  • (Boolean)

77
78
79
# File 'lib/mifare/ultralight.rb', line 77

def model_c?
  @model_c
end

#read(block_addr) ⇒ Object


50
51
52
# File 'lib/mifare/ultralight.rb', line 50

def read(block_addr)
  transceive([CMD_READ, block_addr])
end

#transceive(send_data) ⇒ Object


41
42
43
44
45
46
47
48
# File 'lib/mifare/ultralight.rb', line 41

def transceive(send_data)
  received_data, valid_bits = picc_transceive(send_data, false, true)
  unless valid_bits == 0
    raise UnexpectedDataError, 'Incorrect Mifare ACK format' if received_data.size != 1 || valid_bits != 4 # ACK is 4 bits long
    raise MifareNakError, "Mifare NAK detected: 0x#{received_data[0].to_bytehex}" if received_data[0] != MF_ACK
  end
  received_data
end

#write(page, send_data) ⇒ Object


54
55
56
57
58
59
60
# File 'lib/mifare/ultralight.rb', line 54

def write(page, send_data)
  if send_data.size != 4
    raise UsageError, "Expect 4 bytes data, got: #{send_data.size} byte"
  end

  transceive([CMD_WRITE, page, *send_data])
end