Class: MifareAccessConditionBuilder::MainWindow

Inherits:
Fox::FXMainWindow
  • Object
show all
Includes:
Fox
Defined in:
lib/mifare_access_condition_builder.rb

Defined Under Namespace

Classes: AccBlock, InvalidArgument, SelectionDialog

Constant Summary collapse

DataBitsHead =
['bits','','read', 'write', 'increment', 'dec,tran,dec', 'description']
DataBitsDesc =
{
  '000' => [['A|B', 'A|B', 'A|B', 'A|B'], ['A', 'A', 'A', 'A'], 'transport config'],
  '010' => [['A|B', '-'  , '-'  , '-'  ], ['A', '-', '-', '-'], 'read/write block'],
  '100' => [['A|B', 'B'  , '-'  , '-'  ], ['A', '-', '-', '-'], 'read/write block'],
  '110' => [['A|B', 'B'  , 'B'  , 'A|B'], ['A', '-', '-', 'A'], 'value block'],
  '001' => [['A|B', '-'  , '-'  , 'A|B'], ['A', '-', '-', 'A'], 'value block'],
  '011' => [['B'  , 'B'  , '-'  , '-'  ], ['-', '-', '-', '-'], 'read/write block'],
  '101' => [['B'  , '-'  , '-'  , '-'  ], ['-', '-', '-', '-'], 'read/write block'],
  '111' => [['-'  , '-'  , '-'  , '-'  ], ['-', '-', '-', '-'], 'read/write block'],
}
TrailerBitsHead =
['bits','', 'read A', 'write A', 'read ACC', 'write ACC', 'read B', 'write B', 'description']
TrailerBitsDesc =
{
  '000' => ['-', 'A', 'A'  , '-', 'A', 'A', 'Key B may be read'],
  '010' => ['-', '-', 'A'  , '-', 'A', '-', 'Key B may be read'],
  '100' => ['-', 'B', 'A|B', '-', '-', 'B', ' '],
  '110' => ['-', '-', 'A|B', '-', '-', '-', ' '],
  '001' => ['-', 'A', 'A'  , 'A', 'A', 'A', 'Key B may be read, transport config'],
  '011' => ['-', 'B', 'A|B', 'B', '-', 'B', ' '],
  '101' => ['-', '-', 'A|B', 'B', '-', '-', ' '],
  '111' => ['-', '-', 'A|B', '-', '-', '-', ' '],
}

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ MainWindow

Returns a new instance of MainWindow.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
# File 'lib/mifare_access_condition_builder.rb', line 24

