class MIFARE::Ultralight

Constants

CARD_VERSION
CMD_3DES_AUTH
CMD_CHECK_TEARING_EVENT
CMD_COMP_WRITE
CMD_FAST_READ
CMD_GET_VERSION
CMD_INCR_CNT
CMD_PWD_AUTH
CMD_READ
CMD_READ_CNT
CMD_READ_SIG
CMD_VCSL
CMD_WRITE
MF_ACK

Public Class Methods

new(pcd, uid, sak) click to toggle source
Calls superclass method PICC::new
# 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

Public Instance Methods

get_version() click to toggle source
# 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?() click to toggle source
# File lib/mifare/ultralight.rb, line 77
def model_c?
  @model_c
end
read(block_addr) click to toggle source
# File lib/mifare/ultralight.rb, line 50
def read(block_addr)
  transceive([CMD_READ, block_addr])
end
transceive(send_data) click to toggle source
# 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) click to toggle source
# 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

Private Instance Methods

check_version() click to toggle source
# File lib/mifare/ultralight.rb, line 83
def check_version
  begin
    version = get_version
  rescue CommunicationError
    restart_communication
    return nil
  end
  version
end
support_3des_auth?() click to toggle source

Check if PICC support Ultralight 3DES command

# File lib/mifare/ultralight.rb, line 94
def support_3des_auth?
  # Ask for authentication
  buffer = [CMD_3DES_AUTH, 0x00]

  begin
    transceive(buffer)
    result = true
  rescue CommunicationError
    result = false
  end

  restart_communication
  result
end