|
|
@@ -1,233 +0,0 @@
|
|
|
-require_relative 'helpers'
|
|
|
-
|
|
|
-COLOR_S2_BASES = [0x5A, 0x22, 0x30, 0x11]
|
|
|
-KELVIN_S2_BASES = COLOR_S2_BASES.map { |x| x + 0x80 }
|
|
|
-SATURATION_BRIGHTNESS_S2_BASES = [0x9A, 0x62, 0x70, 0x51]
|
|
|
-
|
|
|
-# saturation bases + 0x80
|
|
|
-COMMAND_BASES = [0x1A, 0xE2, 0xF0, 0xD1]
|
|
|
-
|
|
|
-GROUP_BASES = [0xAF, 0x04, 0xDD, 0x07]
|
|
|
-
|
|
|
-OFFSETTING_S2_FN = ->(bases, s, e) do
|
|
|
- ->(b0) do
|
|
|
- value = bases[ (b0 % 4) ]
|
|
|
- if b0 >= s && b0 <= e
|
|
|
- value = (value + 0x80) % 0x100
|
|
|
- end
|
|
|
-
|
|
|
- [value]
|
|
|
- end
|
|
|
-end
|
|
|
-
|
|
|
-extra_args = {
|
|
|
- kelvin: {
|
|
|
- increments: 2,
|
|
|
- s1_range: [0x0C],
|
|
|
- s2_range: OFFSETTING_S2_FN.call(KELVIN_S2_BASES, 0x14, 0x93)
|
|
|
- },
|
|
|
- color: {
|
|
|
- s1_range: [0x15],
|
|
|
- s2_range: OFFSETTING_S2_FN.call(COLOR_S2_BASES, 0x14, 0x93)
|
|
|
- },
|
|
|
- brightness: {
|
|
|
- s1_range: [0x0F],
|
|
|
- s2_range: OFFSETTING_S2_FN.call(SATURATION_BRIGHTNESS_S2_BASES, 0x54, 0xD3)
|
|
|
- },
|
|
|
- saturation: {
|
|
|
- invert_key: true,
|
|
|
- s1_range: [0x0E],
|
|
|
- s2_range: OFFSETTING_S2_FN.call(SATURATION_BRIGHTNESS_S2_BASES, 0x54, 0xD3)
|
|
|
- },
|
|
|
- on_seq: {
|
|
|
- s1_range: [0x00],
|
|
|
- },
|
|
|
- group: {
|
|
|
- s1_range: [0x00],
|
|
|
- s2_range: OFFSETTING_S2_FN.call(GROUP_BASES, 0x54, 0xD3)
|
|
|
- },
|
|
|
- checksum: {
|
|
|
- s1_range: ->(x) do
|
|
|
- lsn = (((x & 0xF)^2) + 7) % 0x10
|
|
|
-
|
|
|
- (0..0xF).map { |msn| (msn << 4) + lsn }
|
|
|
- end,
|
|
|
- s2_range: [ 0xA1, 0x53, 0x78, 0xA4 ]
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-type_overrides = {
|
|
|
- checksum: 'on_seq'
|
|
|
-}
|
|
|
-
|
|
|
-lengths = {
|
|
|
- color: 256,
|
|
|
- brightness: 0x64,
|
|
|
- kelvin: 0x64,
|
|
|
- saturation: 0x64,
|
|
|
- on_seq: 30,
|
|
|
- checksum: 0xFF,
|
|
|
- group: 40
|
|
|
-}
|
|
|
-
|
|
|
-columns = {
|
|
|
- on_seq: 6,
|
|
|
- group: 7,
|
|
|
- checksum: 8
|
|
|
-}
|
|
|
-
|
|
|
-extract_fns = {
|
|
|
- group: ->(b0) do
|
|
|
- get_group_sequence(type: 'on', col: 7, key: b0, group_range: (0..100))
|
|
|
- end
|
|
|
-}
|
|
|
-
|
|
|
-# PACKET_TYPES = %w(color brightness saturation kelvin on_seq checksum)
|
|
|
-PACKET_TYPES = %w(color brightness kelvin saturation group)
|
|
|
-
|
|
|
-(0x00..0xFF).each do |b0|
|
|
|
- k = xor_key(b0)
|
|
|
- results = {}
|
|
|
-
|
|
|
- PACKET_TYPES.each do |type|
|
|
|
- type_args = extra_args[type.to_sym] || {}
|
|
|
- file_type = type_overrides[type.to_sym] || type
|
|
|
-
|
|
|
- if extract_fn = extract_fns[type.to_sym]
|
|
|
- packet_str = extract_fn.call(b0)
|
|
|
- else
|
|
|
- packet_str = get_sequence(file_type, b0, columns[type.to_sym] || 5)
|
|
|
- end
|
|
|
-
|
|
|
- max_len = lengths[type.to_sym]*2
|
|
|
- if packet_str.length > max_len
|
|
|
- packet_str = packet_str[0...max_len]
|
|
|
- end
|
|
|
-
|
|
|
- args = {}.merge(extra_args[type.to_sym] || {})
|
|
|
-
|
|
|
-
|
|
|
- if args[:s1_range].is_a?(Proc)
|
|
|
- args[:s1_range] = args[:s1_range].call(b0)
|
|
|
- end
|
|
|
-
|
|
|
- if args[:s2_range].is_a?(Proc)
|
|
|
- args[:s2_range] = args[:s2_range].call(b0)
|
|
|
- end
|
|
|
-
|
|
|
- args = {
|
|
|
- seq: packet_str,
|
|
|
- xor_range: [k]
|
|
|
- }.merge(args)
|
|
|
-
|
|
|
- results[type] = search_sequence(args)
|
|
|
- end
|
|
|
-
|
|
|
- num_fns = results.values.map { |x| x[:scramble_fns].length }.max
|
|
|
- printf "0x%02X", b0
|
|
|
-
|
|
|
- (0...num_fns).each do |i|
|
|
|
- printf "\t\t"
|
|
|
-
|
|
|
- PACKET_TYPES.each do |type|
|
|
|
- result = results[type]
|
|
|
-
|
|
|
- fns = result[:scramble_fns]
|
|
|
-
|
|
|
- if i < fns.length
|
|
|
- fn = result[:scramble_fns][i]
|
|
|
- printf "0x%02X\t0x%02X\t0x%02X\t%d\t", fn[:a], fn[:x], fn[:b], result[:num_misses]
|
|
|
- else
|
|
|
- printf "\t\t\t\t"
|
|
|
- end
|
|
|
- end
|
|
|
-
|
|
|
- printf "\n"
|
|
|
- end
|
|
|
-end
|
|
|
-
|
|
|
-# Dir.glob("#{CAPTURES_DIR}/**.txt").each do |filename|
|
|
|
-# puts File.basename(filename)
|
|
|
-# capture = parse_capture(filename)
|
|
|
-#
|
|
|
-# pp first_byte_determines_next(capture, 3)
|
|
|
-#
|
|
|
-# # a = capture
|
|
|
-# # .group_by { |x| x[0] }
|
|
|
-# # .sort
|
|
|
-# # .map { |_, packets| [packets.first[0], packets.first[1]] }
|
|
|
-# # mappings = Hash[a]
|
|
|
-# # perms = []
|
|
|
-# # current_perm = []
|
|
|
-# # elem = a.first
|
|
|
-# # current_perm = [elem[0]]
|
|
|
-# # visited = Set.new([elem[0]])
|
|
|
-# # perm_visited = Set.new([elem[0]])
|
|
|
-# #
|
|
|
-# # while visited.length < mappings.length
|
|
|
-# # new_elem = nil
|
|
|
-# #
|
|
|
-# # puts visited.inspect
|
|
|
-# #
|
|
|
-# # if !mappings.include?(elem[1]) || perm_visited.include?(mappings[elem[1]])
|
|
|
-# # new_elem = (Set.new(mappings.keys) - visited).first
|
|
|
-# # perms << current_perm
|
|
|
-# # current_perm = []
|
|
|
-# # perm_visited = Set.new
|
|
|
-# # else
|
|
|
-# # new_elem = [elem[1], mappings[elem[1]]]
|
|
|
-# # end
|
|
|
-# #
|
|
|
-# # visited << new_elem[0]
|
|
|
-# # perm_visited << new_elem[0]
|
|
|
-# # elem = new_elem
|
|
|
-# # end
|
|
|
-# #
|
|
|
-# # perms << current_perm
|
|
|
-# #
|
|
|
-# # pp perms
|
|
|
-#
|
|
|
-# a = capture
|
|
|
-# .group_by { |x| x[0] }
|
|
|
-# .sort
|
|
|
-# .map { |_, packets| [packets.first[0], packets.first[1]] }
|
|
|
-# .sort { |x,y| x[1] <=> y[1] }
|
|
|
-# a = a
|
|
|
-# .each_with_index.map do |x, i|
|
|
|
-# [x[1],x[0],if a[i-1][1] == x[1]-1
|
|
|
-# (x[0]-a[i-1][0])
|
|
|
-# else
|
|
|
-# nil
|
|
|
-# end]
|
|
|
-# end
|
|
|
-# .to_a
|
|
|
-# # # .group_by { |x| x[1] }
|
|
|
-# # # .sort
|
|
|
-# # # .to_a
|
|
|
-#
|
|
|
-# pp a
|
|
|
-#
|
|
|
-# # a = capture
|
|
|
-# # .group_by { |x| x[0] }
|
|
|
-# # .map { |_, packets| packets.first }
|
|
|
-# # .sort #{ |x, y| x[1] <=> y[1] }
|
|
|
-# # .map { |x| x }
|
|
|
-# # .to_a
|
|
|
-# #
|
|
|
-# end
|
|
|
-
|
|
|
-# on1 = parse_capture("#{CAPTURES_DIR}/rgbwcct_group1_on.txt")
|
|
|
-# on2 = parse_capture("#{CAPTURES_DIR}/rgbwcct_group2_on.txt")
|
|
|
-#
|
|
|
-# on1_g = on1.group_by { |x| x[0] }
|
|
|
-# on2_g = on2.group_by { |x| x[0] }
|
|
|
-#
|
|
|
-# a = (on1 + on2)
|
|
|
-# .map { |x| x[0] }
|
|
|
-# .sort
|
|
|
-# .uniq
|
|
|
-# .map do |key|
|
|
|
-# {key: key, vals: {on1: (on1_g[key]||[]).map { |x| x[1] }, on2: (on2_g[key]||[]).map { |x| x[1] } }}
|
|
|
-# end
|
|
|
-# .to_a
|
|
|
-# pp a
|