def initialize(app)
  # Initialize base class
  super(app, "Mifare Access Condition Builder #{VERSION}", nil, nil, DECOR_ALL, 0, 0, 750, 250)

  # Tooltips einschalten und auf dauerhafte Anzeige einstellen.
  FXToolTip.new(getApp(), TOOLTIP_PERMANENT)

  #    scrollwindow = FXScrollWindow.new(self, LAYOUT_FILL_X | LAYOUT_FILL_Y)
  top = FXVerticalFrame.new(self, LAYOUT_FILL_X | LAYOUT_FILL_Y){|theFrame|
    theFrame.padLeft = theFrame.padRight = theFrame.padBottom = theFrame.padTop = 5
    theFrame.vSpacing = 5

    FXHorizontalFrame.new(theFrame, LAYOUT_FILL_X|LAYOUT_FILL_Y){|hex_frame|
      FXLabel.new(hex_frame, 'Hex-Eingabe (3 Byte):')
      @hex_input = FXTextField.new(hex_frame,0, nil, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X){|this|
        this.connect(SEL_COMMAND, method(:hex_changed))
        this.text = 'FF 07 80'
      }
    }
    @message = FXLabel.new(theFrame, ''){|this|
      this.textColor = FXColor::Red
    }

    @acc_blocks = []
    FXMatrix.new(theFrame, 8, MATRIX_BY_COLUMNS | LAYOUT_FILL_X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0){|matrix|
      [''].+(DataBitsHead).each{|labeltext|
        FXLabel.new(matrix, labeltext, nil, LAYOUT_FILL_COLUMN|LAYOUT_FILL_X)
      }

      for blocknr in 0..2 do
        acc_block = AccBlock.new nil, []
        FXLabel.new(matrix, "Block #{blocknr}", nil, LAYOUT_FILL_X)
        acc_block.bits = FXTextField.new(matrix,10, nil, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X)
        acc_block.bits.connect(SEL_COMMAND, method(:bits_changed))
        FXLabel.new(matrix,'->')
        for desc in 0...5
          acc_block.descs << FXLabel.new(matrix, '', nil, TEXTFIELD_NORMAL|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X|TEXTFIELD_READONLY){|this|
            this.backColor = FXColor::LightGoldenrod1
            bits_field = acc_block.bits
            this.connect(SEL_LEFTBUTTONPRESS){|sender, sel, ptr|
              desc_clicked(sender, sel, ptr, bits_field, acc_block.key_b_readable ? :data_key_b_readable : :data_key_b_secret)
            }
          }
        end
        @acc_blocks << acc_block
      end
    }
    FXMatrix.new(theFrame, 10, MATRIX_BY_COLUMNS | LAYOUT_FILL_X, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0){|matrix|
      [''].+(TrailerBitsHead).each{|labeltext|
        FXLabel.new(matrix, labeltext, nil, LAYOUT_FILL_COLUMN|LAYOUT_FILL_X)
      }

      acc_block = AccBlock.new nil, []
      FXLabel.new(matrix, "Block 3", nil, LAYOUT_FILL_X)
      acc_block.bits = FXTextField.new(matrix,10, nil, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X)
      acc_block.bits.connect(SEL_COMMAND, method(:bits_changed))
      FXLabel.new(matrix,'->')
      for desc in 0...7
        acc_block.descs << FXLabel.new(matrix,'', nil, TEXTFIELD_NORMAL|LAYOUT_FILL_COLUMN|LAYOUT_FILL_X|TEXTFIELD_READONLY){|this|
          this.backColor = FXColor::PaleGreen
          bits_field = acc_block.bits
          this.connect(SEL_LEFTBUTTONPRESS){|sender, sel, ptr|
            desc_clicked(sender, sel, ptr, bits_field, :trailer)
          }
        }
      end
      @acc_blocks << acc_block
    }
  }
  # sinnvolle default-Werte in Felder eintragen
  hex_changed
end

Instance Method Details

#acc_bits_to_hex(blocksbits) ⇒ Object

Raises:



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/mifare_access_condition_builder.rb', line 169

def acc_bits_to_hex(blocksbits)
  raise InvalidArgument, "Bits fuer 4 Bloecke erwartet: #{blocksbits.inspect}" unless blocksbits.length==4

  blocksbits.each_with_index do |bit, bidx|
    raise InvalidArgument, "3 Bit String für Block #{bidx} erwartet: #{bit.inspect}" unless bit=~/^[0-1]{3,3}$/i
  end

  nibbles = [0,0,0]
  blocksbits.each_with_index do |blockbits, bbidx|
    nibbles.each_with_index do |nibble, nidx|
      onoff = blockbits[nidx,1].hex
      nibble |= onoff << bbidx
      nibbles[nidx] = nibble
    end
  end
  return sprintf("%x%x%x%x%x%x",
    nibbles[1] ^ 0xf, nibbles[0] ^ 0xf,
    nibbles[0], nibbles[2] ^ 0xf,
    nibbles[2], nibbles[1])
end

#acc_hex_to_bits(hex) ⇒ Object

Raises:



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/mifare_access_condition_builder.rb', line 149

