Class: ISO144434
Direct Known Subclasses
Constant Summary collapse
- FSCI_to_FSC =
[16, 24, 32, 40, 48, 64, 96, 128, 256]
- CMD_RATS =
0xE0
- CMD_PPS =
0xD0
- CMD_DESELECT =
0xC2
- CMD_SUCCESS =
0x00
- CMD_ADDITIONAL_FRAME =
0xAF
Instance Attribute Summary
Attributes inherited from PICC
Instance Method Summary collapse
-
#deselect ⇒ Object
Send S(DESELECT).
- #halt ⇒ Object
-
#initialize(pcd, uid, sak) ⇒ ISO144434
constructor
A new instance of ISO144434.
- #resume_communication ⇒ Object
-
#select ⇒ Object
ISO/IEC 14443-4 select.
-
#transceive(send_data) ⇒ Object
Wrapper for handling ISO protocol.
Constructor Details
#initialize(pcd, uid, sak) ⇒ ISO144434
Returns a new instance of ISO144434.
10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/iso144434.rb', line 10 def initialize(pcd, uid, sak) super @cid = 0x00 # We don't support CID @fsc = 16 # Assume PICC only supports 16 bytes frame @fwt = 256 # 77.33ms(256 ticks) default frame waiting time @support_cid = false @support_nad = false @block_number = 0 @selected = false end |
Instance Method Details
#deselect ⇒ Object
Send S(DESELECT)
49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/iso144434.rb', line 49 def deselect buffer = [CMD_DESELECT] received_data = @pcd.picc_transceive(buffer) if received_data[0] & 0xF7 == CMD_DESELECT @selected = false true else false end end |
#halt ⇒ Object
133 134 135 136 |
# File 'lib/iso144434.rb', line 133 def halt deselect rescue nil super end |
#resume_communication ⇒ Object
128 129 130 131 |
# File 'lib/iso144434.rb', line 128 def resume_communication deselect rescue nil super end |
#select ⇒ Object
ISO/IEC 14443-4 select
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/iso144434.rb', line 24 def select # Send RATS (Request for Answer To Select) buffer = [CMD_RATS, 0x50 | @cid] received_data = @pcd.picc_transceive(buffer) dr, ds = process_ats(received_data) # Send PPS (Protocol and Parameter Selection Request) buffer = [CMD_PPS | @cid, 0x11, (ds << 2) | dr] received_data = @pcd.picc_transceive(buffer) raise UnexpectedDataError, 'Incorrect response' if received_data[0] != (0xD0 | @cid) # Set PCD baud rate @pcd.transceiver_baud_rate(:tx, dr) @pcd.transceiver_baud_rate(:rx, ds) @block_number = 0 @max_frame_size = [64, @fsc].min @max_inf_size = @max_frame_size - 3 # PCB + CRC16 @max_inf_size -= 1 if @support_cid @max_inf_size -= 1 if @support_nad @selected = true end |
#transceive(send_data) ⇒ Object
Wrapper for handling ISO protocol
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/iso144434.rb', line 62 def transceive(send_data) # Split data according to max buffer size send_data = [send_data] unless send_data.is_a? Array chained_data = send_data.each_slice(@max_inf_size).to_a # Initialize I-block pcb = 0x02 # Send chained data until chained_data.empty? pcb &= 0xEF # Reset chaining indicator pcb |= 0x10 if chained_data.size > 1 # Set chaining pcb |= @block_number # Set block number data = chained_data.shift buffer = [pcb] + data finished = false until finished received_data = handle_wtx(buffer) # Retreive response pcb from data r_pcb = received_data[0] # Received ACK if r_pcb & 0xF6 == 0xA2 # If ACK matches current block number means success # Otherwise transmit it again if (pcb & 0x01) == (r_pcb & 0x01) finished = true end else finished = true end end @block_number ^= 1 # toggle block number for next frame end received_chained_data = [received_data] # Receive chained data while r_pcb & 0x10 != 0 ack = 0xA2 | @block_number # Set block number received_data = handle_wtx([ack]) # Send ACK to receive next frame r_pcb = received_data[0] received_chained_data << received_data @block_number ^= 1 # toggle block number for next frame end # Collect INF from chain inf = [] received_chained_data.each do |data| inf_position = 1 inf_position += 1 if data[0] & 0x08 != 0 # CID present inf_position += 1 if data[0] & 0x04 != 0 # NAD present inf.concat(data[inf_position..-1]) end inf end |