def acc_hex_to_bits(hex)
  hex = hex.gsub(/\s/, '')
  raise InvalidArgument, "3 Byte Hex-String erwartet: #{hex.inspect}" unless hex=~/^[0-9a-f]{6,6}$/i

  blocksbits = ['','','','']
  nibbles = [hex[2,1].hex, hex[5,1].hex, hex[4,1].hex]
  nibbles.each do |nibble|
#       puts "nibble: #{nibble.inspect}"
    blocksbits.each_with_index do |blockbits, bbidx|
      onoff = (nibble >> bbidx) & 1
#         puts "onoff: #{onoff.inspect} bits: #{blockbits.inspect}"
      blockbits << (onoff>0 ? '1' : '0')
    end
  end
  hex2 = acc_bits_to_hex(blocksbits)
  raise InvalidArgument, "Hex-Daten sind inkonsistent: #{hex}!=#{hex2}" unless hex.upcase==hex2.upcase

  return blocksbits
end

#bits_changed(sender = nil, sel = nil, ptr = nil) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/mifare_access_condition_builder.rb', line 132

def bits_changed(sender=nil, sel=nil, ptr=nil)
  blocksbits = @acc_blocks.map{|ab| ab.bits.text }
#     puts "bits-input: #{blocksbits.inspect}"

  hex = ''
  display_error do
    hex = acc_bits_to_hex(blocksbits).upcase
#       puts hex
  end
  display_bits_desc

  @hex_input.text = [hex[0,2], hex[2,2], hex[4..-1]].join(" ")
end

#createObject



97
98
99
100
101
102
103
# File 'lib/mifare_access_condition_builder.rb', line 97

def create
  super
  show(PLACEMENT_SCREEN)
  app.addTimeout(1) do
    @hex_input.setFocus
  end
end

#desc_clicked(sender, sel, ptr, bits_field, data_or_trailer) ⇒ Object



232
233
234
235
236
237
238
239
# File 'lib/mifare_access_condition_builder.rb', line 232

def desc_clicked(sender, sel, ptr, bits_field, data_or_trailer)
  sd = SelectionDialog.new(data_or_trailer, sender, "Select Access Conditions", opts: DECOR_ALL, height: 320, width: 600)
  if sd.execute > 0
    bits = sd.selected_bits
    bits_field.text = bits
    bits_changed
  end
end

#display_bits_descObject



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/mifare_access_condition_builder.rb', line 213

def display_bits_desc
  @acc_blocks.each_with_index do |acc_block, blidx|
    if blidx==3
      descs = TrailerBitsDesc[acc_block.bits.text] || Array.new(6,'')
    else
      trailer = TrailerBitsDesc[@acc_blocks.last.bits.text]
      ws_descs, wr_descs, desc = DataBitsDesc[acc_block.bits.text] || [Array.new(4,'')]*2
      if trailer && trailer[4].tr("-","").empty?
        descs = ws_descs + [desc] # Key B can't be read
        acc_block.key_b_readable = false
      else
        descs = wr_descs + [desc] # Key B may be read
        acc_block.key_b_readable = true
      end
    end
    descs.each_with_index{|desc, descidx| acc_block.descs[descidx].text = desc.to_s }
  end
end

#display_errorObject



105
106
107
108
109
110
111
112
113
# File 'lib/mifare_access_condition_builder.rb', line 105

def display_error
  begin
    yield
  rescue InvalidArgument => e
    @message.text = e.to_s
  else
    @message.text = ''
  end
end

#hex_changed(sender = nil, sel = nil, ptr = nil) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/mifare_access_condition_builder.rb', line 115

def hex_changed(sender=nil, sel=nil, ptr=nil)
  hex = @hex_input.text
#     puts "hex-input: #{hex}"

  bits = nil
  display_error do
    bits = acc_hex_to_bits(hex)
    # puts bits

    @acc_blocks.each_with_index do |bl, blidx|
      bl.bits.text = bits[blidx]
    end
  end

  display_bits_desc
end