Merge pull request #24 from VorpalBlade/feature/code-cleanup
Major code cleanup:
This commit is contained in:
commit
6a7ae704e7
29 changed files with 2205 additions and 1007 deletions
394
.style.yapf
Normal file
394
.style.yapf
Normal file
|
|
@ -0,0 +1,394 @@
|
||||||
|
[style]
|
||||||
|
# Align closing bracket with visual indentation.
|
||||||
|
align_closing_bracket_with_visual_indent=True
|
||||||
|
|
||||||
|
# Allow dictionary keys to exist on multiple lines. For example:
|
||||||
|
#
|
||||||
|
# x = {
|
||||||
|
# ('this is the first element of a tuple',
|
||||||
|
# 'this is the second element of a tuple'):
|
||||||
|
# value,
|
||||||
|
# }
|
||||||
|
allow_multiline_dictionary_keys=False
|
||||||
|
|
||||||
|
# Allow lambdas to be formatted on more than one line.
|
||||||
|
allow_multiline_lambdas=False
|
||||||
|
|
||||||
|
# Allow splitting before a default / named assignment in an argument list.
|
||||||
|
allow_split_before_default_or_named_assigns=True
|
||||||
|
|
||||||
|
# Allow splits before the dictionary value.
|
||||||
|
allow_split_before_dict_value=True
|
||||||
|
|
||||||
|
# Let spacing indicate operator precedence. For example:
|
||||||
|
#
|
||||||
|
# a = 1 * 2 + 3 / 4
|
||||||
|
# b = 1 / 2 - 3 * 4
|
||||||
|
# c = (1 + 2) * (3 - 4)
|
||||||
|
# d = (1 - 2) / (3 + 4)
|
||||||
|
# e = 1 * 2 - 3
|
||||||
|
# f = 1 + 2 + 3 + 4
|
||||||
|
#
|
||||||
|
# will be formatted as follows to indicate precedence:
|
||||||
|
#
|
||||||
|
# a = 1*2 + 3/4
|
||||||
|
# b = 1/2 - 3*4
|
||||||
|
# c = (1+2) * (3-4)
|
||||||
|
# d = (1-2) / (3+4)
|
||||||
|
# e = 1*2 - 3
|
||||||
|
# f = 1 + 2 + 3 + 4
|
||||||
|
#
|
||||||
|
arithmetic_precedence_indication=False
|
||||||
|
|
||||||
|
# Number of blank lines surrounding top-level function and class
|
||||||
|
# definitions.
|
||||||
|
blank_lines_around_top_level_definition=2
|
||||||
|
|
||||||
|
# Insert a blank line before a class-level docstring.
|
||||||
|
blank_line_before_class_docstring=False
|
||||||
|
|
||||||
|
# Insert a blank line before a module docstring.
|
||||||
|
blank_line_before_module_docstring=False
|
||||||
|
|
||||||
|
# Insert a blank line before a 'def' or 'class' immediately nested
|
||||||
|
# within another 'def' or 'class'. For example:
|
||||||
|
#
|
||||||
|
# class Foo:
|
||||||
|
# # <------ this blank line
|
||||||
|
# def method():
|
||||||
|
# ...
|
||||||
|
blank_line_before_nested_class_or_def=False
|
||||||
|
|
||||||
|
# Do not split consecutive brackets. Only relevant when
|
||||||
|
# dedent_closing_brackets is set. For example:
|
||||||
|
#
|
||||||
|
# call_func_that_takes_a_dict(
|
||||||
|
# {
|
||||||
|
# 'key1': 'value1',
|
||||||
|
# 'key2': 'value2',
|
||||||
|
# }
|
||||||
|
# )
|
||||||
|
#
|
||||||
|
# would reformat to:
|
||||||
|
#
|
||||||
|
# call_func_that_takes_a_dict({
|
||||||
|
# 'key1': 'value1',
|
||||||
|
# 'key2': 'value2',
|
||||||
|
# })
|
||||||
|
coalesce_brackets=False
|
||||||
|
|
||||||
|
# The column limit.
|
||||||
|
column_limit=100
|
||||||
|
|
||||||
|
# The style for continuation alignment. Possible values are:
|
||||||
|
#
|
||||||
|
# - SPACE: Use spaces for continuation alignment. This is default behavior.
|
||||||
|
# - FIXED: Use fixed number (CONTINUATION_INDENT_WIDTH) of columns
|
||||||
|
# (ie: CONTINUATION_INDENT_WIDTH/INDENT_WIDTH tabs or
|
||||||
|
# CONTINUATION_INDENT_WIDTH spaces) for continuation alignment.
|
||||||
|
# - VALIGN-RIGHT: Vertically align continuation lines to multiple of
|
||||||
|
# INDENT_WIDTH columns. Slightly right (one tab or a few spaces) if
|
||||||
|
# cannot vertically align continuation lines with indent characters.
|
||||||
|
continuation_align_style=SPACE
|
||||||
|
|
||||||
|
# Indent width used for line continuations.
|
||||||
|
continuation_indent_width=4
|
||||||
|
|
||||||
|
# Put closing brackets on a separate line, dedented, if the bracketed
|
||||||
|
# expression can't fit in a single line. Applies to all kinds of brackets,
|
||||||
|
# including function definitions and calls. For example:
|
||||||
|
#
|
||||||
|
# config = {
|
||||||
|
# 'key1': 'value1',
|
||||||
|
# 'key2': 'value2',
|
||||||
|
# } # <--- this bracket is dedented and on a separate line
|
||||||
|
#
|
||||||
|
# time_series = self.remote_client.query_entity_counters(
|
||||||
|
# entity='dev3246.region1',
|
||||||
|
# key='dns.query_latency_tcp',
|
||||||
|
# transform=Transformation.AVERAGE(window=timedelta(seconds=60)),
|
||||||
|
# start_ts=now()-timedelta(days=3),
|
||||||
|
# end_ts=now(),
|
||||||
|
# ) # <--- this bracket is dedented and on a separate line
|
||||||
|
dedent_closing_brackets=False
|
||||||
|
|
||||||
|
# Disable the heuristic which places each list element on a separate line
|
||||||
|
# if the list is comma-terminated.
|
||||||
|
disable_ending_comma_heuristic=False
|
||||||
|
|
||||||
|
# Place each dictionary entry onto its own line.
|
||||||
|
each_dict_entry_on_separate_line=True
|
||||||
|
|
||||||
|
# Require multiline dictionary even if it would normally fit on one line.
|
||||||
|
# For example:
|
||||||
|
#
|
||||||
|
# config = {
|
||||||
|
# 'key1': 'value1'
|
||||||
|
# }
|
||||||
|
force_multiline_dict=False
|
||||||
|
|
||||||
|
# The regex for an i18n comment. The presence of this comment stops
|
||||||
|
# reformatting of that line, because the comments are required to be
|
||||||
|
# next to the string they translate.
|
||||||
|
i18n_comment=
|
||||||
|
|
||||||
|
# The i18n function call names. The presence of this function stops
|
||||||
|
# reformattting on that line, because the string it has cannot be moved
|
||||||
|
# away from the i18n comment.
|
||||||
|
i18n_function_call=
|
||||||
|
|
||||||
|
# Indent blank lines.
|
||||||
|
indent_blank_lines=False
|
||||||
|
|
||||||
|
# Put closing brackets on a separate line, indented, if the bracketed
|
||||||
|
# expression can't fit in a single line. Applies to all kinds of brackets,
|
||||||
|
# including function definitions and calls. For example:
|
||||||
|
#
|
||||||
|
# config = {
|
||||||
|
# 'key1': 'value1',
|
||||||
|
# 'key2': 'value2',
|
||||||
|
# } # <--- this bracket is indented and on a separate line
|
||||||
|
#
|
||||||
|
# time_series = self.remote_client.query_entity_counters(
|
||||||
|
# entity='dev3246.region1',
|
||||||
|
# key='dns.query_latency_tcp',
|
||||||
|
# transform=Transformation.AVERAGE(window=timedelta(seconds=60)),
|
||||||
|
# start_ts=now()-timedelta(days=3),
|
||||||
|
# end_ts=now(),
|
||||||
|
# ) # <--- this bracket is indented and on a separate line
|
||||||
|
indent_closing_brackets=False
|
||||||
|
|
||||||
|
# Indent the dictionary value if it cannot fit on the same line as the
|
||||||
|
# dictionary key. For example:
|
||||||
|
#
|
||||||
|
# config = {
|
||||||
|
# 'key1':
|
||||||
|
# 'value1',
|
||||||
|
# 'key2': value1 +
|
||||||
|
# value2,
|
||||||
|
# }
|
||||||
|
indent_dictionary_value=False
|
||||||
|
|
||||||
|
# The number of columns to use for indentation.
|
||||||
|
indent_width=4
|
||||||
|
|
||||||
|
# Join short lines into one line. E.g., single line 'if' statements.
|
||||||
|
join_multiple_lines=True
|
||||||
|
|
||||||
|
# Do not include spaces around selected binary operators. For example:
|
||||||
|
#
|
||||||
|
# 1 + 2 * 3 - 4 / 5
|
||||||
|
#
|
||||||
|
# will be formatted as follows when configured with "*,/":
|
||||||
|
#
|
||||||
|
# 1 + 2*3 - 4/5
|
||||||
|
no_spaces_around_selected_binary_operators=
|
||||||
|
|
||||||
|
# Use spaces around default or named assigns.
|
||||||
|
spaces_around_default_or_named_assign=False
|
||||||
|
|
||||||
|
# Adds a space after the opening '{' and before the ending '}' dict delimiters.
|
||||||
|
#
|
||||||
|
# {1: 2}
|
||||||
|
#
|
||||||
|
# will be formatted as:
|
||||||
|
#
|
||||||
|
# { 1: 2 }
|
||||||
|
spaces_around_dict_delimiters=False
|
||||||
|
|
||||||
|
# Adds a space after the opening '[' and before the ending ']' list delimiters.
|
||||||
|
#
|
||||||
|
# [1, 2]
|
||||||
|
#
|
||||||
|
# will be formatted as:
|
||||||
|
#
|
||||||
|
# [ 1, 2 ]
|
||||||
|
spaces_around_list_delimiters=False
|
||||||
|
|
||||||
|
# Use spaces around the power operator.
|
||||||
|
spaces_around_power_operator=False
|
||||||
|
|
||||||
|
# Use spaces around the subscript / slice operator. For example:
|
||||||
|
#
|
||||||
|
# my_list[1 : 10 : 2]
|
||||||
|
spaces_around_subscript_colon=False
|
||||||
|
|
||||||
|
# Adds a space after the opening '(' and before the ending ')' tuple delimiters.
|
||||||
|
#
|
||||||
|
# (1, 2, 3)
|
||||||
|
#
|
||||||
|
# will be formatted as:
|
||||||
|
#
|
||||||
|
# ( 1, 2, 3 )
|
||||||
|
spaces_around_tuple_delimiters=False
|
||||||
|
|
||||||
|
# The number of spaces required before a trailing comment.
|
||||||
|
# This can be a single value (representing the number of spaces
|
||||||
|
# before each trailing comment) or list of values (representing
|
||||||
|
# alignment column values; trailing comments within a block will
|
||||||
|
# be aligned to the first column value that is greater than the maximum
|
||||||
|
# line length within the block). For example:
|
||||||
|
#
|
||||||
|
# With spaces_before_comment=5:
|
||||||
|
#
|
||||||
|
# 1 + 1 # Adding values
|
||||||
|
#
|
||||||
|
# will be formatted as:
|
||||||
|
#
|
||||||
|
# 1 + 1 # Adding values <-- 5 spaces between the end of the statement and comment
|
||||||
|
#
|
||||||
|
# With spaces_before_comment=15, 20:
|
||||||
|
#
|
||||||
|
# 1 + 1 # Adding values
|
||||||
|
# two + two # More adding
|
||||||
|
#
|
||||||
|
# longer_statement # This is a longer statement
|
||||||
|
# short # This is a shorter statement
|
||||||
|
#
|
||||||
|
# a_very_long_statement_that_extends_beyond_the_final_column # Comment
|
||||||
|
# short # This is a shorter statement
|
||||||
|
#
|
||||||
|
# will be formatted as:
|
||||||
|
#
|
||||||
|
# 1 + 1 # Adding values <-- end of line comments in block aligned to col 15
|
||||||
|
# two + two # More adding
|
||||||
|
#
|
||||||
|
# longer_statement # This is a longer statement <-- end of line comments in block aligned to col 20
|
||||||
|
# short # This is a shorter statement
|
||||||
|
#
|
||||||
|
# a_very_long_statement_that_extends_beyond_the_final_column # Comment <-- the end of line comments are aligned based on the line length
|
||||||
|
# short # This is a shorter statement
|
||||||
|
#
|
||||||
|
spaces_before_comment=2
|
||||||
|
|
||||||
|
# Insert a space between the ending comma and closing bracket of a list,
|
||||||
|
# etc.
|
||||||
|
space_between_ending_comma_and_closing_bracket=True
|
||||||
|
|
||||||
|
# Use spaces inside brackets, braces, and parentheses. For example:
|
||||||
|
#
|
||||||
|
# method_call( 1 )
|
||||||
|
# my_dict[ 3 ][ 1 ][ get_index( *args, **kwargs ) ]
|
||||||
|
# my_set = { 1, 2, 3 }
|
||||||
|
space_inside_brackets=False
|
||||||
|
|
||||||
|
# Split before arguments
|
||||||
|
split_all_comma_separated_values=False
|
||||||
|
|
||||||
|
# Split before arguments, but do not split all subexpressions recursively
|
||||||
|
# (unless needed).
|
||||||
|
split_all_top_level_comma_separated_values=False
|
||||||
|
|
||||||
|
# Split before arguments if the argument list is terminated by a
|
||||||
|
# comma.
|
||||||
|
split_arguments_when_comma_terminated=False
|
||||||
|
|
||||||
|
# Set to True to prefer splitting before '+', '-', '*', '/', '//', or '@'
|
||||||
|
# rather than after.
|
||||||
|
split_before_arithmetic_operator=False
|
||||||
|
|
||||||
|
# Set to True to prefer splitting before '&', '|' or '^' rather than
|
||||||
|
# after.
|
||||||
|
split_before_bitwise_operator=True
|
||||||
|
|
||||||
|
# Split before the closing bracket if a list or dict literal doesn't fit on
|
||||||
|
# a single line.
|
||||||
|
split_before_closing_bracket=True
|
||||||
|
|
||||||
|
# Split before a dictionary or set generator (comp_for). For example, note
|
||||||
|
# the split before the 'for':
|
||||||
|
#
|
||||||
|
# foo = {
|
||||||
|
# variable: 'Hello world, have a nice day!'
|
||||||
|
# for variable in bar if variable != 42
|
||||||
|
# }
|
||||||
|
split_before_dict_set_generator=True
|
||||||
|
|
||||||
|
# Split before the '.' if we need to split a longer expression:
|
||||||
|
#
|
||||||
|
# foo = ('This is a really long string: {}, {}, {}, {}'.format(a, b, c, d))
|
||||||
|
#
|
||||||
|
# would reformat to something like:
|
||||||
|
#
|
||||||
|
# foo = ('This is a really long string: {}, {}, {}, {}'
|
||||||
|
# .format(a, b, c, d))
|
||||||
|
split_before_dot=False
|
||||||
|
|
||||||
|
# Split after the opening paren which surrounds an expression if it doesn't
|
||||||
|
# fit on a single line.
|
||||||
|
split_before_expression_after_opening_paren=False
|
||||||
|
|
||||||
|
# If an argument / parameter list is going to be split, then split before
|
||||||
|
# the first argument.
|
||||||
|
split_before_first_argument=False
|
||||||
|
|
||||||
|
# Set to True to prefer splitting before 'and' or 'or' rather than
|
||||||
|
# after.
|
||||||
|
split_before_logical_operator=True
|
||||||
|
|
||||||
|
# Split named assignments onto individual lines.
|
||||||
|
split_before_named_assigns=True
|
||||||
|
|
||||||
|
# Set to True to split list comprehensions and generators that have
|
||||||
|
# non-trivial expressions and multiple clauses before each of these
|
||||||
|
# clauses. For example:
|
||||||
|
#
|
||||||
|
# result = [
|
||||||
|
# a_long_var + 100 for a_long_var in xrange(1000)
|
||||||
|
# if a_long_var % 10]
|
||||||
|
#
|
||||||
|
# would reformat to something like:
|
||||||
|
#
|
||||||
|
# result = [
|
||||||
|
# a_long_var + 100
|
||||||
|
# for a_long_var in xrange(1000)
|
||||||
|
# if a_long_var % 10]
|
||||||
|
split_complex_comprehension=False
|
||||||
|
|
||||||
|
# The penalty for splitting right after the opening bracket.
|
||||||
|
split_penalty_after_opening_bracket=300
|
||||||
|
|
||||||
|
# The penalty for splitting the line after a unary operator.
|
||||||
|
split_penalty_after_unary_operator=10000
|
||||||
|
|
||||||
|
# The penalty of splitting the line around the '+', '-', '*', '/', '//',
|
||||||
|
# ``%``, and '@' operators.
|
||||||
|
split_penalty_arithmetic_operator=300
|
||||||
|
|
||||||
|
# The penalty for splitting right before an if expression.
|
||||||
|
split_penalty_before_if_expr=0
|
||||||
|
|
||||||
|
# The penalty of splitting the line around the '&', '|', and '^'
|
||||||
|
# operators.
|
||||||
|
split_penalty_bitwise_operator=300
|
||||||
|
|
||||||
|
# The penalty for splitting a list comprehension or generator
|
||||||
|
# expression.
|
||||||
|
split_penalty_comprehension=80
|
||||||
|
|
||||||
|
# The penalty for characters over the column limit.
|
||||||
|
split_penalty_excess_character=7000
|
||||||
|
|
||||||
|
# The penalty incurred by adding a line split to the unwrapped line. The
|
||||||
|
# more line splits added the higher the penalty.
|
||||||
|
split_penalty_for_added_line_split=30
|
||||||
|
|
||||||
|
# The penalty of splitting a list of "import as" names. For example:
|
||||||
|
#
|
||||||
|
# from a_very_long_or_indented_module_name_yada_yad import (long_argument_1,
|
||||||
|
# long_argument_2,
|
||||||
|
# long_argument_3)
|
||||||
|
#
|
||||||
|
# would reformat to something like:
|
||||||
|
#
|
||||||
|
# from a_very_long_or_indented_module_name_yada_yad import (
|
||||||
|
# long_argument_1, long_argument_2, long_argument_3)
|
||||||
|
split_penalty_import_names=0
|
||||||
|
|
||||||
|
# The penalty of splitting the line around the 'and' and 'or'
|
||||||
|
# operators.
|
||||||
|
split_penalty_logical_operator=300
|
||||||
|
|
||||||
|
# Use the Tab character for indentation.
|
||||||
|
use_tabs=False
|
||||||
|
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from binascii import unhexlify
|
from binascii import unhexlify
|
||||||
from enum import Enum
|
|
||||||
from validitysensor.flash import read_flash
|
|
||||||
from validitysensor.sensor import *
|
|
||||||
from validitysensor import init
|
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from usb import core as usb_core
|
|
||||||
|
|
||||||
|
from validitysensor import init
|
||||||
|
from validitysensor.sensor import glow_start_scan, glow_end_scan
|
||||||
|
from validitysensor.tls import tls
|
||||||
|
from validitysensor.util import assert_status
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if os.geteuid() != 0:
|
if os.geteuid() != 0:
|
||||||
|
|
@ -23,10 +21,9 @@ if __name__ == "__main__":
|
||||||
glow_end_scan()
|
glow_end_scan()
|
||||||
sleep(0.05)
|
sleep(0.05)
|
||||||
|
|
||||||
led_script = unhexlify(
|
led_script = unhexlify('39ff100000ff03000001ff002000000000ffff0000ffff0000ff03000001ff00'
|
||||||
'39ff100000ff03000001ff002000000000ffff0000ffff0000ff03000001ff00' \
|
'200000000000000000ffff0000ff03000001ff002000000000ffff0000000000'
|
||||||
'200000000000000000ffff0000ff03000001ff002000000000ffff0000000000' \
|
'0000000000000000000000000000000000000000000000000000000000000000'
|
||||||
'0000000000000000000000000000000000000000000000000000000000000000' \
|
'0000000000000000000000000000000000000000000000000000000000')
|
||||||
'0000000000000000000000000000000000000000000000000000000000')
|
|
||||||
|
|
||||||
assert_status(tls.app(led_script))
|
assert_status(tls.app(led_script))
|
||||||
|
|
|
||||||
|
|
@ -20,17 +20,17 @@
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import shutil
|
from enum import Enum
|
||||||
|
|
||||||
from enum import Enum, auto
|
|
||||||
from time import sleep
|
|
||||||
from usb import core as usb_core
|
from usb import core as usb_core
|
||||||
|
|
||||||
python_validity_data='/usr/share/python-validity/'
|
python_validity_data = '/usr/share/python-validity/'
|
||||||
|
|
||||||
|
|
||||||
# FIXME: supported usb ids are duplicated in usb.py
|
# FIXME: supported usb ids are duplicated in usb.py
|
||||||
class VFS(Enum):
|
class VFS(Enum):
|
||||||
|
|
@ -38,6 +38,7 @@ class VFS(Enum):
|
||||||
DEV_97 = (0x138a, 0x0097)
|
DEV_97 = (0x138a, 0x0097)
|
||||||
DEV_9a = (0x06cb, 0x009a)
|
DEV_9a = (0x06cb, 0x009a)
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_URIS = {
|
DEFAULT_URIS = {
|
||||||
VFS.DEV_90: {
|
VFS.DEV_90: {
|
||||||
'driver': 'https://download.lenovo.com/pccbbs/mobiles/n1cgn08w.exe',
|
'driver': 'https://download.lenovo.com/pccbbs/mobiles/n1cgn08w.exe',
|
||||||
|
|
@ -76,15 +77,12 @@ def download_and_extract_fw(dev_type, fwdir, fwuri=None):
|
||||||
with open(fwarchive, 'wb') as out_file:
|
with open(fwarchive, 'wb') as out_file:
|
||||||
out_file.write(response.read())
|
out_file.write(response.read())
|
||||||
|
|
||||||
subprocess.check_call(['innoextract',
|
subprocess.check_call([
|
||||||
'--output-dir', fwdir,
|
'innoextract', '--output-dir', fwdir, '--include', fwname, '--collisions', 'overwrite',
|
||||||
'--include', fwname,
|
|
||||||
'--collisions', 'overwrite',
|
|
||||||
fwarchive
|
fwarchive
|
||||||
])
|
])
|
||||||
|
|
||||||
fwpath = subprocess.check_output([
|
fwpath = subprocess.check_output(['find', fwdir, '-name', fwname]).decode('utf-8').strip()
|
||||||
'find', fwdir, '-name', fwname]).decode('utf-8').strip()
|
|
||||||
print('Found firmware at {}'.format(fwpath))
|
print('Found firmware at {}'.format(fwpath))
|
||||||
|
|
||||||
if not fwpath:
|
if not fwpath:
|
||||||
|
|
@ -92,6 +90,7 @@ def download_and_extract_fw(dev_type, fwdir, fwuri=None):
|
||||||
|
|
||||||
return fwpath
|
return fwpath
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('--driver-uri')
|
parser.add_argument('--driver-uri')
|
||||||
|
|
@ -111,8 +110,7 @@ if __name__ == "__main__":
|
||||||
raise Exception('No supported validity device found')
|
raise Exception('No supported validity device found')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subprocess.check_call(['innoextract', '--version'],
|
subprocess.check_call(['innoextract', '--version'], stdout=subprocess.DEVNULL)
|
||||||
stdout=subprocess.DEVNULL)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print('Impossible to run innoextract: {}'.format(e))
|
print('Impossible to run innoextract: {}'.format(e))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import logging
|
||||||
|
import logging.handlers
|
||||||
import os
|
import os
|
||||||
import pwd
|
import pwd
|
||||||
import re
|
import re
|
||||||
|
|
@ -16,21 +18,18 @@ import dbus
|
||||||
import dbus.mainloop.glib
|
import dbus.mainloop.glib
|
||||||
import dbus.service
|
import dbus.service
|
||||||
import yaml
|
import yaml
|
||||||
|
from gi.repository import GLib
|
||||||
from usb import core as usb_core
|
from usb import core as usb_core
|
||||||
|
|
||||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
|
||||||
from gi.repository import GLib
|
|
||||||
import logging
|
|
||||||
import logging.handlers
|
|
||||||
|
|
||||||
from validitysensor import init
|
from validitysensor import init
|
||||||
from validitysensor.tls import tls
|
|
||||||
from validitysensor.usb import usb
|
|
||||||
from validitysensor.sid import sid_from_string
|
|
||||||
from validitysensor.db import subtype_to_string, db, SidIdentity, User
|
from validitysensor.db import subtype_to_string, db, SidIdentity, User
|
||||||
from validitysensor.sensor import sensor, RebootException
|
from validitysensor.sensor import sensor, RebootException
|
||||||
|
from validitysensor.sid import sid_from_string
|
||||||
|
from validitysensor.tls import tls
|
||||||
|
from validitysensor.usb import usb
|
||||||
from validitysensor.winbio_constants import finger_ids
|
from validitysensor.winbio_constants import finger_ids
|
||||||
|
|
||||||
|
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||||
GLib.threads_init()
|
GLib.threads_init()
|
||||||
|
|
||||||
INTERFACE_NAME = 'io.github.uunicorn.Fprint.Device'
|
INTERFACE_NAME = 'io.github.uunicorn.Fprint.Device'
|
||||||
|
|
@ -64,9 +63,7 @@ class Device(dbus.service.Object):
|
||||||
"""Resolve user name to database object"""
|
"""Resolve user name to database object"""
|
||||||
return db.lookup_user(self.user2identity(user))
|
return db.lookup_user(self.user2identity(user))
|
||||||
|
|
||||||
@dbus.service.method(dbus_interface=INTERFACE_NAME,
|
@dbus.service.method(dbus_interface=INTERFACE_NAME, in_signature="s", out_signature="as")
|
||||||
in_signature="s",
|
|
||||||
out_signature="as")
|
|
||||||
def ListEnrolledFingers(self, user):
|
def ListEnrolledFingers(self, user):
|
||||||
try:
|
try:
|
||||||
logging.debug('In ListEnrolledFingers %s' % user)
|
logging.debug('In ListEnrolledFingers %s' % user)
|
||||||
|
|
@ -82,9 +79,7 @@ class Device(dbus.service.Object):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
@dbus.service.method(dbus_interface=INTERFACE_NAME,
|
@dbus.service.method(dbus_interface=INTERFACE_NAME, in_signature='s', out_signature='')
|
||||||
in_signature='s',
|
|
||||||
out_signature='')
|
|
||||||
def DeleteEnrolledFingers(self, user):
|
def DeleteEnrolledFingers(self, user):
|
||||||
logging.debug('In DeleteEnrolledFingers %s' % user)
|
logging.debug('In DeleteEnrolledFingers %s' % user)
|
||||||
usr = self.user2record(user)
|
usr = self.user2record(user)
|
||||||
|
|
@ -94,9 +89,7 @@ class Device(dbus.service.Object):
|
||||||
|
|
||||||
db.del_record(usr.dbid)
|
db.del_record(usr.dbid)
|
||||||
|
|
||||||
@dbus.service.method(dbus_interface=INTERFACE_NAME,
|
@dbus.service.method(dbus_interface=INTERFACE_NAME, in_signature='ss', out_signature='')
|
||||||
in_signature='ss',
|
|
||||||
out_signature='')
|
|
||||||
def VerifyStart(self, user, finger):
|
def VerifyStart(self, user, finger):
|
||||||
logging.debug('In VerifyStart for %s, %s' % (user, finger))
|
logging.debug('In VerifyStart for %s, %s' % (user, finger))
|
||||||
|
|
||||||
|
|
@ -130,15 +123,11 @@ class Device(dbus.service.Object):
|
||||||
thread.daemon = True
|
thread.daemon = True
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
@dbus.service.method(dbus_interface=INTERFACE_NAME,
|
@dbus.service.method(dbus_interface=INTERFACE_NAME, in_signature='', out_signature='')
|
||||||
in_signature='',
|
|
||||||
out_signature='')
|
|
||||||
def Cancel(self):
|
def Cancel(self):
|
||||||
sensor.cancel()
|
sensor.cancel()
|
||||||
|
|
||||||
@dbus.service.method(dbus_interface=INTERFACE_NAME,
|
@dbus.service.method(dbus_interface=INTERFACE_NAME, in_signature='ss', out_signature='')
|
||||||
in_signature='ss',
|
|
||||||
out_signature='')
|
|
||||||
def EnrollStart(self, user, finger_name):
|
def EnrollStart(self, user, finger_name):
|
||||||
logging.debug('In EnrollStart %s for %s' % (finger_name, user))
|
logging.debug('In EnrollStart %s for %s' % (finger_name, user))
|
||||||
|
|
||||||
|
|
@ -169,11 +158,9 @@ class Device(dbus.service.Object):
|
||||||
logging.exception(e)
|
logging.exception(e)
|
||||||
self.EnrollStatus('enroll-failed', True)
|
self.EnrollStatus('enroll-failed', True)
|
||||||
|
|
||||||
if index == None:
|
if index is None:
|
||||||
logging.exception(
|
logging.exception('Unknown finger name passed to enroll? ' + finger_name + ' (' +
|
||||||
'Unknown finger name passed to enroll? ' +
|
winbio_name + ')')
|
||||||
finger_name + ' (' + winbio_name + ')'
|
|
||||||
)
|
|
||||||
self.EnrollStatus('enroll-failed', True)
|
self.EnrollStatus('enroll-failed', True)
|
||||||
else:
|
else:
|
||||||
thread = Thread(target=run)
|
thread = Thread(target=run)
|
||||||
|
|
@ -192,9 +179,7 @@ class Device(dbus.service.Object):
|
||||||
def EnrollStatus(self, result, done):
|
def EnrollStatus(self, result, done):
|
||||||
logging.debug('EnrollStatus')
|
logging.debug('EnrollStatus')
|
||||||
|
|
||||||
@dbus.service.method(dbus_interface=INTERFACE_NAME,
|
@dbus.service.method(dbus_interface=INTERFACE_NAME, in_signature='s', out_signature='s')
|
||||||
in_signature='s',
|
|
||||||
out_signature='s')
|
|
||||||
def RunCmd(self, cmd):
|
def RunCmd(self, cmd):
|
||||||
logging.debug('RunCmd')
|
logging.debug('RunCmd')
|
||||||
return hexlify(tls.app(unhexlify(cmd))).decode()
|
return hexlify(tls.app(unhexlify(cmd))).decode()
|
||||||
|
|
@ -228,7 +213,10 @@ def main():
|
||||||
parser = argparse.ArgumentParser('Open fprintd DBus service')
|
parser = argparse.ArgumentParser('Open fprintd DBus service')
|
||||||
parser.add_argument('--debug', help='Enable tracing', action='store_true')
|
parser.add_argument('--debug', help='Enable tracing', action='store_true')
|
||||||
parser.add_argument('--devpath', help='USB device path: usb-<busnum>-<address>')
|
parser.add_argument('--devpath', help='USB device path: usb-<busnum>-<address>')
|
||||||
parser.add_argument('--configpath', default='/etc/python-validity', type=Path, help='Path to config files')
|
parser.add_argument('--configpath',
|
||||||
|
default='/etc/python-validity',
|
||||||
|
type=Path,
|
||||||
|
help='Path to config files')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.debug:
|
if args.debug:
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import argparse
|
|
||||||
import re
|
|
||||||
import dbus
|
|
||||||
import dbus.mainloop.glib
|
|
||||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
|
||||||
from gi.repository import GObject, GLib
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import dbus.mainloop.glib
|
||||||
|
|
||||||
|
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||||
|
|
||||||
bus = dbus.SystemBus()
|
bus = dbus.SystemBus()
|
||||||
o = bus.get_object('net.reactivated.Fprint', '/net/reactivated/Fprint/Manager', introspect=False)
|
o = bus.get_object('net.reactivated.Fprint', '/net/reactivated/Fprint/Manager', introspect=False)
|
||||||
o = o.GetDefaultDevice()
|
o = o.GetDefaultDevice()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
from validitysensor.usb import usb
|
|
||||||
from validitysensor.sensor import factory_reset, RebootException
|
from validitysensor.sensor import factory_reset, RebootException
|
||||||
|
from validitysensor.usb import usb
|
||||||
|
|
||||||
try:
|
try:
|
||||||
usb.open()
|
usb.open()
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,8 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import argparse
|
|
||||||
import re
|
|
||||||
import dbus
|
|
||||||
import dbus.mainloop.glib
|
import dbus.mainloop.glib
|
||||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
|
||||||
from gi.repository import GObject, GLib
|
|
||||||
|
|
||||||
import pwd
|
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||||
|
|
||||||
bus = dbus.SystemBus()
|
bus = dbus.SystemBus()
|
||||||
o = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
|
o = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
|
||||||
|
|
@ -16,10 +11,10 @@ ls = o.ListNames()
|
||||||
for n in ls:
|
for n in ls:
|
||||||
if n[0] != ':':
|
if n[0] != ':':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
pid = o.GetConnectionUnixProcessID(n)
|
pid = o.GetConnectionUnixProcessID(n)
|
||||||
|
|
||||||
with open('/proc/%d/cmdline' % pid) as f:
|
with open('/proc/%d/cmdline' % pid) as f:
|
||||||
s=f.read()
|
s = f.read()
|
||||||
s=s.split('\0')
|
s = s.split('\0')
|
||||||
print('%-10s %-5d %s' % (n, pid, ' '.join(s)))
|
print('%-10s %-5d %s' % (n, pid, ' '.join(s)))
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
import code
|
||||||
|
import logging
|
||||||
|
from binascii import hexlify
|
||||||
|
|
||||||
from validitysensor.tls import tls
|
from validitysensor.tls import tls
|
||||||
from validitysensor.usb import usb
|
from validitysensor.usb import usb
|
||||||
from validitysensor.db import db
|
from validitysensor.db import db
|
||||||
|
|
@ -7,11 +11,10 @@ from validitysensor.sid import *
|
||||||
from validitysensor.init import open as open9x
|
from validitysensor.init import open as open9x
|
||||||
from threading import Condition
|
from threading import Condition
|
||||||
from time import sleep
|
from time import sleep
|
||||||
import logging
|
|
||||||
import code
|
|
||||||
|
|
||||||
#usb.trace_enabled = True
|
# usb.trace_enabled = True
|
||||||
#tls.trace_enabled = True
|
# tls.trace_enabled = True
|
||||||
|
|
||||||
|
|
||||||
def identify():
|
def identify():
|
||||||
def update_cb(e):
|
def update_cb(e):
|
||||||
|
|
@ -21,6 +24,7 @@ def identify():
|
||||||
|
|
||||||
print('Got finger %x for user recordid %d. Hash: %s' % (subtype, usrid, hexlify(hsh).decode()))
|
print('Got finger %x for user recordid %d. Hash: %s' % (subtype, usrid, hexlify(hsh).decode()))
|
||||||
|
|
||||||
|
|
||||||
def enroll(sid, finger):
|
def enroll(sid, finger):
|
||||||
def update_cb(x, e):
|
def update_cb(x, e):
|
||||||
if e is not None:
|
if e is not None:
|
||||||
|
|
@ -31,4 +35,3 @@ def enroll(sid, finger):
|
||||||
recid = sensor.enroll(sid, finger, update_cb)
|
recid = sensor.enroll(sid, finger, update_cb)
|
||||||
|
|
||||||
print('Created a finger record with dbid %d' % recid)
|
print('Created a finger record with dbid %d' % recid)
|
||||||
|
|
||||||
|
|
|
||||||
39
setup.py
39
setup.py
|
|
@ -3,26 +3,19 @@
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
setup(name='python-validity',
|
setup(name='python-validity',
|
||||||
version='0.9',
|
version='0.9',
|
||||||
py_modules = [],
|
py_modules=[],
|
||||||
packages=['validitysensor'],
|
packages=['validitysensor'],
|
||||||
scripts=[
|
scripts=[
|
||||||
'bin/validity-led-dance',
|
'bin/validity-led-dance',
|
||||||
'bin/validity-sensors-firmware',
|
'bin/validity-sensors-firmware',
|
||||||
],
|
],
|
||||||
install_requires=[
|
install_requires=['cryptography >= 2.1.4', 'pyusb >= 1.0.0', 'pyyaml >= 3.12'],
|
||||||
'cryptography >= 2.1.4',
|
data_files=[
|
||||||
'pyusb >= 1.0.0',
|
('share/dbus-1/system.d/', ['dbus_service/io.github.uunicorn.Fprint.conf']),
|
||||||
'pyyaml >= 3.12'
|
('lib/python-validity/', ['dbus_service/dbus-service']),
|
||||||
],
|
('share/python-validity/playground/', [
|
||||||
data_files=[
|
'scripts/dbus-cmd.py', 'scripts/lsdbus.py', 'scripts/factory-reset.py',
|
||||||
('share/dbus-1/system.d/', ['dbus_service/io.github.uunicorn.Fprint.conf']),
|
'scripts/prototype.py'
|
||||||
('lib/python-validity/', ['dbus_service/dbus-service']),
|
]),
|
||||||
('share/python-validity/playground/', [
|
])
|
||||||
'scripts/dbus-cmd.py',
|
|
||||||
'scripts/lsdbus.py',
|
|
||||||
'scripts/factory-reset.py',
|
|
||||||
'scripts/prototype.py'
|
|
||||||
]),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,4 @@
|
||||||
from enum import Enum, auto
|
def __load_blob(blob: str) -> bytes:
|
||||||
|
|
||||||
class Blobs(Enum):
|
|
||||||
init_hardcoded = auto()
|
|
||||||
init_hardcoded_clean_slate = auto()
|
|
||||||
reset_blob = auto()
|
|
||||||
db_write_enable = auto()
|
|
||||||
|
|
||||||
|
|
||||||
def __load_blob(blob):
|
|
||||||
from .usb import usb
|
from .usb import usb
|
||||||
|
|
||||||
if usb.usb_dev().idVendor == 0x138a:
|
if usb.usb_dev().idVendor == 0x138a:
|
||||||
|
|
@ -22,6 +13,8 @@ def __load_blob(blob):
|
||||||
globals()[blob] = getattr(blobs, blob)
|
globals()[blob] = getattr(blobs, blob)
|
||||||
return globals()[blob]
|
return globals()[blob]
|
||||||
|
|
||||||
for p in dir(Blobs):
|
|
||||||
if isinstance(getattr(Blobs, p), Blobs):
|
init_hardcoded = lambda: __load_blob('init_hardcoded')
|
||||||
globals()[p] = lambda bname=p: __load_blob(bname)
|
init_hardcoded_clean_slate = lambda: __load_blob('init_hardcoded_clean_slate')
|
||||||
|
reset_blob = lambda: __load_blob('reset_blob')
|
||||||
|
db_write_enable = lambda: __load_blob('db_write_enable')
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
from .util import unhex
|
from .util import unhex
|
||||||
|
|
||||||
init_hardcoded=unhex('''
|
init_hardcoded = unhex('''
|
||||||
06020000013917b3dda91383b5bcac64fa4ad35dce96570a9d2d974b80926a431f9cd46248980a263c6fcef6a82839a90b59ac590848859
|
06020000013917b3dda91383b5bcac64fa4ad35dce96570a9d2d974b80926a431f9cd46248980a263c6fcef6a82839a90b59ac590848859
|
||||||
afac817b7d53bf51cd3205c1b8f43048be8253c3bd247937c837aca8b18d3cc8ee8c8971ac4f688813cf3d8550d71496985b7ec07ff2dc7
|
afac817b7d53bf51cd3205c1b8f43048be8253c3bd247937c837aca8b18d3cc8ee8c8971ac4f688813cf3d8550d71496985b7ec07ff2dc7
|
||||||
896d330fdab263a0ee433a5c4bc910439d1c6161853feb03f5502209502e7308beb7919473cfe69f422c30502d226a4d0a34d96c8c77956
|
896d330fdab263a0ee433a5c4bc910439d1c6161853feb03f5502209502e7308beb7919473cfe69f422c30502d226a4d0a34d96c8c77956
|
||||||
|
|
@ -13,9 +12,9 @@ e024ca6b9a48332c1a69a5a3fdd24b964cf7e7c55229bb0b48a6e339eb2c42d07ec850a4ee780660
|
||||||
b3d5cad8d5bd7cea37e58a31307a6d50e6ae379a53f1366678c0741a3d872b8dcfefa7f63128dc8245
|
b3d5cad8d5bd7cea37e58a31307a6d50e6ae379a53f1366678c0741a3d872b8dcfefa7f63128dc8245
|
||||||
''')
|
''')
|
||||||
|
|
||||||
init_hardcoded_clean_slate=unhex('')
|
init_hardcoded_clean_slate = unhex('')
|
||||||
|
|
||||||
reset_blob=unhex('''
|
reset_blob = unhex('''
|
||||||
0602000001d6123241376f110935a7ae38b614ced9952eaa38e2984842d0552d984b69ab5c1a70175513319970225d9ca25be063a7d70a2
|
0602000001d6123241376f110935a7ae38b614ced9952eaa38e2984842d0552d984b69ab5c1a70175513319970225d9ca25be063a7d70a2
|
||||||
9dff803240c099ba5386910b69c3b7ca8d0b26ec9a5684fe92af9c6d8068ace0954eb8582adc6208aa6c116b1778ff531dd2b6817a10d66
|
9dff803240c099ba5386910b69c3b7ca8d0b26ec9a5684fe92af9c6d8068ace0954eb8582adc6208aa6c116b1778ff531dd2b6817a10d66
|
||||||
7e0385d18ac7ccb47eb67f1f54b5b94c84d65529c6e9fe9039218ae9cde123f38ffa52a953ed589d0d8bb48680aeea6544b7ceedbea3216
|
7e0385d18ac7ccb47eb67f1f54b5b94c84d65529c6e9fe9039218ae9cde123f38ffa52a953ed589d0d8bb48680aeea6544b7ceedbea3216
|
||||||
|
|
@ -226,7 +225,7 @@ f72aea07e183577f591a081845ea340797b79c6c8742e8826a6d7df773ec8564025fbb570bfbc001
|
||||||
a5d4483f1
|
a5d4483f1
|
||||||
''')
|
''')
|
||||||
|
|
||||||
db_write_enable=unhex('''
|
db_write_enable = unhex('''
|
||||||
06020000015ddf5d76a8e3bab8b10d9f82f0b31652d5b208dff1d20745b7c5442e09db880c80ca103d5b2071d8bdcaab452b900d1785be2
|
06020000015ddf5d76a8e3bab8b10d9f82f0b31652d5b208dff1d20745b7c5442e09db880c80ca103d5b2071d8bdcaab452b900d1785be2
|
||||||
de478669e72a9d082273f0f6176b700ffb65a026af052e76de5f9e247e994bed7c79e34815b465a8070a76da7d365525d7285dfb152d24c
|
de478669e72a9d082273f0f6176b700ffb65a026af052e76de5f9e247e994bed7c79e34815b465a8070a76da7d365525d7285dfb152d24c
|
||||||
732a471f031d22ebb67d6e27bfff74b3ab1c4780461a460c0ea5710fbd32ab59a6ca9ca3e3e24264640b15245a6c48b6bd20c6848c2307e
|
732a471f031d22ebb67d6e27bfff74b3ab1c4780461a460c0ea5710fbd32ab59a6ca9ca3e3e24264640b15245a6c48b6bd20c6848c2307e
|
||||||
|
|
@ -262,7 +261,7 @@ a2da95eb8445a6381f3941917bed7fcf01ab199228eadd1968847e4b9a40022d2b0ec68318abf97c
|
||||||
''')
|
''')
|
||||||
|
|
||||||
# FIXME this must be very specific to a particular device and constructed on the fly from multiple hardcoded tables:
|
# FIXME this must be very specific to a particular device and constructed on the fly from multiple hardcoded tables:
|
||||||
identify_prg=unhex('''
|
identify_prg = unhex('''
|
||||||
02980000002300000020000800002000800000010032007000000000802020050024200000502077362820010030200100082170000c210
|
02980000002300000020000800002000800000010032007000000000802020050024200000502077362820010030200100082170000c210
|
||||||
000482102004c210000582000005c20000060200000682005006c20012970200121742001887820018084202000942001809c200902a020
|
000482102004c210000582000005c20000060200000682005006c20012970200121742001887820018084202000942001809c200902a020
|
||||||
0b19b4200000b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc2
|
0b19b4200000b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc2
|
||||||
|
|
@ -295,7 +294,7 @@ c1e1e1c221f201d21201e1c1f34242221201f20221f201e241e241d2020221e2420231d221e211e1
|
||||||
''')
|
''')
|
||||||
|
|
||||||
# The following blob has only 1 byte difference from the above
|
# The following blob has only 1 byte difference from the above
|
||||||
enroll_prg=unhex('''
|
enroll_prg = unhex('''
|
||||||
02980000002300000020000800002000800000010032007000000000802020050024200000502077362820010030200100082170000c210
|
02980000002300000020000800002000800000010032007000000000802020050024200000502077362820010030200100082170000c210
|
||||||
000482102004c210000582000005c20000060200000682005006c20012970200121742001887820018084202000942001809c200902a020
|
000482102004c210000582000005c20000060200000682005006c20012970200121742001887820018084202000942001809c200902a020
|
||||||
0b19b4200000b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc2
|
0b19b4200000b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc2
|
||||||
|
|
@ -327,7 +326,7 @@ c1e1e1c221f201d21201e1c1f34242221201f20221f201e241e241d2020221e2420231d221e211e1
|
||||||
81808180818081808180818081808180818081808080808080808080807f807f807f807f7f7e7e
|
81808180818081808180818081808180818081808080808080808080807f807f807f807f7f7e7e
|
||||||
''')
|
''')
|
||||||
|
|
||||||
calibrate_prg=unhex('''
|
calibrate_prg = unhex('''
|
||||||
0298006103230000002000080000200080000001003200700000000080202005002420000050207736282
|
0298006103230000002000080000200080000001003200700000000080202005002420000050207736282
|
||||||
0010030200100082170000c210000482102004c210000582000005c20000060200000682005006c200129
|
0010030200100082170000c210000482102004c210000582000005c20000060200000682005006c200129
|
||||||
70200121742001887820018084202000942001809c200902a0200b19b4200000b8203b04bc201400c0200
|
70200121742001887820018084202000942001809c200902a0200b19b4200000b8203b04bc201400c0200
|
||||||
|
|
@ -365,4 +364,3 @@ c2d182e1e30182e1c321d341d341e321c301e1e241e201f201d1c321a301e1c211e21341f1e20202
|
||||||
8080808180818081808080818081808180818081808180808081808180818081808180818081808180818
|
8080808180818081808080818081808180818081808180808081808180818081808180818081808180818
|
||||||
0818081808180818081808080808080808080807f807f807f807f7f7e7e
|
0818081808180818081808080808080808080807f807f807f807f7f7e7e
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
from .util import unhex
|
from .util import unhex
|
||||||
|
|
||||||
init_hardcoded=unhex('''
|
init_hardcoded = unhex('''
|
||||||
06020000014a231406e5542fc6dc3b1aedebe68f55596ad3ca13f6e019994c6f71672fff756fbde0511d09d45978b12ba415b3694a0e763
|
06020000014a231406e5542fc6dc3b1aedebe68f55596ad3ca13f6e019994c6f71672fff756fbde0511d09d45978b12ba415b3694a0e763
|
||||||
48c8cfe9dbb9abf86813fc0c67c1005519a6f87360c2fb3e12bd0a9e012b06d9f5c9b44ccc6645b0fbd47afe45c8c874fcb88fbfd18fb7a
|
48c8cfe9dbb9abf86813fc0c67c1005519a6f87360c2fb3e12bd0a9e012b06d9f5c9b44ccc6645b0fbd47afe45c8c874fcb88fbfd18fb7a
|
||||||
9b3241351f256acce689f9586a52b01f8fdcb66cdf3b340b1f9f386d58ca24fdfcdfbcebefb5f3a3c2a08357721040235a20ce1ee2f4f78
|
9b3241351f256acce689f9586a52b01f8fdcb66cdf3b340b1f9f386d58ca24fdfcdfbcebefb5f3a3c2a08357721040235a20ce1ee2f4f78
|
||||||
|
|
@ -15,7 +14,7 @@ f3135c5e78820e36653fa3db535f57c71897242939d7da50f81070ce9ab81c61af6ac29a6c6c4a5d
|
||||||
2999d1c0e7acf67e598696cd58cc4bdb1b7c037ee9a085f784c4
|
2999d1c0e7acf67e598696cd58cc4bdb1b7c037ee9a085f784c4
|
||||||
''')
|
''')
|
||||||
|
|
||||||
init_hardcoded_clean_slate=unhex('''
|
init_hardcoded_clean_slate = unhex('''
|
||||||
06020000012c40c9d271378bc0912ef5dced69bd81b7fc16972c7b46e621af54a00e2cc6baca6eb83ea30222dfc6c925262006ae93412ea
|
06020000012c40c9d271378bc0912ef5dced69bd81b7fc16972c7b46e621af54a00e2cc6baca6eb83ea30222dfc6c925262006ae93412ea
|
||||||
cf482f2034ee7b13297474b7e1e91f279cac2ccb7195443e4dd3328cfd292ade073fcc2eaa8f07b77231130ba997f921b9be7b4fb6cc691
|
cf482f2034ee7b13297474b7e1e91f279cac2ccb7195443e4dd3328cfd292ade073fcc2eaa8f07b77231130ba997f921b9be7b4fb6cc691
|
||||||
0d2976b3e050913b27dbe73afd6e964260b9435ebab5117e71f7cb68464d4b6f8afc7e1a421f671f5854a1d0c8ab93ed3b88b2bc1a42875
|
0d2976b3e050913b27dbe73afd6e964260b9435ebab5117e71f7cb68464d4b6f8afc7e1a421f671f5854a1d0c8ab93ed3b88b2bc1a42875
|
||||||
|
|
@ -32,7 +31,7 @@ b4c74c39900830abc6906a1004bef1b5b7dbbbeb5ec1b22604ac86429b9f56511b746a7124c449b8
|
||||||
aa41249faeef4d838e280cb5d6fc19cfe86c75f
|
aa41249faeef4d838e280cb5d6fc19cfe86c75f
|
||||||
''')
|
''')
|
||||||
|
|
||||||
reset_blob=unhex('''
|
reset_blob = unhex('''
|
||||||
06020000018772bd56dd58d64023e1745f7c253a49b32dd6a02bc32347195b6763bfcc23c9e0beb0c5809e06a5628629f28c4048530a5cd
|
06020000018772bd56dd58d64023e1745f7c253a49b32dd6a02bc32347195b6763bfcc23c9e0beb0c5809e06a5628629f28c4048530a5cd
|
||||||
df6f48391ea0c2cb5a7ffe93ef04c8b4dad584117e65aac085c25062a0f12a8ee432c7ecbb6613c28b743e4a75e382afc6b8037e342d466
|
df6f48391ea0c2cb5a7ffe93ef04c8b4dad584117e65aac085c25062a0f12a8ee432c7ecbb6613c28b743e4a75e382afc6b8037e342d466
|
||||||
7b66a73691edc6b25698c15e78d9d67f7cc56274e99e6b7bb5fba32dd42d74dfa672f414c4a29302b30a202d00a2571d2a884169e82106c
|
7b66a73691edc6b25698c15e78d9d67f7cc56274e99e6b7bb5fba32dd42d74dfa672f414c4a29302b30a202d00a2571d2a884169e82106c
|
||||||
|
|
@ -252,7 +251,7 @@ f20332657d2ca6728b9865a6bfdc9a9055a6ab86cb782307c2c0255525884bf8060f8aed7ec034f3
|
||||||
20f8bb8d94784228934870046f60ac937af4957c9414bcc33895fcc183062be4e4bff56f9c89838ead8e433dc604536938
|
20f8bb8d94784228934870046f60ac937af4957c9414bcc33895fcc183062be4e4bff56f9c89838ead8e433dc604536938
|
||||||
''')
|
''')
|
||||||
|
|
||||||
db_write_enable=unhex('''
|
db_write_enable = unhex('''
|
||||||
0602000001f48001074892b6c57deb7889b5ebf86bc3040f6d91ff1f68765f046591184be08cf36c154b7ec5368139d0f9532382214379a
|
0602000001f48001074892b6c57deb7889b5ebf86bc3040f6d91ff1f68765f046591184be08cf36c154b7ec5368139d0f9532382214379a
|
||||||
ff3ffbfe4659e2f274e864bd0ad660f99e21da2bab677dbfa907a66ce110c180d2ddc5dfe40b8ed975cbedffc11631f12f8bd646a0ee82d
|
ff3ffbfe4659e2f274e864bd0ad660f99e21da2bab677dbfa907a66ce110c180d2ddc5dfe40b8ed975cbedffc11631f12f8bd646a0ee82d
|
||||||
44d2a6c1ec9cfbd40f485cb3d9124376b97b4a3349b0a730adda626d8ac28ec20e886aab1b8851deee3431c4d89c8bb3e787eaa9c0323df
|
44d2a6c1ec9cfbd40f485cb3d9124376b97b4a3349b0a730adda626d8ac28ec20e886aab1b8851deee3431c4d89c8bb3e787eaa9c0323df
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
from .util import unhex
|
from .util import unhex
|
||||||
|
|
||||||
init_hardcoded=unhex('''
|
init_hardcoded = unhex('''
|
||||||
06020000014a231406e5542fc6dc3b1aedebe68f55596ad3ca13f6e019994c6f71672fff756fbde0511d09d45978b12ba415b3694a0e763
|
06020000014a231406e5542fc6dc3b1aedebe68f55596ad3ca13f6e019994c6f71672fff756fbde0511d09d45978b12ba415b3694a0e763
|
||||||
48c8cfe9dbb9abf86813fc0c67c1005519a6f87360c2fb3e12bd0a9e012b06d9f5c9b44ccc6645b0fbd47afe45c8c874fcb88fbfd18fb7a
|
48c8cfe9dbb9abf86813fc0c67c1005519a6f87360c2fb3e12bd0a9e012b06d9f5c9b44ccc6645b0fbd47afe45c8c874fcb88fbfd18fb7a
|
||||||
9b3241351f256acce689f9586a52b01f8fdcb66cdf3b340b1f9f386d58ca24fdfcdfbcebefb5f3a3c2a08357721040235a20ce1ee2f4f78
|
9b3241351f256acce689f9586a52b01f8fdcb66cdf3b340b1f9f386d58ca24fdfcdfbcebefb5f3a3c2a08357721040235a20ce1ee2f4f78
|
||||||
|
|
@ -15,7 +14,7 @@ f3135c5e78820e36653fa3db535f57c71897242939d7da50f81070ce9ab81c61af6ac29a6c6c4a5d
|
||||||
2999d1c0e7acf67e598696cd58cc4bdb1b7c037ee9a085f784c4
|
2999d1c0e7acf67e598696cd58cc4bdb1b7c037ee9a085f784c4
|
||||||
''')
|
''')
|
||||||
|
|
||||||
init_hardcoded_clean_slate=unhex('''
|
init_hardcoded_clean_slate = unhex('''
|
||||||
06020000012c40c9d271378bc0912ef5dced69bd81b7fc16972c7b46e621af54a00e2cc6baca6eb83ea30222dfc6c925262006ae93412ea
|
06020000012c40c9d271378bc0912ef5dced69bd81b7fc16972c7b46e621af54a00e2cc6baca6eb83ea30222dfc6c925262006ae93412ea
|
||||||
cf482f2034ee7b13297474b7e1e91f279cac2ccb7195443e4dd3328cfd292ade073fcc2eaa8f07b77231130ba997f921b9be7b4fb6cc691
|
cf482f2034ee7b13297474b7e1e91f279cac2ccb7195443e4dd3328cfd292ade073fcc2eaa8f07b77231130ba997f921b9be7b4fb6cc691
|
||||||
0d2976b3e050913b27dbe73afd6e964260b9435ebab5117e71f7cb68464d4b6f8afc7e1a421f671f5854a1d0c8ab93ed3b88b2bc1a42875
|
0d2976b3e050913b27dbe73afd6e964260b9435ebab5117e71f7cb68464d4b6f8afc7e1a421f671f5854a1d0c8ab93ed3b88b2bc1a42875
|
||||||
|
|
@ -32,7 +31,7 @@ b4c74c39900830abc6906a1004bef1b5b7dbbbeb5ec1b22604ac86429b9f56511b746a7124c449b8
|
||||||
aa41249faeef4d838e280cb5d6fc19cfe86c75f
|
aa41249faeef4d838e280cb5d6fc19cfe86c75f
|
||||||
''')
|
''')
|
||||||
|
|
||||||
reset_blob=unhex('''
|
reset_blob = unhex('''
|
||||||
06020000018772bd56dd58d64023e1745f7c253a49b32dd6a02bc32347195b6763bfcc23c9e0beb0c5809e06a5628629f28c4048530a5cd
|
06020000018772bd56dd58d64023e1745f7c253a49b32dd6a02bc32347195b6763bfcc23c9e0beb0c5809e06a5628629f28c4048530a5cd
|
||||||
df6f48391ea0c2cb5a7ffe93ef04c8b4dad584117e65aac085c25062a0f12a8ee432c7ecbb6613c28b743e4a75e382afc6b8037e342d466
|
df6f48391ea0c2cb5a7ffe93ef04c8b4dad584117e65aac085c25062a0f12a8ee432c7ecbb6613c28b743e4a75e382afc6b8037e342d466
|
||||||
7b66a73691edc6b25698c15e78d9d67f7cc56274e99e6b7bb5fba32dd42d74dfa672f414c4a29302b30a202d00a2571d2a884169e82106c
|
7b66a73691edc6b25698c15e78d9d67f7cc56274e99e6b7bb5fba32dd42d74dfa672f414c4a29302b30a202d00a2571d2a884169e82106c
|
||||||
|
|
@ -252,7 +251,7 @@ f20332657d2ca6728b9865a6bfdc9a9055a6ab86cb782307c2c0255525884bf8060f8aed7ec034f3
|
||||||
20f8bb8d94784228934870046f60ac937af4957c9414bcc33895fcc183062be4e4bff56f9c89838ead8e433dc604536938
|
20f8bb8d94784228934870046f60ac937af4957c9414bcc33895fcc183062be4e4bff56f9c89838ead8e433dc604536938
|
||||||
''')
|
''')
|
||||||
|
|
||||||
db_write_enable=unhex('''
|
db_write_enable = unhex('''
|
||||||
0602000001f48001074892b6c57deb7889b5ebf86bc3040f6d91ff1f68765f046591184be08cf36c154b7ec5368139d0f9532382214379a
|
0602000001f48001074892b6c57deb7889b5ebf86bc3040f6d91ff1f68765f046591184be08cf36c154b7ec5368139d0f9532382214379a
|
||||||
ff3ffbfe4659e2f274e864bd0ad660f99e21da2bab677dbfa907a66ce110c180d2ddc5dfe40b8ed975cbedffc11631f12f8bd646a0ee82d
|
ff3ffbfe4659e2f274e864bd0ad660f99e21da2bab677dbfa907a66ce110c180d2ddc5dfe40b8ed975cbedffc11631f12f8bd646a0ee82d
|
||||||
44d2a6c1ec9cfbd40f485cb3d9124376b97b4a3349b0a730adda626d8ac28ec20e886aab1b8851deee3431c4d89c8bb3e787eaa9c0323df
|
44d2a6c1ec9cfbd40f485cb3d9124376b97b4a3349b0a730adda626d8ac28ec20e886aab1b8851deee3431c4d89c8bb3e787eaa9c0323df
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,70 @@
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
from .tls import tls
|
|
||||||
from .util import assert_status
|
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
|
from struct import pack, unpack
|
||||||
|
|
||||||
from .blobs import db_write_enable
|
from .blobs import db_write_enable
|
||||||
from .flash import call_cleanups
|
from .flash import call_cleanups
|
||||||
from .sid import *
|
from .sid import SidIdentity, sid_from_bytes
|
||||||
|
from .tls import tls
|
||||||
|
from .util import assert_status
|
||||||
from .winbio_constants import finger_names
|
from .winbio_constants import finger_names
|
||||||
|
|
||||||
class UserStorage():
|
|
||||||
def __init__(self, dbid, name):
|
class UserStorage:
|
||||||
self.dbid=dbid
|
def __init__(self, dbid: int, name: str):
|
||||||
self.name=name
|
self.dbid = dbid
|
||||||
self.users=[]
|
self.name = name
|
||||||
|
self.users = []
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<UserStorage: dbid=%04x name=%s users=%s>' % (self.dbid, repr(self.name), repr(self.users))
|
return '<UserStorage: dbid=%04x name=%s users=%s>' % (self.dbid, repr(
|
||||||
|
self.name), repr(self.users))
|
||||||
|
|
||||||
class User():
|
|
||||||
def __init__(self, dbid, identity):
|
class User:
|
||||||
self.dbid=dbid
|
def __init__(self, dbid: int, identity: str):
|
||||||
self.identity=identity
|
self.dbid = dbid
|
||||||
self.fingers=[]
|
self.identity = identity
|
||||||
|
self.fingers: typing.List[typing.Mapping[str, int]] = []
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<User: dbid=%04x identity=%s fingers=%s>' % (self.dbid, repr(self.identity), repr(self.fingers))
|
return '<User: dbid=%04x identity=%s fingers=%s>' % (self.dbid, repr(
|
||||||
|
self.identity), repr(self.fingers))
|
||||||
|
|
||||||
|
|
||||||
def subtype_to_string(s: int):
|
def subtype_to_string(s: int):
|
||||||
finger_name = finger_names.get(s, None)
|
finger_name = finger_names.get(s, None)
|
||||||
return finger_name or 'Unknown'
|
return finger_name or 'Unknown'
|
||||||
|
|
||||||
def parse_user_storage(rsp):
|
|
||||||
|
def parse_user_storage(rsp: bytes):
|
||||||
rc, = unpack('<H', rsp[:2])
|
rc, = unpack('<H', rsp[:2])
|
||||||
|
|
||||||
if rc == 0x04b3:
|
if rc == 0x04b3:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
assert_status(rsp[:2])
|
assert_status(rsp[:2])
|
||||||
rsp=rsp[2:]
|
rsp = rsp[2:]
|
||||||
|
|
||||||
hdr, rsp = rsp[:8], rsp[8:]
|
hdr, rsp = rsp[:8], rsp[8:]
|
||||||
recid, usercnt, namesz, unknwn = unpack('<HHHH', hdr)
|
recid, usercnt, namesz, unknwn = unpack('<HHHH', hdr)
|
||||||
usrtab, rsp = rsp[:4*usercnt], rsp[4*usercnt:]
|
usrtab, rsp = rsp[:4 * usercnt], rsp[4 * usercnt:]
|
||||||
name, rsp = rsp[:namesz], rsp[namesz:]
|
name, rsp = rsp[:namesz], rsp[namesz:]
|
||||||
|
|
||||||
if len(rsp) > 0:
|
if len(rsp) > 0:
|
||||||
raise Exception('Junk at the end of the storage info response: %s' % rsp.hex())
|
raise Exception('Junk at the end of the storage info response: %s' % rsp.hex())
|
||||||
|
|
||||||
storage=UserStorage(recid, name)
|
storage = UserStorage(recid, name)
|
||||||
|
|
||||||
while len(usrtab) > 0:
|
while len(usrtab) > 0:
|
||||||
rec, usrtab = usrtab[:4], usrtab[4:]
|
rec, usrtab = usrtab[:4], usrtab[4:]
|
||||||
urid, valsz = unpack('<HH', rec)
|
urid, valsz = unpack('<HH', rec)
|
||||||
storage.users += [ { 'dbid': urid, 'valueSize': valsz } ]
|
storage.users += [{'dbid': urid, 'valueSize': valsz}]
|
||||||
|
|
||||||
return storage
|
return storage
|
||||||
|
|
||||||
def parse_identity(b):
|
|
||||||
|
def parse_identity(b: bytes):
|
||||||
t, b = b[:4], b[4:]
|
t, b = b[:4], b[4:]
|
||||||
t, = unpack('<L', t)
|
t, = unpack('<L', t)
|
||||||
|
|
||||||
|
|
@ -65,45 +73,48 @@ def parse_identity(b):
|
||||||
l, = unpack('<L', l)
|
l, = unpack('<L', l)
|
||||||
return sid_from_bytes(b[:l])
|
return sid_from_bytes(b[:l])
|
||||||
|
|
||||||
raise Exception('Don''t know how to handle identity type %d' % t)
|
raise Exception('Don' 't know how to handle identity type %d' % t)
|
||||||
|
|
||||||
|
|
||||||
def parse_user(rsp: bytes):
|
def parse_user(rsp: bytes):
|
||||||
assert_status(rsp[:2])
|
assert_status(rsp[:2])
|
||||||
rsp=rsp[2:]
|
rsp = rsp[2:]
|
||||||
|
|
||||||
hdr, rsp = rsp[:8], rsp[8:]
|
hdr, rsp = rsp[:8], rsp[8:]
|
||||||
recid, fingercnt, unknwn, identitysz = unpack('<HHHH', hdr)
|
recid, fingercnt, unknwn, identitysz = unpack('<HHHH', hdr)
|
||||||
fingertab, rsp = rsp[:8*fingercnt], rsp[8*fingercnt:]
|
fingertab, rsp = rsp[:8 * fingercnt], rsp[8 * fingercnt:]
|
||||||
identity, rsp = rsp[:identitysz], rsp[identitysz:]
|
identity, rsp = rsp[:identitysz], rsp[identitysz:]
|
||||||
|
|
||||||
if len(rsp) > 0:
|
if len(rsp) > 0:
|
||||||
raise Exception('Junk at the end of the user info response: %s' % rsp.hex())
|
raise Exception('Junk at the end of the user info response: %s' % rsp.hex())
|
||||||
|
|
||||||
identity = parse_identity(identity)
|
identity = parse_identity(identity)
|
||||||
user=User(recid, identity)
|
user = User(recid, identity)
|
||||||
|
|
||||||
while len(fingertab) > 0:
|
while len(fingertab) > 0:
|
||||||
rec, fingertab = fingertab[:8], fingertab[8:]
|
rec, fingertab = fingertab[:8], fingertab[8:]
|
||||||
frid, subtype, stgid, valsz = unpack('<HHHH', rec)
|
frid, subtype, stgid, valsz = unpack('<HHHH', rec)
|
||||||
user.fingers += [ { 'dbid': frid, 'subtype': subtype, 'storage': stgid, 'valueSize': valsz } ]
|
user.fingers += [{'dbid': frid, 'subtype': subtype, 'storage': stgid, 'valueSize': valsz}]
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
def identity_to_bytes(identity: str):
|
def identity_to_bytes(identity: str):
|
||||||
if isinstance(identity, SidIdentity):
|
if isinstance(identity, SidIdentity):
|
||||||
b=identity.to_bytes()
|
b = identity.to_bytes()
|
||||||
b = pack('<LL', 3, len(b)) + b
|
b = pack('<LL', 3, len(b)) + b
|
||||||
|
|
||||||
# May not be neccessary, but windows union has a minimum size of 0x4c bytes
|
# May not be neccessary, but windows union has a minimum size of 0x4c bytes
|
||||||
# and search by identity treats same SIDs with different sizes as different keys
|
# and search by identity treats same SIDs with different sizes as different keys
|
||||||
while len(b) < 0x4c:
|
while len(b) < 0x4c:
|
||||||
b += b'\0'
|
b += b'\0'
|
||||||
|
|
||||||
return b
|
return b
|
||||||
else:
|
else:
|
||||||
raise Exception('Don''t know how to handle identity %s' % repr(identity))
|
raise Exception('Don' 't know how to handle identity %s' % repr(identity))
|
||||||
|
|
||||||
class DbRecord():
|
|
||||||
|
class DbRecord:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.dbid = 0
|
self.dbid = 0
|
||||||
self.type = 0
|
self.type = 0
|
||||||
|
|
@ -113,29 +124,24 @@ class DbRecord():
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<DbRecord: dbid=%d type=%d storage=%d value=%s children=%s>' % (
|
return '<DbRecord: dbid=%d type=%d storage=%d value=%s children=%s>' % (
|
||||||
self.dbid,
|
self.dbid, self.type, self.storage, repr(self.value), repr(self.children))
|
||||||
self.type,
|
|
||||||
self.storage,
|
|
||||||
repr(self.value),
|
|
||||||
repr(self.children)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class Db():
|
|
||||||
class Info():
|
class Db:
|
||||||
def __init__(self, total, used, free, records, roots):
|
class Info:
|
||||||
self.total = total # partition size
|
def __init__(self, total: int, used: int, free: int, records: int, roots):
|
||||||
self.used = used # used (not deleted)
|
self.total = total # partition size
|
||||||
self.free = free # unallocated space
|
self.used = used # used (not deleted)
|
||||||
self.records = records # total number, including deleted
|
self.free = free # unallocated space
|
||||||
|
self.records = records # total number, including deleted
|
||||||
self.roots = roots
|
self.roots = roots
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'Db.Info(total=%d, used=%d, free=%d, records=%d, roots=%s)' % (
|
return 'Db.Info(total=%d, used=%d, free=%d, records=%d, roots=%s)' % (
|
||||||
self.total, self.used, self.free, self.records, repr(self.roots))
|
self.total, self.used, self.free, self.records, repr(self.roots))
|
||||||
|
|
||||||
def get_user_storage(self, dbid=0, name=''):
|
def get_user_storage(self, dbid=0, name=''):
|
||||||
name=name.encode()
|
name = name.encode()
|
||||||
|
|
||||||
if len(name) > 0:
|
if len(name) > 0:
|
||||||
name += b'\0'
|
name += b'\0'
|
||||||
|
|
@ -148,15 +154,15 @@ class Db():
|
||||||
def get_storage_data(self):
|
def get_storage_data(self):
|
||||||
stg = self.get_user_storage(name='StgWindsor')
|
stg = self.get_user_storage(name='StgWindsor')
|
||||||
rc = self.get_record_children(stg.dbid).children
|
rc = self.get_record_children(stg.dbid).children
|
||||||
return [i['dbid'] for i in rc if i['type'] == 8] # 8 == "data" type
|
return [i['dbid'] for i in rc if i['type'] == 8] # 8 == "data" type
|
||||||
|
|
||||||
def get_user(self, dbid):
|
def get_user(self, dbid: int):
|
||||||
return parse_user(tls.cmd(pack('<BHHH', 0x4a, dbid, 0, 0)))
|
return parse_user(tls.cmd(pack('<BHHH', 0x4a, dbid, 0, 0)))
|
||||||
|
|
||||||
def lookup_user(self, identity: str) -> typing.Optional[User]:
|
def lookup_user(self, identity: str) -> typing.Optional[User]:
|
||||||
stg = self.get_user_storage(name='StgWindsor')
|
stg = self.get_user_storage(name='StgWindsor')
|
||||||
data = identity_to_bytes(identity)
|
data = identity_to_bytes(identity)
|
||||||
|
|
||||||
rsp = tls.cmd(pack('<BHHH', 0x4a, 0, stg.dbid, len(data)) + data)
|
rsp = tls.cmd(pack('<BHHH', 0x4a, 0, stg.dbid, len(data)) + data)
|
||||||
rc, = unpack('<H', rsp[:2])
|
rc, = unpack('<H', rsp[:2])
|
||||||
|
|
||||||
|
|
@ -165,31 +171,31 @@ class Db():
|
||||||
else:
|
else:
|
||||||
return parse_user(rsp)
|
return parse_user(rsp)
|
||||||
|
|
||||||
def get_record_value(self, dbid):
|
def get_record_value(self, dbid: int):
|
||||||
rsp = tls.cmd(pack('<BH', 0x49, dbid))
|
rsp = tls.cmd(pack('<BH', 0x49, dbid))
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
|
|
||||||
rec = DbRecord()
|
rec = DbRecord()
|
||||||
rec.dbid, rec.type, rec.storage, sz = unpack('<xxHHHHxx', rsp[:12])
|
rec.dbid, rec.type, rec.storage, sz = unpack('<xxHHHHxx', rsp[:12])
|
||||||
rec.value = rsp[12:12+sz]
|
rec.value = rsp[12:12 + sz]
|
||||||
|
|
||||||
return rec
|
return rec
|
||||||
|
|
||||||
def get_record_children(self, dbid):
|
def get_record_children(self, dbid: int):
|
||||||
rsp = tls.cmd(pack('<BH', 0x46, dbid))
|
rsp = tls.cmd(pack('<BH', 0x46, dbid))
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
|
|
||||||
rec = DbRecord()
|
rec = DbRecord()
|
||||||
rec.dbid, rec.type, rec.storage, sz, cnt = unpack('<xxHHHHHxx', rsp[:14])
|
rec.dbid, rec.type, rec.storage, sz, cnt = unpack('<xxHHHHHxx', rsp[:14])
|
||||||
rsp = rsp[14:]
|
rsp = rsp[14:]
|
||||||
rec.children=[]
|
rec.children = []
|
||||||
for i in range(0, cnt):
|
for i in range(0, cnt):
|
||||||
dbid, typ = unpack('<HH', rsp[i*4:i*4+4])
|
dbid, typ = unpack('<HH', rsp[i * 4:i * 4 + 4])
|
||||||
rec.children += [{ 'dbid': dbid, 'type': typ }]
|
rec.children += [{'dbid': dbid, 'type': typ}]
|
||||||
|
|
||||||
return rec
|
return rec
|
||||||
|
|
||||||
def del_record(self, dbid):
|
def del_record(self, dbid: int):
|
||||||
assert_status(tls.cmd(pack('<BH', 0x48, dbid)))
|
assert_status(tls.cmd(pack('<BH', 0x48, dbid)))
|
||||||
|
|
||||||
def db_info(self):
|
def db_info(self):
|
||||||
|
|
@ -200,12 +206,12 @@ class Db():
|
||||||
unknown1, unknown0, total, used, free, records, nroots = unpack('<LLLLLHH', rsp[:0x18])
|
unknown1, unknown0, total, used, free, records, nroots = unpack('<LLLLLHH', rsp[:0x18])
|
||||||
# Seems to always be unknown1 == 1, unknown0 == 0
|
# Seems to always be unknown1 == 1, unknown0 == 0
|
||||||
rsp = rsp[0x18:]
|
rsp = rsp[0x18:]
|
||||||
roots = [unpack('<H', rsp[i*2:i*2+2])[0] for i in range(0, nroots)]
|
roots = [unpack('<H', rsp[i * 2:i * 2 + 2])[0] for i in range(0, nroots)]
|
||||||
|
|
||||||
return Db.Info(total, used, free, records, roots)
|
return Db.Info(total, used, free, records, roots)
|
||||||
|
|
||||||
def new_record(self, parent, typ, storage, data):
|
def new_record(self, parent: int, typ: int, storage: int, data: bytes):
|
||||||
self.db_info() # TODO check free space, compact the partition when out of storage
|
self.db_info() # TODO check free space, compact the partition when out of storage
|
||||||
assert_status(tls.cmd(db_write_enable))
|
assert_status(tls.cmd(db_write_enable))
|
||||||
try:
|
try:
|
||||||
rsp = tls.cmd(pack('<BHHHH', 0x47, parent, typ, storage, len(data)) + data)
|
rsp = tls.cmd(pack('<BHHHH', 0x47, parent, typ, storage, len(data)) + data)
|
||||||
|
|
@ -215,21 +221,21 @@ class Db():
|
||||||
call_cleanups()
|
call_cleanups()
|
||||||
return recid
|
return recid
|
||||||
|
|
||||||
def new_user(self, identity):
|
def new_user(self, identity: str):
|
||||||
data = identity_to_bytes(identity)
|
data = identity_to_bytes(identity)
|
||||||
|
|
||||||
stg = self.get_user_storage(name='StgWindsor')
|
stg = self.get_user_storage(name='StgWindsor')
|
||||||
rec = self.new_record(stg.dbid, 5, stg.dbid, data)
|
rec = self.new_record(stg.dbid, 5, stg.dbid, data)
|
||||||
return rec
|
return rec
|
||||||
|
|
||||||
def new_finger(self, userid, template):
|
def new_finger(self, userid: int, template: bytes):
|
||||||
stg = self.get_user_storage(name='StgWindsor')
|
stg = self.get_user_storage(name='StgWindsor')
|
||||||
# We ask to create an object of type 0xb,
|
# We ask to create an object of type 0xb,
|
||||||
# but because of the magical `db_write_enable` in the new_record() it ends up being 0x6
|
# but because of the magical `db_write_enable` in the new_record() it ends up being 0x6
|
||||||
rec = self.new_record(userid, 0xb, stg.dbid, template)
|
rec = self.new_record(userid, 0xb, stg.dbid, template)
|
||||||
return rec
|
return rec
|
||||||
|
|
||||||
def new_data(self, parent, data):
|
def new_data(self, parent: int, data: bytes):
|
||||||
stg = self.get_user_storage(name='StgWindsor')
|
stg = self.get_user_storage(name='StgWindsor')
|
||||||
data = pack('<HH', 1, len(data)) + data
|
data = pack('<HH', 1, len(data)) + data
|
||||||
rec = self.new_record(parent, 0x8, stg.dbid, data)
|
rec = self.new_record(parent, 0x8, stg.dbid, data)
|
||||||
|
|
@ -240,11 +246,11 @@ class Db():
|
||||||
val = hexlify(rec.value).decode()
|
val = hexlify(rec.value).decode()
|
||||||
if len(val) > 80:
|
if len(val) > 80:
|
||||||
val = val[:80] + '...'
|
val = val[:80] + '...'
|
||||||
print('%s%d (type %d) %s' % (' '*depth, rec.dbid, rec.type, val))
|
print('%s%d (type %d) %s' % (' ' * depth, rec.dbid, rec.type, val))
|
||||||
|
|
||||||
rec = self.get_record_children(root)
|
rec = self.get_record_children(root)
|
||||||
for c in rec.children:
|
for c in rec.children:
|
||||||
self.dump_raw(c['dbid'], depth+1)
|
self.dump_raw(c['dbid'], depth + 1)
|
||||||
|
|
||||||
def dump_all(self):
|
def dump_all(self):
|
||||||
stg = self.get_user_storage(name='StgWindsor')
|
stg = self.get_user_storage(name='StgWindsor')
|
||||||
|
|
@ -252,7 +258,8 @@ class Db():
|
||||||
for u in usrs:
|
for u in usrs:
|
||||||
print('%2d: User %s with %d fingers:' % (u.dbid, repr(u.identity), len(u.fingers)))
|
print('%2d: User %s with %d fingers:' % (u.dbid, repr(u.identity), len(u.fingers)))
|
||||||
for f in u.fingers:
|
for f in u.fingers:
|
||||||
print(' %2d: %02x (%s)' % (f['dbid'], f['subtype'], subtype_to_string(f['subtype'])))
|
print(' %2d: %02x (%s)' %
|
||||||
|
(f['dbid'], f['subtype'], subtype_to_string(f['subtype'])))
|
||||||
|
|
||||||
|
|
||||||
db = Db()
|
db = Db()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,50 +1,66 @@
|
||||||
from .tls import tls
|
import typing
|
||||||
from struct import pack, unpack
|
from struct import pack, unpack
|
||||||
from .util import assert_status, unhex
|
|
||||||
from .blobs import db_write_enable
|
from .blobs import db_write_enable
|
||||||
from .hw_tables import flash_ic_table_lookup
|
from .hw_tables import flash_ic_table_lookup, FlashIcInfo
|
||||||
|
from .tls import tls
|
||||||
|
from .util import assert_status, unhex
|
||||||
|
|
||||||
class FlashInfo():
|
|
||||||
def __init__(self, ic, blocks, unknown0, blocksize, unknown1, partitions):
|
|
||||||
self.ic, self.blocks, self.unknown0, self.blocksize, self.unknown1, self.partitions = ic, blocks, unknown0, blocksize, unknown1, partitions
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return 'FlashInfo(%s, 0x%x, 0x%x, 0x%x, 0x%x, %s)' % (repr(self.ic), self.blocks, self.unknown0, self.blocksize, self.unknown1, repr(self.partitions))
|
|
||||||
|
|
||||||
# type 01 is for the firmware - written blocks are decrypted on the fly using fw key
|
# type 01 is for the firmware - written blocks are decrypted on the fly using fw key
|
||||||
# access lvl:
|
# access lvl:
|
||||||
# 2 -- write only
|
# 2 -- write only
|
||||||
# 7 -- can read/write even without TLS
|
# 7 -- can read/write even without TLS
|
||||||
class PartitionInfo():
|
class PartitionInfo:
|
||||||
def __init__(self, id, type, access_lvl, offset, size):
|
def __init__(self, id: int, type: int, access_lvl: int, offset: int, size: int):
|
||||||
self.id, self.type, self.access_lvl, self.offset, self.size = id, type, access_lvl, offset, size
|
self.id, self.type, self.access_lvl, self.offset, self.size = id, type, access_lvl, offset, size
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'PartitionInfo(0x%02x, 0x%02x, 0x%04x, 0x%08x, 0x%08x)' % (self.id, self.type, self.access_lvl, self.offset, self.size)
|
return 'PartitionInfo(0x%02x, 0x%02x, 0x%04x, 0x%08x, 0x%08x)' % (
|
||||||
|
self.id, self.type, self.access_lvl, self.offset, self.size)
|
||||||
|
|
||||||
|
|
||||||
|
class FlashInfo:
|
||||||
|
def __init__(self, ic: FlashIcInfo, blocks: int, unknown0: int, blocksize: int, unknown1: int,
|
||||||
|
partitions: typing.Sequence[PartitionInfo]):
|
||||||
|
self.ic = ic
|
||||||
|
self.blocks = blocks
|
||||||
|
self.unknown0 = unknown0
|
||||||
|
self.blocksize = blocksize
|
||||||
|
self.unknown1 = unknown1
|
||||||
|
self.partitions = partitions
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return 'FlashInfo(%s, 0x%x, 0x%x, 0x%x, 0x%x, %s)' % (repr(
|
||||||
|
self.ic), self.blocks, self.unknown0, self.blocksize, self.unknown1,
|
||||||
|
repr(self.partitions))
|
||||||
|
|
||||||
|
|
||||||
def get_flash_info():
|
def get_flash_info():
|
||||||
rsp=tls.cmd(unhex('3e'))
|
rsp = tls.cmd(unhex('3e'))
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
rsp=rsp[2:]
|
rsp = rsp[2:]
|
||||||
hdr=rsp[:0xe]
|
hdr = rsp[:0xe]
|
||||||
rsp=rsp[0xe:]
|
rsp = rsp[0xe:]
|
||||||
jid0, jid1, blocks, unknown0, blocksize, unknown1, pcnt = unpack('<HHHHHHH', hdr)
|
jid0, jid1, blocks, unknown0, blocksize, unknown1, pcnt = unpack('<HHHHHHH', hdr)
|
||||||
|
|
||||||
ic=flash_ic_table_lookup(jid0, jid1, blocks*blocksize)
|
|
||||||
|
|
||||||
if ic == None:
|
ic = flash_ic_table_lookup(jid0, jid1, blocks * blocksize)
|
||||||
raise Exception('Unknown flash IC. JEDEC id=%x:%x, size=%dx%d' % (jid0, jid1, blocks, blocksize))
|
|
||||||
|
|
||||||
partitions=[rsp[i*0xc:(i+1)*0xc] for i in range(0, pcnt)]
|
if ic is None:
|
||||||
partitions=[unpack('<BBHLL', i) for i in partitions]
|
raise Exception('Unknown flash IC. JEDEC id=%x:%x, size=%dx%d' %
|
||||||
partitions=[PartitionInfo(*i) for i in partitions]
|
(jid0, jid1, blocks, blocksize))
|
||||||
|
|
||||||
|
partitions = [rsp[i * 0xc:(i + 1) * 0xc] for i in range(0, pcnt)]
|
||||||
|
partitions = [unpack('<BBHLL', i) for i in partitions]
|
||||||
|
partitions = [PartitionInfo(*i) for i in partitions]
|
||||||
|
|
||||||
return FlashInfo(ic, blocks, unknown0, blocksize, unknown1, partitions)
|
return FlashInfo(ic, blocks, unknown0, blocksize, unknown1, partitions)
|
||||||
|
|
||||||
|
|
||||||
# >>> 4302 -- get partition header (get fwext info)
|
# >>> 4302 -- get partition header (get fwext info)
|
||||||
# b004 -- no fw detected
|
# b004 -- no fw detected
|
||||||
# 0000
|
# 0000
|
||||||
# 0100 (major) 0100 (minor) 0800 (modules) c28c745a (buildtime)
|
# 0100 (major) 0100 (minor) 0800 (modules) c28c745a (buildtime)
|
||||||
# type subtype major minor size
|
# type subtype major minor size
|
||||||
# 0100 3446 0200 0700 d03e0000
|
# 0100 3446 0200 0700 d03e0000
|
||||||
# 0100 8408 0100 0700 00040000
|
# 0100 8408 0100 0700 00040000
|
||||||
|
|
@ -54,64 +70,74 @@ def get_flash_info():
|
||||||
# 0200 2377 0000 0100 802f0000
|
# 0200 2377 0000 0100 802f0000
|
||||||
# 0200 6637 0100 0c00 f0220200
|
# 0200 6637 0100 0c00 f0220200
|
||||||
# 0100 2556 0000 0100 60040000
|
# 0100 2556 0000 0100 60040000
|
||||||
class ModuleInfo():
|
class ModuleInfo:
|
||||||
def __init__(self, type, subtype, major, minor, size):
|
def __init__(self, type: int, subtype: int, major: int, minor: int, size: int):
|
||||||
self.type, self.subtype, self.major, self.minor, self.size = type, subtype, major, minor, size
|
self.type, self.subtype, self.major, self.minor, self.size = type, subtype, major, minor, size
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'ModuleInfo(0x%04x, 0x%04x, %d, %d, %d)' % (self.type, self.subtype, self.major, self.minor, self.size)
|
return 'ModuleInfo(0x%04x, 0x%04x, %d, %d, %d)' % (self.type, self.subtype, self.major,
|
||||||
|
self.minor, self.size)
|
||||||
|
|
||||||
class FirmwareInfo():
|
|
||||||
def __init__(self, major, minor, buildtime, modules):
|
class FirmwareInfo:
|
||||||
|
def __init__(self, major: int, minor: int, buildtime: int,
|
||||||
|
modules: typing.Sequence[ModuleInfo]):
|
||||||
self.major, self.minor, self.buildtime, self.modules = major, minor, buildtime, modules
|
self.major, self.minor, self.buildtime, self.modules = major, minor, buildtime, modules
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'FirmwareInfo(%d, %d, %d, %s)' % (self.major, self.minor, self.buildtime, repr(self.modules))
|
return 'FirmwareInfo(%d, %d, %d, %s)' % (self.major, self.minor, self.buildtime,
|
||||||
|
repr(self.modules))
|
||||||
|
|
||||||
def get_fw_info(partition):
|
|
||||||
rsp=tls.cmd(pack('<BB', 0x43, partition))
|
def get_fw_info(partition: int):
|
||||||
|
rsp = tls.cmd(pack('<BB', 0x43, partition))
|
||||||
|
|
||||||
# don't want to throw exception here - it is normal not to have FW when we're about to upload it
|
# don't want to throw exception here - it is normal not to have FW when we're about to upload it
|
||||||
if len(rsp) == 2 and rsp[1] == 4 and rsp[0] == 0xb0:
|
if len(rsp) == 2 and rsp[1] == 4 and rsp[0] == 0xb0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
rsp=rsp[2:]
|
rsp = rsp[2:]
|
||||||
hdr=rsp[:0xa]
|
hdr = rsp[:0xa]
|
||||||
rsp=rsp[0xa:]
|
rsp = rsp[0xa:]
|
||||||
major, minor, modcnt, buildtime = unpack('<HHHL', hdr)
|
major, minor, modcnt, buildtime = unpack('<HHHL', hdr)
|
||||||
modules=[rsp[i*0xc:(i+1)*0xc] for i in range(0, modcnt)]
|
modules = [rsp[i * 0xc:(i + 1) * 0xc] for i in range(0, modcnt)]
|
||||||
modules=[unpack('<HHHHL', i) for i in modules]
|
modules = [unpack('<HHHHL', i) for i in modules]
|
||||||
modules=[ModuleInfo(*i) for i in modules]
|
modules = [ModuleInfo(*i) for i in modules]
|
||||||
|
|
||||||
return FirmwareInfo(major, minor, buildtime, modules)
|
return FirmwareInfo(major, minor, buildtime, modules)
|
||||||
|
|
||||||
|
|
||||||
def write_enable():
|
def write_enable():
|
||||||
assert_status(tls.cmd(db_write_enable))
|
assert_status(tls.cmd(db_write_enable))
|
||||||
|
|
||||||
|
|
||||||
def call_cleanups():
|
def call_cleanups():
|
||||||
rsp = tls.cmd(b'\x1a')
|
rsp = tls.cmd(b'\x1a')
|
||||||
err = unpack('<H', rsp[:2])[0]
|
err = unpack('<H', rsp[:2])[0]
|
||||||
if err == 0x0491: # Nothing to commit
|
if err == 0x0491: # Nothing to commit
|
||||||
return # don't throw an exception, just ignore
|
return # don't throw an exception, just ignore
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
|
|
||||||
def erase_flash(partition):
|
|
||||||
|
def erase_flash(partition: int):
|
||||||
assert_status(tls.cmd(db_write_enable))
|
assert_status(tls.cmd(db_write_enable))
|
||||||
try:
|
try:
|
||||||
assert_status(tls.cmd(pack('<BB', 0x3f, partition)))
|
assert_status(tls.cmd(pack('<BB', 0x3f, partition)))
|
||||||
finally:
|
finally:
|
||||||
call_cleanups()
|
call_cleanups()
|
||||||
|
|
||||||
def read_flash(partition, addr, size):
|
|
||||||
|
def read_flash(partition: int, addr: int, size: int) -> bytes:
|
||||||
cmd = pack('<BBBHLL', 0x40, partition, 1, 0, addr, size)
|
cmd = pack('<BBBHLL', 0x40, partition, 1, 0, addr, size)
|
||||||
rsp = tls.cmd(cmd)
|
rsp = tls.cmd(cmd)
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
sz, = unpack('<xxLxx', rsp[:8])
|
sz, = unpack('<xxLxx', rsp[:8])
|
||||||
|
|
||||||
return rsp[8:8+sz]
|
return rsp[8:8 + sz]
|
||||||
|
|
||||||
def write_flash(partition, addr, buf):
|
|
||||||
|
def write_flash(partition: int, addr: int, buf: bytes):
|
||||||
tls.cmd(db_write_enable)
|
tls.cmd(db_write_enable)
|
||||||
cmd = pack('<BBBHLL', 0x41, partition, 1, 0, addr, len(buf)) + buf
|
cmd = pack('<BBBHLL', 0x41, partition, 1, 0, addr, len(buf)) + buf
|
||||||
try:
|
try:
|
||||||
|
|
@ -120,21 +146,25 @@ def write_flash(partition, addr, buf):
|
||||||
finally:
|
finally:
|
||||||
call_cleanups()
|
call_cleanups()
|
||||||
|
|
||||||
def write_flash_all(partition, ptr, buf):
|
|
||||||
|
def write_flash_all(partition: int, ptr: int, buf: bytes):
|
||||||
bs = 0x1000
|
bs = 0x1000
|
||||||
while len(buf) > 0:
|
while len(buf) > 0:
|
||||||
chunk, buf = buf[:bs], buf[bs:]
|
chunk, buf = buf[:bs], buf[bs:]
|
||||||
write_flash(partition, ptr, chunk)
|
write_flash(partition, ptr, chunk)
|
||||||
ptr += len(chunk)
|
ptr += len(chunk)
|
||||||
|
|
||||||
def read_flash_all(partition, start, size):
|
|
||||||
|
def read_flash_all(partition: int, start: int, size: int):
|
||||||
bs = 0x1000
|
bs = 0x1000
|
||||||
blocks = [read_flash(partition, addr, bs) for addr in range(start, start+size, bs)]
|
blocks = [read_flash(partition, addr, bs) for addr in range(start, start + size, bs)]
|
||||||
return b''.join(blocks)[:size]
|
return b''.join(blocks)[:size]
|
||||||
|
|
||||||
def write_fw_signature(partition, signature):
|
|
||||||
rsp=tls.cmd(pack('<BBxH', 0x42, partition, len(signature)) + signature)
|
def write_fw_signature(partition: int, signature: bytes):
|
||||||
|
rsp = tls.cmd(pack('<BBxH', 0x42, partition, len(signature)) + signature)
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
|
|
||||||
|
|
||||||
def read_tls_flash():
|
def read_tls_flash():
|
||||||
return read_flash(1, 0, 0x1000)
|
return read_flash(1, 0, 0x1000)
|
||||||
|
|
|
||||||
|
|
@ -1,81 +1,775 @@
|
||||||
|
|
||||||
from .table_types import SensorTypeInfo, SensorCaptureProg
|
from .table_types import SensorTypeInfo, SensorCaptureProg
|
||||||
|
|
||||||
SensorTypeInfo.table=[
|
SensorTypeInfo.table = [
|
||||||
SensorTypeInfo(sensor_type=0x00db, bytes_per_line=0x98, repeat_multiplier=1, lines_per_calibration_data=144, line_width=144, calibration_blob='101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f'),
|
SensorTypeInfo(
|
||||||
SensorTypeInfo(sensor_type=0x00e4, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=100, line_width=112, calibration_blob='9392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e'),
|
sensor_type=0x00db,
|
||||||
SensorTypeInfo(sensor_type=0x00ed, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
|
bytes_per_line=0x98,
|
||||||
SensorTypeInfo(sensor_type=0x0199, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
|
repeat_multiplier=1,
|
||||||
SensorTypeInfo(sensor_type=0x00b5, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
|
lines_per_calibration_data=144,
|
||||||
SensorTypeInfo(sensor_type=0x0885, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
|
line_width=144,
|
||||||
SensorTypeInfo(sensor_type=0x1055, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
|
calibration_blob=
|
||||||
SensorTypeInfo(sensor_type=0x1825, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
|
'101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f'
|
||||||
SensorTypeInfo(sensor_type=0x1ff5, bytes_per_line=0x78, repeat_multiplier=2, lines_per_calibration_data=112, line_width=112, calibration_blob='9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'),
|
),
|
||||||
SensorTypeInfo(sensor_type=0x00b3, bytes_per_line=0x60, repeat_multiplier=2, lines_per_calibration_data=84, line_width=85, calibration_blob='898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19'),
|
SensorTypeInfo(
|
||||||
SensorTypeInfo(sensor_type=0x143b, bytes_per_line=0x5c, repeat_multiplier=2, lines_per_calibration_data=84, line_width=84, calibration_blob='898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19'),
|
sensor_type=0x00e4,
|
||||||
SensorTypeInfo(sensor_type=0x08b1, bytes_per_line=0x58, repeat_multiplier=2, lines_per_calibration_data=78, line_width=78, calibration_blob='9b9a9996959392918f8e8d8b8a89878685837d7b7a7977767573716f6d6b6a695d5b5a595756555251504e4d4c4a41403e3d3c3a393432312c2a28261e1d1c1a19181615141211100d0c0a090806'),
|
bytes_per_line=0x78,
|
||||||
SensorTypeInfo(sensor_type=0x00e1, bytes_per_line=0x58, repeat_multiplier=2, lines_per_calibration_data=78, line_width=78, calibration_blob='9b9a9996959392918f8e8d8b8a89878685837d7b7a7977767573716f6d6b6a695d5b5a595756555251504e4d4c4a41403e3d3c3a393432312c2a28261e1d1c1a19181615141211100d0c0a090806'),
|
repeat_multiplier=2,
|
||||||
SensorTypeInfo(sensor_type=0x00ea, bytes_per_line=0x5c, repeat_multiplier=1, lines_per_calibration_data=84, line_width=84, calibration_blob='898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19'),
|
lines_per_calibration_data=100,
|
||||||
SensorTypeInfo(sensor_type=0x0194, bytes_per_line=0x7c, repeat_multiplier=3, lines_per_calibration_data=84, line_width=114, calibration_blob='000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253'),
|
line_width=112,
|
||||||
SensorTypeInfo(sensor_type=0x0126, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
|
calibration_blob=
|
||||||
SensorTypeInfo(sensor_type=0x0117, bytes_per_line=0xa0, repeat_multiplier=4, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
|
'9392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e'
|
||||||
SensorTypeInfo(sensor_type=0x08f3, bytes_per_line=0xa0, repeat_multiplier=1, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
|
),
|
||||||
SensorTypeInfo(sensor_type=0x08f6, bytes_per_line=0xa0, repeat_multiplier=1, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
|
SensorTypeInfo(
|
||||||
SensorTypeInfo(sensor_type=0x0121, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
|
sensor_type=0x00ed,
|
||||||
SensorTypeInfo(sensor_type=0x0b4b, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
|
bytes_per_line=0x78,
|
||||||
SensorTypeInfo(sensor_type=0x0b4d, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=56, line_width=144, calibration_blob='0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'),
|
repeat_multiplier=2,
|
||||||
SensorTypeInfo(sensor_type=0x0130, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=40, line_width=144, calibration_blob='15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
|
lines_per_calibration_data=112,
|
||||||
SensorTypeInfo(sensor_type=0x0be2, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=40, line_width=144, calibration_blob='15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
|
line_width=112,
|
||||||
SensorTypeInfo(sensor_type=0x0be1, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=40, line_width=144, calibration_blob='15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
|
calibration_blob=
|
||||||
SensorTypeInfo(sensor_type=0x0518, bytes_per_line=0xa0, repeat_multiplier=2, lines_per_calibration_data=40, line_width=144, calibration_blob='15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
|
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
|
||||||
SensorTypeInfo(sensor_type=0x0179, bytes_per_line=0x98, repeat_multiplier=3, lines_per_calibration_data=56, line_width=144, calibration_blob='3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172'),
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0199,
|
||||||
|
bytes_per_line=0x78,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=112,
|
||||||
|
line_width=112,
|
||||||
|
calibration_blob=
|
||||||
|
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x00b5,
|
||||||
|
bytes_per_line=0x78,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=112,
|
||||||
|
line_width=112,
|
||||||
|
calibration_blob=
|
||||||
|
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0885,
|
||||||
|
bytes_per_line=0x78,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=112,
|
||||||
|
line_width=112,
|
||||||
|
calibration_blob=
|
||||||
|
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x1055,
|
||||||
|
bytes_per_line=0x78,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=112,
|
||||||
|
line_width=112,
|
||||||
|
calibration_blob=
|
||||||
|
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x1825,
|
||||||
|
bytes_per_line=0x78,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=112,
|
||||||
|
line_width=112,
|
||||||
|
calibration_blob=
|
||||||
|
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x1ff5,
|
||||||
|
bytes_per_line=0x78,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=112,
|
||||||
|
line_width=112,
|
||||||
|
calibration_blob=
|
||||||
|
'9b9a999796959392918f8e8d8b8a898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19181615141211100e0d0c0a090806'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x00b3,
|
||||||
|
bytes_per_line=0x60,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=84,
|
||||||
|
line_width=85,
|
||||||
|
calibration_blob=
|
||||||
|
'898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x143b,
|
||||||
|
bytes_per_line=0x5c,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=84,
|
||||||
|
line_width=84,
|
||||||
|
calibration_blob=
|
||||||
|
'898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x08b1,
|
||||||
|
bytes_per_line=0x58,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=78,
|
||||||
|
line_width=78,
|
||||||
|
calibration_blob=
|
||||||
|
'9b9a9996959392918f8e8d8b8a89878685837d7b7a7977767573716f6d6b6a695d5b5a595756555251504e4d4c4a41403e3d3c3a393432312c2a28261e1d1c1a19181615141211100d0c0a090806'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x00e1,
|
||||||
|
bytes_per_line=0x58,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=78,
|
||||||
|
line_width=78,
|
||||||
|
calibration_blob=
|
||||||
|
'9b9a9996959392918f8e8d8b8a89878685837d7b7a7977767573716f6d6b6a695d5b5a595756555251504e4d4c4a41403e3d3c3a393432312c2a28261e1d1c1a19181615141211100d0c0a090806'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x00ea,
|
||||||
|
bytes_per_line=0x5c,
|
||||||
|
repeat_multiplier=1,
|
||||||
|
lines_per_calibration_data=84,
|
||||||
|
line_width=84,
|
||||||
|
calibration_blob=
|
||||||
|
'898786858382817f7e7d7b7a797776757372716f6e6d6b6a696766656362615f5e5d5b5a595756555251504e4d4c4a49484645444241403e3d3c3a39383635343231302e2d2c2a29282625242221201e1d1c1a19'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0194,
|
||||||
|
bytes_per_line=0x7c,
|
||||||
|
repeat_multiplier=3,
|
||||||
|
lines_per_calibration_data=84,
|
||||||
|
line_width=114,
|
||||||
|
calibration_blob=
|
||||||
|
'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0126,
|
||||||
|
bytes_per_line=0xa0,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=56,
|
||||||
|
line_width=144,
|
||||||
|
calibration_blob=
|
||||||
|
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0117,
|
||||||
|
bytes_per_line=0xa0,
|
||||||
|
repeat_multiplier=4,
|
||||||
|
lines_per_calibration_data=56,
|
||||||
|
line_width=144,
|
||||||
|
calibration_blob=
|
||||||
|
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x08f3,
|
||||||
|
bytes_per_line=0xa0,
|
||||||
|
repeat_multiplier=1,
|
||||||
|
lines_per_calibration_data=56,
|
||||||
|
line_width=144,
|
||||||
|
calibration_blob=
|
||||||
|
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x08f6,
|
||||||
|
bytes_per_line=0xa0,
|
||||||
|
repeat_multiplier=1,
|
||||||
|
lines_per_calibration_data=56,
|
||||||
|
line_width=144,
|
||||||
|
calibration_blob=
|
||||||
|
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0121,
|
||||||
|
bytes_per_line=0xa0,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=56,
|
||||||
|
line_width=144,
|
||||||
|
calibration_blob=
|
||||||
|
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0b4b,
|
||||||
|
bytes_per_line=0xa0,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=56,
|
||||||
|
line_width=144,
|
||||||
|
calibration_blob=
|
||||||
|
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0b4d,
|
||||||
|
bytes_per_line=0xa0,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=56,
|
||||||
|
line_width=144,
|
||||||
|
calibration_blob=
|
||||||
|
'0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243'
|
||||||
|
),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0130,
|
||||||
|
bytes_per_line=0xa0,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=40,
|
||||||
|
line_width=144,
|
||||||
|
calibration_blob=
|
||||||
|
'15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0be2,
|
||||||
|
bytes_per_line=0xa0,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=40,
|
||||||
|
line_width=144,
|
||||||
|
calibration_blob=
|
||||||
|
'15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0be1,
|
||||||
|
bytes_per_line=0xa0,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=40,
|
||||||
|
line_width=144,
|
||||||
|
calibration_blob=
|
||||||
|
'15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0518,
|
||||||
|
bytes_per_line=0xa0,
|
||||||
|
repeat_multiplier=2,
|
||||||
|
lines_per_calibration_data=40,
|
||||||
|
line_width=144,
|
||||||
|
calibration_blob=
|
||||||
|
'15161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3b'),
|
||||||
|
SensorTypeInfo(
|
||||||
|
sensor_type=0x0179,
|
||||||
|
bytes_per_line=0x98,
|
||||||
|
repeat_multiplier=3,
|
||||||
|
lines_per_calibration_data=56,
|
||||||
|
line_width=144,
|
||||||
|
calibration_blob=
|
||||||
|
'3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172'
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
SensorCaptureProg.table=[
|
SensorCaptureProg.table = [
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
|
SensorCaptureProg(
|
||||||
SensorCaptureProg(major=0x6, minor=0x6, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
|
major=0x6,
|
||||||
SensorCaptureProg(major=0x6, minor=0x7, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
|
minor=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x8, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
|
build=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0xa, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['230000003200680000000080002000002020000024200000382000002820df0b2c20df0b302000003420000050200a005c20000064204300602000004c2000006c20100070201000742005007820050084202000b4200000b8203b00bc201400c0200200c4200100c82002007403000233001c000000008054202a2203005820272f0300cc200000ef03d0200000ef033200480000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203b00002804001428000008280000082800001428300008280000142831001c281a006411240068110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
|
u1=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0xb, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['230000003200680000000080002000002020000024200000382000002820df0b2c20df0b302000003420000050200a005c20000064204300602000004c2000006c20100070201000742005007820050084202000b4200000b8203b00bc201400c0200200c4200100c82002007403000233001c000000008054202a2203005820272f0300cc200000ef03d0200000ef033200480000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203b00002804001428000008280000082800001428300008280000142831001c281a006411240068110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
|
dev_type=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0x0, a0=0x0, a1=0x0, blobs=['230000003200680000000080002000002020000024200000382000002820df0b2c20df0b302000003420000050200a005c20000064204300602000004c2000006c20100070201000742005007820050084202000b4200000b8203b00bc201400c0200200c4200100c82002007403000233001c000000008054202a2203005820272f0300cc200000ef03d0200000ef033200480000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203b00002804001428000008280000082800001428300008280000142831001c281a006411240068110000', '2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000', '29000400000000003500040000000000']),
|
a0=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x6, build=0x0, u1=0x0, dev_type=0x885, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082150000c210000482105004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601066310250101000007c8078c06ff4f80006d0300200307030b90098db08d099186890b9108c180910ac190ba2c928f099382890b938889898908c881910ac8888a9189099a82890b9a8889898908d081910ad0888a9189080282890a02095a80890b5a888908d981890ad98891898a095e81890b5e8889898908e181890ae18891898a096481890b64888989096e8108e9810b6e880ae9889191ba096f828f0b6f8889918908f082890af08891898a097681890b7690b9928f08f882910af8908a8a91097c818a0b7c88090181890b018889892491097f818a0b7f900908818a0b0890898a910c0703030720040200002f0004007000000029000400700000003500040080000000']),
|
a1=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x7, build=0x0, u1=0x0, dev_type=0x885, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082150000c210000482105004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601066310250101000007c8078c06ff4f80006d0300200307030b90098db08d099186890b9108c180910ac190ba2c928f099382890b938889898908c881910ac8888a9189099a82890b9a8889898908d081910ad0888a9189080282890a02095a80890b5a888908d981890ad98891898a095e81890b5e8889898908e181890ae18891898a096481890b64888989096e8108e9810b6e880ae9889191ba096f828f0b6f8889918908f082890af08891898a097681890b7690b9928f08f882910af8908a8a91097c818a0b7c88090181890b018889892491097f818a0b7f900908818a0b0890898a910c0703030720040200002f0004007000000029000400700000003500040080000000']),
|
blobs=[
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x1055, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482103004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601066310250101000007c8078c06ff4f80006d0300200307030b90098db08d099186890b9108c180910ac190ba2c928f099382890b938889898908c881910ac8888a9189099a82890b9a8889898908d081910ad0888a9189080282890a02095a80890b5a888908d981890ad98891898a095e81890b5e8889898908e181890ae18891898a096481890b64888989096e8108e9810b6e880ae9889191ba096f828f0b6f8889918908f082890af08891898a097681890b7690b9928f08f882910af8908a8a91097c818a0b7c88090181890b018889892491097f818a0b7f900908818a0b0890898a910c0703030720040200002f0004007000000029000400700000003500040080000000']),
|
'23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000',
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x1825, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601062810250101000007c8078c06ff4f80006d0300200307030990098db00b90880991858e08c1810b9190910ac1b828928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f812089920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000']),
|
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0xb5, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482106004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e0034007801000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001023171023171023161023161023160106635205001025010100000007c8078c06ff00004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000']),
|
'29000400000000003500040000000000'
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x1ff5, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482106004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601062810250101000007c8078c06ff4f80006d0300200307030990098db00b90880991858e08c1810b9190910ac1b828928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f812089920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000']),
|
]),
|
||||||
SensorCaptureProg(major=0x6, minor=0x7, build=0x0, u1=0x0, dev_type=0x1825, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601065010240101000007c8078c06ff00004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000']),
|
SensorCaptureProg(
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0xe4, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221410221410221410221410221401066510250101000007c8078c06ff4f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c0703030720040200002f0004006400000029000400700000003500040080000000']),
|
major=0x6,
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0xed, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482104004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601065010240101000007c8078c06ff00004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000']),
|
minor=0x6,
|
||||||
SensorCaptureProg(major=0x6, minor=0x7, build=0x0, u1=0x0, dev_type=0x143b, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200200c4200100c82002003300100000000080cc200000d600d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c1117003400340200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101c11101c11101c11101c11101c10010657101e0101000007c8078c06ff00004f80006d03002c03070308c608c709930703800ac60994800ac70995800b930996800b940997800b950998800b9608c8800b9708ca800b9808cb800ac808cc800aca08ce800acb08cf800acc099a800ace099b800acf099c800b9a099d800b9b099e800b9c099f800b9d08d0800b9e08d2800b9f08d3800ad008d4800ad208d6800ad308d7800ad40802800ad60803800ad7095a800a02095b800a03095c800b5a095d800b5b08d9800b5c08da800b5d08db800ad908dd800ada08de800adb08df800add095e800ade095f800adf0960800b5e0961800b5f0962800b600963800b6108e1800b6208e2800b6308e3800ae108e5800ae208e6800ae308e7800ae50964800ae60965800ae70966800b640967800b650968800b66096e800b6708e9800b6808ea800b6e08eb800ae908ed800aea08ef800aeb08ee800aed096f800aef0970800aee0971800b6f0972800b700974800b710975800b7208f0800b7408f1800b7508f2800af008f4800af108f5800af208f6800af40976800af50977800af60979800b760978800b77097a800b79097b800b7808f8800b7a08fa800b7b08fc800af808fd800afa08fe800afc0900800c2007030307200402002f0004005400000029000400580000003500040068000000']),
|
build=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x7, build=0x0, u1=0x0, dev_type=0xb3, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082140000c210000482106004c210000582000005c2000006020000068200a006c20012970200121742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200100c4200100c82002003300100000000080cc2000002c01d0200000a1013200440000000080dc205302e0206401e420a901e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c11180034003c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101c11101c11101c11101c11101c10010657101e0101000007c8078c06ff00004f80006d03002c0308c608c70703800ac60993800ac70994800b930995800b940996800b950997800b960998800b9708c8800b9808ca800ac808cb800aca08cc800acb08ce800acc08cf800ace099a800acf099b800b9a099c800b9b099d800b9c099e800b9d099f800b9e08d0800b9f08d2800ad008d3800ad208d4800ad308d6800ad408d7800ad60802800ad70803800a02095a800a03095b800b5a095c800b5b095d800b5c08d9800b5d08da800ad908db800ada08dd800adb08de800add08df800ade095e800adf095f800b5e0960800b5f0961800b600962800b610963800b6208e1800b6308e2800ae108e3800ae208e5800ae308e6800ae508e7800ae60964800ae70965800b640966800b650967800b660968800b67096e800b6808e9800b6e08ea800ae908eb800aea08ed800aeb08ef800aed08ee800aef096f800aee0970800b6f0971800b700972800b710974800b720975800b7408f0800b7508f1800af008f2800af108f4800af208f5800af408f6800af50976800af60977800b760979800b770978800b79097a800b78097b800b7a08f8800b7b08fa800af808fc800afa08fd800afc08fe800afd090080808080240c0703030720040200000000002f0004005400000029000400580000003500040068000000']),
|
u1=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0xe1, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032006c000000008020200400242000005020773628200100302001003c208000082138000c210000482105004c210000582000005c2000006020000068200a006c20014970200141742001887820018084203000942001809c200902a0200b19bc201400c0200200c4200100c82002003300100000000080cc2000006401d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c11160034001402000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101b10101b10101b10101b0f101b0f010656101e0101000007c8078c06ff4f80006d03002c03070308c108bf098f0703800ac10990800abf098d800b8f0991800b900992800b8d08c5800b9108c3800b9208c6800ac508c4800ac308cb800ac608c7800ac40993800acb0994800ac70995800b930997800b940996800b950998800b9708ce800b9608cc800b9808cf800ace08d0800acc08d2800acf08dd800ad0099a800ad2099b800add099c800b9a0803800b9b095a800b9c095b800a0308de800b5a08df800b5b08e1800ade08eb800adf08ed800ae108f1800aeb095c800aed0962800af10963800b5c096f800b620970800b630971800b6f08f2800b7008f5800b7108f6800af208fa800af508f8800af608fc800afa0974800af80976800afc097b800b74097a800b76097f800b7b097e800b7a08fd800b7f08fe800b7e090b800afd090c800afe090d800b0b090f800b0c0980800b0d0982800b0f0983800b80097d800b820978800b83097c800b7d0914800b780908800b7c0909800b140907800b080905800b090904800b070979800b050977800b040975800b790972800b77096c800b750936800b7209348080800c20070303072004020000002f0004004e00000029000400540000003500040064000000']),
|
dev_type=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x8b1, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032006c000000008020200400242000005020773628200100302001003c208000082138000c210000482107004c210000582000005c2000006020000068200a006c20014970200141742001887820018084203000942001809c200902a0200b19bc201400c0200200c4200100c82002003300100000000080cc2000002c00d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c11160034001402000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101b10101b10101b10101b0f101b0f010656101e0101000007c8078c06ff4f80006d03002c03070308c108bf098f0703800ac10990800abf098d800b8f0991800b900992800b8d08c5800b9108c3800b9208c6800ac508c4800ac308cb800ac608c7800ac40993800acb0994800ac70995800b930997800b940996800b950998800b9708ce800b9608cc800b9808cf800ace08d0800acc08d2800acf08dd800ad0099a800ad2099b800add099c800b9a0803800b9b095a800b9c095b800a0308de800b5a08df800b5b08e1800ade08eb800adf08ed800ae108f1800aeb095c800aed0962800af10963800b5c096f800b620970800b630971800b6f08f2800b7008f5800b7108f6800af208fa800af508f8800af608fc800afa0974800af80976800afc097b800b74097a800b76097f800b7b097e800b7a08fd800b7f08fe800b7e090b800afd090c800afe090d800b0b090f800b0c0980800b0d0982800b0f0983800b80097d800b820978800b83097c800b7d0914800b780908800b7c0909800b140907800b080905800b090904800b070979800b050977800b040975800b790972800b77096c800b750936800b7209348080800c20070303072004020000002f0004004e00000029000400540000003500040064000000']),
|
a0=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0xea, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082138000c210000482106004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200200c4200100c82002003300100000000080cc200000d600d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c11170034003002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101b11101b11101b11101b11101b1001064d101d0101000007c8078c06ff00004f80006d03002c03070308c608c709930703800ac60994800ac70995800b930996800b940997800b950998800b9608c8800b9708ca800b9808cb800ac808cc800aca08ce800acb08cf800acc099a800ace099b800acf099c800b9a099d800b9b099e800b9c099f800b9d08d0800b9e08d2800b9f08d3800ad008d4800ad208d6800ad308d7800ad40802800ad60803800ad7095a800a02095b800a03095c800b5a095d800b5b08d9800b5c08da800b5d08db800ad908dd800ada08de800adb08df800add095e800ade095f800adf0960800b5e0961800b5f0962800b600963800b6108e1800b6208e2800b6308e3800ae108e5800ae208e6800ae308e7800ae50964800ae60965800ae70966800b640967800b650968800b66096e800b6708e9800b6808ea800b6e08eb800ae908ed800aea08ef800aeb08ee800aed096f800aef0970800aee0971800b6f0972800b700974800b710975800b7208f0800b7408f1800b7508f2800af008f4800af108f5800af208f6800af40976800af50977800af60979800b760978800b77097a800b79097b800b7808f8800b7a08fa800b7b08fc800af808fd800afa08fe800afc0900800c2007030307200402002f0004005400000029000400540000003500040064000000']),
|
a1=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x199, a0=0x18, a1=0x19, blobs=['23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482107004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c111e00340078010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601065010250101000007c8078c06ff0000000000004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000']),
|
blobs=[
|
||||||
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0x8f3, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032006000000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20700070207000742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002a0030000330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c64200050630c642000606c0c64200070620c642000806b0c64200090610c642000a06a0c642000b0600c642000c0690c642000d05f0c642000e05e0c642000f04f0c642000005d0c642000104e0c642000205c0c642000304d0c642000405b0c642000504c0c642000605a0c642000704b0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d10c642000d02b0c642000e0d20c642000f02a0c64200000d30c64200010290c64200020d60c64200030280c64200040d70c642000501d0c64200060d80c642000701c0c64200080d90c642000901b0c642000a0da0c642000b01a0c642000c0de0c642000d0190c642000e0df0c642000f0150c64200000e00c64200010140c64200020e10c64200030130c64200040e20c64200050120c64200060e40c64200070110c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b070100002403089808a9089908a8089a08a7089b08a6089c08a4089d08a3089e08a2089f08a1c0102c03088808b9088908b8088a08b7088b08b3089208b2089308b1089408b0089508afc01003087108c6087208c5087d08c2087e08c1087f08c0088008bf088108bb088708bac0100628070103084f085e085f08690860086a0861086b0862086c086308c9086f08c8087008c7c010030847082e0848082f08490830084a0831084b085a084c085b084d085c084e085dc01003082a08d2082b08d1082c08ce083808cd083908cc083a08cb083b08ca0846082dc0100632070103081508df081908de081a08da081b08d9081c08d8081d08d7082808d6082908d3c01059940b03080a08e8080b08e7080c08e6080d08e5081108e4081208e2081308e1081408e0c0102403080008f1080108f0080208ef080308ee080408ed080508ec080608eb080708eac0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
|
'23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000',
|
||||||
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0x8f6, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20500070205000742000007820000084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c64200050630c642000606c0c64200070620c642000806b0c64200090610c642000a06a0c642000b0600c642000c0690c642000d05f0c642000e05e0c642000f04f0c642000005d0c642000104e0c642000205c0c642000304d0c642000405b0c642000504c0c642000605a0c642000704b0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c0000000080681101006411260034001c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b070100000720240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c90863086c0862086b0861086a08600869085f085e084fc01003085d084e085c084d085b084c085a084b0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c0100308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c010070320030c07030703072004020000004200080002089000000000002f00040038000000', '2f00040038000000290004009000000035000400a0000000']),
|
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
|
||||||
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0x121, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20720070207200742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a120100000620102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063007010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
|
'29000400000000003500040000000000'
|
||||||
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0x121, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20720070207200742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a120100000620102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063007010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
|
]),
|
||||||
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0xb4b, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20660070206600742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
|
SensorCaptureProg(
|
||||||
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0xb4b, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20660070206600742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
|
major=0x6,
|
||||||
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0xb4b, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050201f015c200000602000004c2003006c20720070207200742004007820040084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d03005e03004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
|
minor=0x7,
|
||||||
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0xb4b, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050201f015c200000602000004c2003006c20720070207200742004007820040084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d03005e03004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
|
build=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x14, build=0x0, u1=0x0, dev_type=0xb4d, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20600070206000742002007820020084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d01005e01004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
|
u1=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0xb4d, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20600070206000742002007820020084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c', '32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d01005e01004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000']),
|
dev_type=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0x130, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20400070204000742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003', '330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c', '32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000']),
|
a0=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0x518, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20640070206400742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003', '330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c', '32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000']),
|
a1=0x0,
|
||||||
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0xbe1, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20550070205500742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003', '330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c', '32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000']),
|
blobs=[
|
||||||
SensorCaptureProg(major=0x6, minor=0x15, build=0x0, u1=0x0, dev_type=0xbe2, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20500070205000742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003', '330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c', '32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000']),
|
'23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000',
|
||||||
SensorCaptureProg(major=0x6, minor=0xb, build=0x0, u1=0x0, dev_type=0x194, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032005c0000000080202004002820ff0b2c20f60b6c202f007020000074201000782000005c2000006020000064200000502000005420151d84202000942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc2000004900d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0201400f8200500fc200000b8203b00002804001428000008280000082810001428180008281100142819001c281a00', '32001400000000806811010064111f007c1700007017010033001c00000000809c1701000000ac1700900100b01754000000b417007200003400500010061110061110061110061110061001068010080101000007c80764060000002003070107010c07840a640863c91e2cc9159107010a9dc9110701030a3208330701c90f20c91e070304020000000000', '2f0004005400000029000400000000003500040010000000']),
|
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0x179, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032007800000000802020040024200000382000002820df0b2c20df0b30200000342000003c20000040200000442000004820000050200a005c20000060200000642000004c200300002100006c2030007020300040210000742006007820060084202000b4200000b8203a00bc201400c0200200c4200100c820020033001c000000008054202f27030058202f270300cc200000ef03d0200000ef033200440000000080dc20e803e020e803e420d002e820d002f0200500f8200500fc200000b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '320014000000008068110100641126007c1700007017010033001c00000000809c1701000000ac1700900100b01738000000b417009000003400040310060b10060b10060b10060b10060c01064e10080101000007c80764060000002003070107010c2c078408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b800aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a720871800ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d1800a2c082b800ad108d2800a2b082a800ad208d3800a2a0829800ad308d6800a290828800ad608d7800a28081d800ad708d8800a1d081c800ad808d9800a1c081b800ad908da800a1b081a800ada08de800a1a0819800ade08df800a190815800adf08e0800a150814800ae008e1800a140813800ae108e2800a130812800ae208e4800a120811800ae408e5800a11080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708ea800a0b080a800aea08eb800a0a0807800aeb08ec800a070806800aec08ed800a060805800aed08ee800a050804800aee08ef800a040803800aef08f0800a030802800af008f1800a020801800af108f2800a010800802007032003070307030402000000', '2f0004003800000029000400000000003500040010000000']),
|
'29000400000000003500040000000000'
|
||||||
SensorCaptureProg(major=0x6, minor=0xa, build=0x0, u1=0x0, dev_type=0x117, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032006400000000802020040024200000382000002820df0b2c20df0b30200000342000003c2080004020800050200a005c200000602000004c2003006c20680070206800742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '32000c000000008068110100641126003400ac0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102b0e102b0e102b0e102b0e01000000061e10301001000007c80764060b4f80005080006d030007010000006d0300200307010007032408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b802c0aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a72087180062807010ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d1800a2c082b800ad108d2800a2b082a80063207010ad208d3800a2a0829800ad308d6800a290828800ad608d7800a28081d800ad708d8800a1d081c800ad808d9800a1c081b800ad908da800a1b081a800ada08de800a1a0819800ade08df800a190815800adf08e0800a150814800ae008e1800a140813800ae108e2800a130812800ae208e4800a120811800ae408e5800a11080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708ea800a0b080a800aea08eb800a0a0807800aeb08ec800a070806800aec08ed800a06080580240aed08ee800a050804800aee08ef800a040803800aef08f0800a030802800af008f1800a020801800af108f2800c0a01080080070103040200000000002f00040038000000', '290004009400000035000400a4000000']),
|
]),
|
||||||
SensorCaptureProg(major=0x6, minor=0xb, build=0x0, u1=0x0, dev_type=0x117, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032006400000000802020040024200000382000002820df0b2c20df0b30200000342000003c2080004020800050200a005c200000602000004c2003006c20680070206800742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '32000c000000008068110100641126003400ac0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102b0e102b0e102b0e102b0e01000000061e10301001000007c80764060b4f80005080006d030007010000006d0300200307010007032408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b802c0aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a72087180062807010ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d1800a2c082b800ad108d2800a2b082a80063207010ad208d3800a2a0829800ad308d6800a290828800ad608d7800a28081d800ad708d8800a1d081c800ad808d9800a1c081b800ad908da800a1b081a800ada08de800a1a0819800ade08df800a190815800adf08e0800a150814800ae008e1800a140813800ae108e2800a130812800ae208e4800a120811800ae408e5800a11080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708ea800a0b080a800aea08eb800a0a0807800aeb08ec800a070806800aec08ed800a06080580240aed08ee800a050804800aee08ef800a040803800aef08f0800a030802800af008f1800a020801800af108f2800c0a01080080070103040200000000002f00040038000000', '290004009400000035000400a4000000']),
|
SensorCaptureProg(
|
||||||
SensorCaptureProg(major=0x6, minor=0xb, build=0x0, u1=0x0, dev_type=0x126, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032007000000000802020040024200000382000002820df0b2c20df0b30200000342000003c2080004020800050200a005c200000602000004c2003006c2068007020680074200100782001006420000084202000b4200000b8203a00bc201400c0200200c4200100c820020074030000a0030f00330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00', '32000c000000008068110100641126003400ac0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102b0e102b0e102b0e102b0e01000000061e10301001000007c80764060b4f80005080006d030007010000006d0300200307010007032408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b802c0aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a72087180062807010ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d0800a2c082b800ad008d1800a2b082a80063207010ad108d2800a2a0829800ad208d3800a290828800ad308d6800a28081c800ad608d7800a1c081b800ad708d8800a1b081a800ad808d9800a1a0819800ad908da800a190815800ada08df800a150814800adf08e0800a140813800ae008e1800a130812800ae108e2800a120811800ae208e4800a11080e800ae408e5800a0e080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708e8800a0b080a800ae808ea800a0a0807800aea08eb800a070806800aeb08ec800a06080580240aec08ed800a050804800aed08ee800a040803800aee08ef800a030802800aef08f0800a020801800af008f1800c0a01080080070c03040200000000002f00040038000000290004009400000035000400a4000000']),
|
major=0x6,
|
||||||
SensorCaptureProg(major=0x6, minor=0x0, build=0x0, u1=0x0, dev_type=0xdb, a0=0x18, a1=0x19, blobs=['2300000020000800002000800000010032007000000000802020050024200000502077362820010030200100082170000c210000482102004c210000582000005c20000060200000682005006c20012970200121742001887820018084202000942001809c200902a0200b19b4200000b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b00000804001408000008080000080800001408300008080000140831001c081a00', '32000c0000000080501101004c1126003400080310061d10061d10061d10061d10061c01065810080101000007c8078c06100000204f80007f000003070107010c07032c08fc80095a800afc08fb800b5a095b800afb08fa800b5b095c800afa08f9800b5c095d800af908f8800b5d095e800af808f7800b5e095f800af708f6800b5f0960800af608f5800b600961800af508f4800b610962800af408f3800b620963800af308f2800b630964800af208f1800b640965800af108f0800b650966800af008ef800b660967800aef08ee800b670968800aee08ed800b68096c800aed08ec800b6c096d800aec08eb800b6d096e800aeb08ea800b6e096f800aea08e9800b6f0970800ae908e8800b700971800ae808e7800b710972800ae708e6800b720973800ae608e5800b730974800ae508e4800b740975800ae408e3800b750976800ae308e2800b760977800ae208e1800b770978800ae108e0800b780979800ae008df800b79097a800adf08de800b7a097b800ade08dd800b7b097c800add08dc800b7c097d800adc08db800b7d097e800adb08da800b7e097f800ada08d9800b7f0980800ad908d8800b800981800ad808d7800b810982800ad708d6800b820983800ad608d5800b830984800ad508d4800b840985800ad408d3800b850986800ad308d2800b860987800ad208d1800b870988800ad108d0800b880989800ad008cf800b89098a800acf08ce800b8a098b800ace08cd800b8b098c800acd08cc800b8c098d800acc08cb800b8d098e800acb08ca800b8e098f800aca08c9800b8f0990800ac908c8800b900991800ac808c7800b910992800ac708c6800b920993800ac608c5800b930994800ac508c4800b940995800ac408c3800b950996800ac308c2800b960997800ac208c1800b970998800ac108c0800b980999800ac008bf800b99099a800abf08be800b9a099b800abe08bd800b9b099c800abd08bc800b9c099d800abc08bb800b9d099e800abb08ba800b9e099f800aba08b9800b9f09a0800ab908b8800ba00801800ab808b7800a010802800ab708b6800a020803800ab608b5800a030804802003070404020000000000002f0004009000000029000400000000003500040010000000']),
|
minor=0x8,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x0,
|
||||||
|
a0=0x0,
|
||||||
|
a1=0x0,
|
||||||
|
blobs=[
|
||||||
|
'23000000320074000000008000200000502077322820020030200000082110000c211000482105004c2105002020000024200000582000005c20000060204300682014006c2001247020012c842020008c20900190202c01942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc200000a101d0200000a10132004c0000000080dc20e803e0206401e420d002e8200001ec201400f0200500fc200000b8203a00140800000008040008080000080802001408300008080300140831001c081a004c11240050110000',
|
||||||
|
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
|
||||||
|
'29000400000000003500040000000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0xa,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x0,
|
||||||
|
a0=0x0,
|
||||||
|
a1=0x0,
|
||||||
|
blobs=[
|
||||||
|
'230000003200680000000080002000002020000024200000382000002820df0b2c20df0b302000003420000050200a005c20000064204300602000004c2000006c20100070201000742005007820050084202000b4200000b8203b00bc201400c0200200c4200100c82002007403000233001c000000008054202a2203005820272f0300cc200000ef03d0200000ef033200480000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203b00002804001428000008280000082800001428300008280000142831001c281a006411240068110000',
|
||||||
|
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
|
||||||
|
'29000400000000003500040000000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0xb,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x0,
|
||||||
|
a0=0x0,
|
||||||
|
a1=0x0,
|
||||||
|
blobs=[
|
||||||
|
'230000003200680000000080002000002020000024200000382000002820df0b2c20df0b302000003420000050200a005c20000064204300602000004c2000006c20100070201000742005007820050084202000b4200000b8203b00bc201400c0200200c4200100c82002007403000233001c000000008054202a2203005820272f0300cc200000ef03d0200000ef033200480000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203b00002804001428000008280000082800001428300008280000142831001c281a006411240068110000',
|
||||||
|
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
|
||||||
|
'29000400000000003500040000000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x14,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x0,
|
||||||
|
a0=0x0,
|
||||||
|
a1=0x0,
|
||||||
|
blobs=[
|
||||||
|
'230000003200680000000080002000002020000024200000382000002820df0b2c20df0b302000003420000050200a005c20000064204300602000004c2000006c20100070201000742005007820050084202000b4200000b8203b00bc201400c0200200c4200100c82002007403000233001c000000008054202a2203005820272f0300cc200000ef03d0200000ef033200480000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203b00002804001428000008280000082800001428300008280000142831001c281a006411240068110000',
|
||||||
|
'2a00080020010100100100002c002800802080200000000000013f4000000000080f080f00000000279c1000279c10000000000000000000340040000300000007160000240a59085a0701c9500aaa07010ada08db0701c9460b2107010800800a0088c9590a5a07010aa908aa0701c91f0ac900000c040100000000',
|
||||||
|
'29000400000000003500040000000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x6,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x885,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082150000c210000482105004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601066310250101000007c8078c06ff4f80006d0300200307030b90098db08d099186890b9108c180910ac190ba2c928f099382890b938889898908c881910ac8888a9189099a82890b9a8889898908d081910ad0888a9189080282890a02095a80890b5a888908d981890ad98891898a095e81890b5e8889898908e181890ae18891898a096481890b64888989096e8108e9810b6e880ae9889191ba096f828f0b6f8889918908f082890af08891898a097681890b7690b9928f08f882910af8908a8a91097c818a0b7c88090181890b018889892491097f818a0b7f900908818a0b0890898a910c0703030720040200002f0004007000000029000400700000003500040080000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x7,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x885,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082150000c210000482105004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601066310250101000007c8078c06ff4f80006d0300200307030b90098db08d099186890b9108c180910ac190ba2c928f099382890b938889898908c881910ac8888a9189099a82890b9a8889898908d081910ad0888a9189080282890a02095a80890b5a888908d981890ad98891898a095e81890b5e8889898908e181890ae18891898a096481890b64888989096e8108e9810b6e880ae9889191ba096f828f0b6f8889918908f082890af08891898a097681890b7690b9928f08f882910af8908a8a91097c818a0b7c88090181890b018889892491097f818a0b7f900908818a0b0890898a910c0703030720040200002f0004007000000029000400700000003500040080000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x0,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x1055,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482103004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601066310250101000007c8078c06ff4f80006d0300200307030b90098db08d099186890b9108c180910ac190ba2c928f099382890b938889898908c881910ac8888a9189099a82890b9a8889898908d081910ad0888a9189080282890a02095a80890b5a888908d981890ad98891898a095e81890b5e8889898908e181890ae18891898a096481890b64888989096e8108e9810b6e880ae9889191ba096f828f0b6f8889918908f082890af08891898a097681890b7690b9928f08f882910af8908a8a91097c818a0b7c88090181890b018889892491097f818a0b7f900908818a0b0890898a910c0703030720040200002f0004007000000029000400700000003500040080000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x0,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x1825,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601062810250101000007c8078c06ff4f80006d0300200307030990098db00b90880991858e08c1810b9190910ac1b828928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f812089920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x0,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xb5,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482106004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c111e0034007801000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001023171023171023161023161023160106635205001025010100000007c8078c06ff00004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x0,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x1ff5,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482106004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601062810250101000007c8078c06ff4f80006d0300200307030990098db00b90880991858e08c1810b9190910ac1b828928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f812089920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x7,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x1825,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601065010240101000007c8078c06ff00004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x0,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xe4,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c111e00340070010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221410221410221410221410221401066510250101000007c8078c06ff4f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c0703030720040200002f0004006400000029000400700000003500040080000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x0,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xed,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482104004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c111e00340074010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601065010240101000007c8078c06ff00004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x7,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x143b,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082138000c210000482108004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200200c4200100c82002003300100000000080cc200000d600d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c1117003400340200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101c11101c11101c11101c11101c10010657101e0101000007c8078c06ff00004f80006d03002c03070308c608c709930703800ac60994800ac70995800b930996800b940997800b950998800b9608c8800b9708ca800b9808cb800ac808cc800aca08ce800acb08cf800acc099a800ace099b800acf099c800b9a099d800b9b099e800b9c099f800b9d08d0800b9e08d2800b9f08d3800ad008d4800ad208d6800ad308d7800ad40802800ad60803800ad7095a800a02095b800a03095c800b5a095d800b5b08d9800b5c08da800b5d08db800ad908dd800ada08de800adb08df800add095e800ade095f800adf0960800b5e0961800b5f0962800b600963800b6108e1800b6208e2800b6308e3800ae108e5800ae208e6800ae308e7800ae50964800ae60965800ae70966800b640967800b650968800b66096e800b6708e9800b6808ea800b6e08eb800ae908ed800aea08ef800aeb08ee800aed096f800aef0970800aee0971800b6f0972800b700974800b710975800b7208f0800b7408f1800b7508f2800af008f4800af108f5800af208f6800af40976800af50977800af60979800b760978800b77097a800b79097b800b7808f8800b7a08fa800b7b08fc800af808fd800afa08fe800afc0900800c2007030307200402002f0004005400000029000400580000003500040068000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x7,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xb3,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082140000c210000482106004c210000582000005c2000006020000068200a006c20012970200121742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200100c4200100c82002003300100000000080cc2000002c01d0200000a1013200440000000080dc205302e0206401e420a901e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c11180034003c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101c11101c11101c11101c11101c10010657101e0101000007c8078c06ff00004f80006d03002c0308c608c70703800ac60993800ac70994800b930995800b940996800b950997800b960998800b9708c8800b9808ca800ac808cb800aca08cc800acb08ce800acc08cf800ace099a800acf099b800b9a099c800b9b099d800b9c099e800b9d099f800b9e08d0800b9f08d2800ad008d3800ad208d4800ad308d6800ad408d7800ad60802800ad70803800a02095a800a03095b800b5a095c800b5b095d800b5c08d9800b5d08da800ad908db800ada08dd800adb08de800add08df800ade095e800adf095f800b5e0960800b5f0961800b600962800b610963800b6208e1800b6308e2800ae108e3800ae208e5800ae308e6800ae508e7800ae60964800ae70965800b640966800b650967800b660968800b67096e800b6808e9800b6e08ea800ae908eb800aea08ed800aeb08ef800aed08ee800aef096f800aee0970800b6f0971800b700972800b710974800b720975800b7408f0800b7508f1800af008f2800af108f4800af208f5800af408f6800af50976800af60977800b760979800b770978800b79097a800b78097b800b7a08f8800b7b08fa800af808fc800afa08fd800afc08fe800afd090080808080240c0703030720040200000000002f0004005400000029000400580000003500040068000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x0,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xe1,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032006c000000008020200400242000005020773628200100302001003c208000082138000c210000482105004c210000582000005c2000006020000068200a006c20014970200141742001887820018084203000942001809c200902a0200b19bc201400c0200200c4200100c82002003300100000000080cc2000006401d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c11160034001402000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101b10101b10101b10101b0f101b0f010656101e0101000007c8078c06ff4f80006d03002c03070308c108bf098f0703800ac10990800abf098d800b8f0991800b900992800b8d08c5800b9108c3800b9208c6800ac508c4800ac308cb800ac608c7800ac40993800acb0994800ac70995800b930997800b940996800b950998800b9708ce800b9608cc800b9808cf800ace08d0800acc08d2800acf08dd800ad0099a800ad2099b800add099c800b9a0803800b9b095a800b9c095b800a0308de800b5a08df800b5b08e1800ade08eb800adf08ed800ae108f1800aeb095c800aed0962800af10963800b5c096f800b620970800b630971800b6f08f2800b7008f5800b7108f6800af208fa800af508f8800af608fc800afa0974800af80976800afc097b800b74097a800b76097f800b7b097e800b7a08fd800b7f08fe800b7e090b800afd090c800afe090d800b0b090f800b0c0980800b0d0982800b0f0983800b80097d800b820978800b83097c800b7d0914800b780908800b7c0909800b140907800b080905800b090904800b070979800b050977800b040975800b790972800b77096c800b750936800b7209348080800c20070303072004020000002f0004004e00000029000400540000003500040064000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x0,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x8b1,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032006c000000008020200400242000005020773628200100302001003c208000082138000c210000482107004c210000582000005c2000006020000068200a006c20014970200141742001887820018084203000942001809c200902a0200b19bc201400c0200200c4200100c82002003300100000000080cc2000002c00d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c11160034001402000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101b10101b10101b10101b0f101b0f010656101e0101000007c8078c06ff4f80006d03002c03070308c108bf098f0703800ac10990800abf098d800b8f0991800b900992800b8d08c5800b9108c3800b9208c6800ac508c4800ac308cb800ac608c7800ac40993800acb0994800ac70995800b930997800b940996800b950998800b9708ce800b9608cc800b9808cf800ace08d0800acc08d2800acf08dd800ad0099a800ad2099b800add099c800b9a0803800b9b095a800b9c095b800a0308de800b5a08df800b5b08e1800ade08eb800adf08ed800ae108f1800aeb095c800aed0962800af10963800b5c096f800b620970800b630971800b6f08f2800b7008f5800b7108f6800af208fa800af508f8800af608fc800afa0974800af80976800afc097b800b74097a800b76097f800b7b097e800b7a08fd800b7f08fe800b7e090b800afd090c800afe090d800b0b090f800b0c0980800b0d0982800b0f0983800b80097d800b820978800b83097c800b7d0914800b780908800b7c0909800b140907800b080905800b090904800b070979800b050977800b040975800b790972800b77096c800b750936800b7209348080800c20070303072004020000002f0004004e00000029000400540000003500040064000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x0,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xea,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320070000000008020200400242000005020773628200100302001003c208000082138000c210000482106004c210000582000005c2000006020000068200a006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300bc201400c0200200c4200100c82002003300100000000080cc200000d600d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c11170034003002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000101b11101b11101b11101b11101b1001064d101d0101000007c8078c06ff00004f80006d03002c03070308c608c709930703800ac60994800ac70995800b930996800b940997800b950998800b9608c8800b9708ca800b9808cb800ac808cc800aca08ce800acb08cf800acc099a800ace099b800acf099c800b9a099d800b9b099e800b9c099f800b9d08d0800b9e08d2800b9f08d3800ad008d4800ad208d6800ad308d7800ad40802800ad60803800ad7095a800a02095b800a03095c800b5a095d800b5b08d9800b5c08da800b5d08db800ad908dd800ada08de800adb08df800add095e800ade095f800adf0960800b5e0961800b5f0962800b600963800b6108e1800b6208e2800b6308e3800ae108e5800ae208e6800ae308e7800ae50964800ae60965800ae70966800b640967800b650968800b66096e800b6708e9800b6808ea800b6e08eb800ae908ed800aea08ef800aeb08ee800aed096f800aef0970800aee0971800b6f0972800b700974800b710975800b7208f0800b7408f1800b7508f2800af008f4800af108f5800af208f6800af40976800af50977800af60979800b760978800b77097a800b79097b800b7808f8800b7a08fa800b7b08fc800af808fd800afa08fe800afc0900800c2007030307200402002f0004005400000029000400540000003500040064000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x0,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x199,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'23000000200008000020008000000100320074000000008020200400242000005020773628200100302001003c208000082138000c210000482107004c210000582000005c20000060200000682005006c20014970200141742001887820018084202000942001809c200902a0200b19b4200300b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203a00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c111e00340078010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010221710221710221610221610221601065010250101000007c8078c06ff0000000000004f80006d0300280307030990098db00b90880991858e08c1810b9190910ac1b8928a0993878a890b9388898908c88191890ac8889289099a818a890b9a88898908d08191890ad08892890802818a095a810a0288890b5a8808d98189890ad9908989095e8289890b5e88898908e18189890ae190898909648289890b648889096e8108e981890b6e880ae99091b9096f828a8f0b6f88918908f0818a890af090898909768289910b76b8918a08f88792910af8888a92097c81898a0b7c09018089890b01888991097f8189920b7f09088089920b088889920c07030307200402000000002f0004007000000029000400700000003500040080000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x14,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x8f3,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032006000000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20700070207000742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002a0030000330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c64200050630c642000606c0c64200070620c642000806b0c64200090610c642000a06a0c642000b0600c642000c0690c642000d05f0c642000e05e0c642000f04f0c642000005d0c642000104e0c642000205c0c642000304d0c642000405b0c642000504c0c642000605a0c642000704b0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d10c642000d02b0c642000e0d20c642000f02a0c64200000d30c64200010290c64200020d60c64200030280c64200040d70c642000501d0c64200060d80c642000701c0c64200080d90c642000901b0c642000a0da0c642000b01a0c642000c0de0c642000d0190c642000e0df0c642000f0150c64200000e00c64200010140c64200020e10c64200030130c64200040e20c64200050120c64200060e40c64200070110c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
|
||||||
|
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b070100002403089808a9089908a8089a08a7089b08a6089c08a4089d08a3089e08a2089f08a1c0102c03088808b9088908b8088a08b7088b08b3089208b2089308b1089408b0089508afc01003087108c6087208c5087d08c2087e08c1087f08c0088008bf088108bb088708bac0100628070103084f085e085f08690860086a0861086b0862086c086308c9086f08c8087008c7c010030847082e0848082f08490830084a0831084b085a084c085b084d085c084e085dc01003082a08d2082b08d1082c08ce083808cd083908cc083a08cb083b08ca0846082dc0100632070103081508df081908de081a08da081b08d9081c08d8081d08d7082808d6082908d3c01059940b03080a08e8080b08e7080c08e6080d08e5081108e4081208e2081308e1081408e0c0102403080008f1080108f0080208ef080308ee080408ed080508ec080608eb080708eac0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x14,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x8f6,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20500070205000742000007820000084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c64200050630c642000606c0c64200070620c642000806b0c64200090610c642000a06a0c642000b0600c642000c0690c642000d05f0c642000e05e0c642000f04f0c642000005d0c642000104e0c642000205c0c642000304d0c642000405b0c642000504c0c642000605a0c642000704b0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
|
||||||
|
'32000c0000000080681101006411260034001c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b070100000720240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c90863086c0862086b0861086a08600869085f085e084fc01003085d084e085c084d085b084c085a084b0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c0100308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c010070320030c07030703072004020000004200080002089000000000002f00040038000000',
|
||||||
|
'2f00040038000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x14,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x121,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20720070207200742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
|
||||||
|
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a120100000620102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063007010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x15,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x121,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20720070207200742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
|
||||||
|
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a120100000620102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063007010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x14,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xb4b,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20660070206600742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
|
||||||
|
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x15,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xb4b,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20660070206600742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
|
||||||
|
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d00005e00004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x14,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xb4b,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050201f015c200000602000004c2003006c20720070207200742004007820040084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
|
||||||
|
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d03005e03004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x15,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xb4b,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050201f015c200000602000004c2003006c20720070207200742004007820040084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
|
||||||
|
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d03005e03004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x14,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xb4d,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20600070206000742002007820020084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
|
||||||
|
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d01005e01004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x15,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xb4d,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20600070206000742002007820020084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'330064030000008064200000a10c642000109f0c64200020a20c642000309e0c64200040a30c642000509d0c64200060a40c642000709c0c64200080a60c642000909b0c642000a0a70c642000b09a0c642000c0a80c642000d0990c642000e0a90c642000f0980c64200000af0c64200010950c64200020b00c64200030940c64200040b10c64200050930c64200060b20c64200070920c64200080b30c642000908b0c642000a0b70c642000b08a0c642000c0b80c642000d0890c642000e0b90c642000f0880c64200000ba0c64200010870c64200020bb0c64200030810c64200040bf0c64200050800c64200060c00c642000707f0c64200080c10c642000907e0c642000a0c20c642000b07d0c642000c0c50c642000d0720c642000e0c60c642000f0710c64200000c70c64200010700c64200020c80c642000306f0c64200040c90c642000506d0c642000607a0c642000706c0c64200080790c642000906b0c642000a0780c642000b06a0c642000c06e0c642000d0690c642000e0630c642000f05e0c64200000620c642000105d0c64200020610c642000305c0c64200040600c642000505b0c642000605f0c642000705a0c64200080310c642000904a0c642000a0300c642000b0490c642000c02f0c642000d0480c642000e02e0c642000f0470c642000002d0c64200010460c64200020ca0c642000303b0c64200040cb0c642000503a0c64200060cc0c64200070390c64200080cd0c64200090380c642000a0ce0c642000b02c0c642000c0d00c642000d02b0c642000e0d10c642000f02a0c64200000d20c64200010290c64200020d30c64200030280c64200040d60c642000501c0c64200060d70c642000701b0c64200080d80c642000901a0c642000a0d90c642000b0190c642000c0da0c642000d0150c642000e0df0c642000f0140c64200000e00c64200010130c64200020e10c64200030120c64200040e20c64200050110c64200060e40c642000700e0c64200080e50c642000900d0c642000a0e60c642000b00c0c642000c0e70c642000d00b0c642000e0e80c642000f00a0c64200000ea0c64200010070c64200020eb0c64200030060c64200040ec0c64200050050c64200060ed0c64200070040c64200080ee0c64200090030c642000a0ef0c642000b0020c642000c0f00c642000d0010c642000e0f10c642000f0000c',
|
||||||
|
'32000c000000008068110100641126003400180200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a13102a13102a12010000061e102d0101000007c8078c060b5d01005e01004f80005080006d030059940b07010000240308a1089f08a2089e08a3089d08a4089c08a6089b08a7089a08a8089908a90898c0102c0308af089508b0089408b1089308b2089208b3088b08b7088a08b8088908b90888c0100308ba088708bb088108bf088008c0087f08c1087e08c2087d08c5087208c60871c010062807010308c7087008c8086f08c9086d087a086c0879086b0878086a086e08690863085ec010030862085d0861085c0860085b085f085a0831084a08300849082f0848082e0847c01003082d084608ca083b08cb083a08cc083908cd083808ce082c08d0082b08d1082ac010063207010308d2082908d3082808d6081c08d7081b08d8081a08d9081908da081508df0814c01059940b0308e0081308e1081208e2081108e4080e08e5080d08e6080c08e7080b08e8080ac010240308ea080708eb080608ec080508ed080408ee080308ef080208f0080108f10800c0100c0720070c2003040200004200080002089000000000002f00040038000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x15,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x130,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20400070204000742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003',
|
||||||
|
'330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c',
|
||||||
|
'32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x15,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x518,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20640070206400742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003',
|
||||||
|
'330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c',
|
||||||
|
'32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x15,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xbe1,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20550070205500742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003',
|
||||||
|
'330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c',
|
||||||
|
'32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x15,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xbe2,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c00000000802020040024200000382000002820df0b2c20df0b302000003420000050200a015c200000602000004c2003006c20500070205000742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a003200b4020000008074030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030001740300037403000174030003740300017403000374030005740300077403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030001740300037403001574030017740300017403000374030015740300177403000174030003740300157403001774030015740300177403000174030003',
|
||||||
|
'330064030000008064200000e40c64200010050c64200020e60c64200030040c64200040e70c64200050020c64200060eb0c64200070000c64200080ec0c64200090010c642000a0ed0c642000b0030c642000c0f10c642000d0060c642000e0f00c642000f0070c64200000ef0c64200010080c64200020ee0c642000300a0c64200040ea0c642000500b0c64200060e80c642000700c0c64200080e50c642000900d0c642000a0e10c642000b0100c642000c0e00c642000d0140c642000e0df0c642000f0160c64200000de0c64200010190c64200020dc0c642000301d0c64200040db0c642000501e0c64200060da0c64200070220c64200080d30c64200090250c642000a0d10c642000b0270c642000c0cb0c642000d02b0c642000e0ca0c642000f02d0c642000003a0c64200010310c642000203b0c64200030320c642000403d0c64200050370c642000603e0c64200070390c64200080460c642000903c0c642000a0470c642000b03f0c642000c0490c642000d0400c642000e04a0c642000f0450c642000004c0c64200010480c642000204d0c642000304b0c642000405c0c642000504e0c642000605d0c642000704f0c642000805e0c64200090500c642000a0610c642000b0550c642000c0620c642000d05a0c642000e0630c642000f05b0c64200000680c642000105f0c64200020690c64200030600c642000406a0c64200050640c642000606d0c64200070650c642000806e0c642000906b0c642000a06f0c642000b06c0c642000c0700c642000d0710c642000e0c90c642000f0720c64200000c80c64200010770c64200020c60c64200030780c64200040c20c642000507c0c64200060c10c642000707f0c64200080c00c64200090820c642000a0bd0c642000b0840c642000c0bc0c642000d0870c642000e0b80c642000f08b0c64200000b50c642000108f0c64200020b20c64200030910c64200040af0c64200050940c64200060ae0c64200070980c64200080ad0c642000909a0c642000a0ac0c642000b09e0c642000c0ab0c642000d09f0c642000e0a90c642000f09d0c64200000a80c642000109c0c64200020a70c642000309b0c64200040a60c64200050990c64200060a40c64200070960c64200080a30c64200090950c642000a0a20c642000b0930c642000c0a10c642000d0920c642000e0a90c642000f09d0c',
|
||||||
|
'32000c0000000080681101006411260034000c0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007e007e0102a0d102a0d102a0e0100000628102c0101000007c8078c061400004f80005080006d030059940b07010000240308e4080508e6080408e7080208eb080008ec080108ed080308f1080608f00807c0102c0308ef080808ee080a08ea080b08e8080c08e5080d08e1081008e0081408df0816c0100308de081908dc081d08db081e08da082208d3082508d1082708cb082b08ca082dc01003083a0831083b0832083d0837083e08390846083c0847083f08490840084a0845c01003084c0848084d084b085c084e085d084f085e0850086108550862085a0863085bc010030868085f08690860086a0864086d0865086e086b086f086c0870087108c90872c0100308c8087708c6087808c2087c08c1087f08c0088208bd088408bc088708b8088bc0100308b5088f08b2089108af089408ae089808ad089a08ac089e08ab089f08a9089dc010240308a9089d08a8089c08a7089b08a6089908a4089608a3089508a2089308a10892c0100c072c20030703070304020000004200080002089000000000002f00040028000000290004009000000035000400a0000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0xb,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x194,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032005c0000000080202004002820ff0b2c20f60b6c202f007020000074201000782000005c2000006020000064200000502000005420151d84202000942001809c200902a0200b19b4200000b8203a00bc201400c0200200c4200200c82008003300100000000080cc2000004900d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0201400f8200500fc200000b8203b00002804001428000008280000082810001428180008281100142819001c281a00',
|
||||||
|
'32001400000000806811010064111f007c1700007017010033001c00000000809c1701000000ac1700900100b01754000000b417007200003400500010061110061110061110061110061001068010080101000007c80764060000002003070107010c07840a640863c91e2cc9159107010a9dc9110701030a3208330701c90f20c91e070304020000000000',
|
||||||
|
'2f0004005400000029000400000000003500040010000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x0,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x179,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032007800000000802020040024200000382000002820df0b2c20df0b30200000342000003c20000040200000442000004820000050200a005c20000060200000642000004c200300002100006c2030007020300040210000742006007820060084202000b4200000b8203a00bc201400c0200200c4200100c820020033001c000000008054202f27030058202f270300cc200000ef03d0200000ef033200440000000080dc20e803e020e803e420d002e820d002f0200500f8200500fc200000b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'320014000000008068110100641126007c1700007017010033001c00000000809c1701000000ac1700900100b01738000000b417009000003400040310060b10060b10060b10060b10060c01064e10080101000007c80764060000002003070107010c2c078408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b800aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a720871800ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d1800a2c082b800ad108d2800a2b082a800ad208d3800a2a0829800ad308d6800a290828800ad608d7800a28081d800ad708d8800a1d081c800ad808d9800a1c081b800ad908da800a1b081a800ada08de800a1a0819800ade08df800a190815800adf08e0800a150814800ae008e1800a140813800ae108e2800a130812800ae208e4800a120811800ae408e5800a11080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708ea800a0b080a800aea08eb800a0a0807800aeb08ec800a070806800aec08ed800a060805800aed08ee800a050804800aee08ef800a040803800aef08f0800a030802800af008f1800a020801800af108f2800a010800802007032003070307030402000000',
|
||||||
|
'2f0004003800000029000400000000003500040010000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0xa,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x117,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032006400000000802020040024200000382000002820df0b2c20df0b30200000342000003c2080004020800050200a005c200000602000004c2003006c20680070206800742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'32000c000000008068110100641126003400ac0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102b0e102b0e102b0e102b0e01000000061e10301001000007c80764060b4f80005080006d030007010000006d0300200307010007032408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b802c0aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a72087180062807010ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d1800a2c082b800ad108d2800a2b082a80063207010ad208d3800a2a0829800ad308d6800a290828800ad608d7800a28081d800ad708d8800a1d081c800ad808d9800a1c081b800ad908da800a1b081a800ada08de800a1a0819800ade08df800a190815800adf08e0800a150814800ae008e1800a140813800ae108e2800a130812800ae208e4800a120811800ae408e5800a11080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708ea800a0b080a800aea08eb800a0a0807800aeb08ec800a070806800aec08ed800a06080580240aed08ee800a050804800aee08ef800a040803800aef08f0800a030802800af008f1800a020801800af108f2800c0a01080080070103040200000000002f00040038000000',
|
||||||
|
'290004009400000035000400a4000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0xb,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x117,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032006400000000802020040024200000382000002820df0b2c20df0b30200000342000003c2080004020800050200a005c200000602000004c2003006c20680070206800742001007820010084202000b4200000bc201400c0200200c4200100c820020074030002330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'32000c000000008068110100641126003400ac0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102b0e102b0e102b0e102b0e01000000061e10301001000007c80764060b4f80005080006d030007010000006d0300200307010007032408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b802c0aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a72087180062807010ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d1800a2c082b800ad108d2800a2b082a80063207010ad208d3800a2a0829800ad308d6800a290828800ad608d7800a28081d800ad708d8800a1d081c800ad808d9800a1c081b800ad908da800a1b081a800ada08de800a1a0819800ade08df800a190815800adf08e0800a150814800ae008e1800a140813800ae108e2800a130812800ae208e4800a120811800ae408e5800a11080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708ea800a0b080a800aea08eb800a0a0807800aeb08ec800a070806800aec08ed800a06080580240aed08ee800a050804800aee08ef800a040803800aef08f0800a030802800af008f1800a020801800af108f2800c0a01080080070103040200000000002f00040038000000',
|
||||||
|
'290004009400000035000400a4000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0xb,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0x126,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032007000000000802020040024200000382000002820df0b2c20df0b30200000342000003c2080004020800050200a005c200000602000004c2003006c2068007020680074200100782001006420000084202000b4200000b8203a00bc201400c0200200c4200100c820020074030000a0030f00330028000000008054202a2203005820272f03004420898103004820868e0300cc200000ef03d0200000ef033200400000000080dc20fa00e020fa00e420b400e820b400f0200500f8200500b8203a00002804001428000008280000082800001428300008280000142831001c281a00',
|
||||||
|
'32000c000000008068110100641126003400ac0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102b0e102b0e102b0e102b0e01000000061e10301001000007c80764060b4f80005080006d030007010000006d0300200307010007032408a180089f800aa108a2800a9f089e800aa208a3800a9e089d800aa308a4800a9d089c800aa408a6800a9c089b802c0aa608a7800a9b089a800aa708a8800a9a0899800aa808a9800a990898800aa908af800a980895800aaf08b0800a950894800ab008b1800a940893800ab108b2800a930892800ab208b3800a92088b800ab308b7800a8b088a800ab708b8800a8a0889800ab808b9800a890888800ab908ba800a880887800aba08bb800a870881800abb08bf800a810880800abf08c0800a80087f800ac008c1800a7f087e800ac108c2800a7e087d800ac208c5800a7d0872800ac508c6800a72087180062807010ac608c7800a710870800ac708c8800a70086f800ac808c9800a6f0863800ac9086c800a630862800a6c086b800a620861800a6b086a800a610860800a6a0869800a60085f800a69085e800a5f084f800a5e085d800a4f084e800a5d085c800a4e084d800a5c085b800a4d084c800a5b085a800a4c084b800a5a0831800a4b084a800a310830800a4a0849800a30082f800a490848800a2f082e800a480847800a2e082d800a470846800a2d08ca800a46083b800aca08cb800a3b083a800acb08cc800a3a0839800acc08cd800a390838800acd08ce800a38082c800ace08d0800a2c082b800ad008d1800a2b082a80063207010ad108d2800a2a0829800ad208d3800a290828800ad308d6800a28081c800ad608d7800a1c081b800ad708d8800a1b081a800ad808d9800a1a0819800ad908da800a190815800ada08df800a150814800adf08e0800a140813800ae008e1800a130812800ae108e2800a120811800ae208e4800a11080e800ae408e5800a0e080d800ae508e6800a0d080c800ae608e7800a0c080b800ae708e8800a0b080a800ae808ea800a0a0807800aea08eb800a070806800aeb08ec800a06080580240aec08ed800a050804800aed08ee800a040803800aee08ef800a030802800aef08f0800a020801800af008f1800c0a01080080070c03040200000000002f00040038000000290004009400000035000400a4000000'
|
||||||
|
]),
|
||||||
|
SensorCaptureProg(
|
||||||
|
major=0x6,
|
||||||
|
minor=0x0,
|
||||||
|
build=0x0,
|
||||||
|
u1=0x0,
|
||||||
|
dev_type=0xdb,
|
||||||
|
a0=0x18,
|
||||||
|
a1=0x19,
|
||||||
|
blobs=[
|
||||||
|
'2300000020000800002000800000010032007000000000802020050024200000502077362820010030200100082170000c210000482102004c210000582000005c20000060200000682005006c20012970200121742001887820018084202000942001809c200902a0200b19b4200000b8203b04bc201400c0200200c4200100c82002003300100000000080cc200000f503d0200000a1013200440000000080dc20e803e0206401e420d002e8200001f0200500f8200500fc200000b8203b00000804001408000008080000080800001408300008080000140831001c081a00',
|
||||||
|
'32000c0000000080501101004c1126003400080310061d10061d10061d10061d10061c01065810080101000007c8078c06100000204f80007f000003070107010c07032c08fc80095a800afc08fb800b5a095b800afb08fa800b5b095c800afa08f9800b5c095d800af908f8800b5d095e800af808f7800b5e095f800af708f6800b5f0960800af608f5800b600961800af508f4800b610962800af408f3800b620963800af308f2800b630964800af208f1800b640965800af108f0800b650966800af008ef800b660967800aef08ee800b670968800aee08ed800b68096c800aed08ec800b6c096d800aec08eb800b6d096e800aeb08ea800b6e096f800aea08e9800b6f0970800ae908e8800b700971800ae808e7800b710972800ae708e6800b720973800ae608e5800b730974800ae508e4800b740975800ae408e3800b750976800ae308e2800b760977800ae208e1800b770978800ae108e0800b780979800ae008df800b79097a800adf08de800b7a097b800ade08dd800b7b097c800add08dc800b7c097d800adc08db800b7d097e800adb08da800b7e097f800ada08d9800b7f0980800ad908d8800b800981800ad808d7800b810982800ad708d6800b820983800ad608d5800b830984800ad508d4800b840985800ad408d3800b850986800ad308d2800b860987800ad208d1800b870988800ad108d0800b880989800ad008cf800b89098a800acf08ce800b8a098b800ace08cd800b8b098c800acd08cc800b8c098d800acc08cb800b8d098e800acb08ca800b8e098f800aca08c9800b8f0990800ac908c8800b900991800ac808c7800b910992800ac708c6800b920993800ac608c5800b930994800ac508c4800b940995800ac408c3800b950996800ac308c2800b960997800ac208c1800b970998800ac108c0800b980999800ac008bf800b99099a800abf08be800b9a099b800abe08bd800b9b099c800abd08bc800b9c099d800abc08bb800b9d099e800abb08ba800b9e099f800aba08b9800b9f09a0800ab908b8800ba00801800ab808b7800a010802800ab708b6800a020803800ab608b5800a030804802003070404020000000000002f0004009000000029000400000000003500040010000000'
|
||||||
|
]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
|
class DeviceInfo:
|
||||||
class DeviceInfo():
|
def __init__(self, major: int, type: int, version: int, version_mask: int, name: str):
|
||||||
def __init__(self, major, type, version, version_mask, name):
|
|
||||||
self.major, self.type, self.version, self.version_mask, self.name = major, type, version, version_mask, name
|
self.major, self.type, self.version, self.version_mask, self.name = major, type, version, version_mask, name
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "DeviceInfo(0x%04x, 0x%04x, 0x%02x, 0x%02x, '%s')" % (
|
return "DeviceInfo(0x%04x, 0x%04x, 0x%02x, 0x%02x, '%s')" % (
|
||||||
self.major, self.type, self.version, self.version_mask, self.name
|
self.major, self.type, self.version, self.version_mask, self.name)
|
||||||
)
|
|
||||||
|
|
||||||
dev_info_table=[
|
|
||||||
|
dev_info_table = [
|
||||||
DeviceInfo(0x0000, 0x0080, 0x00, 0x00, 'VSI 15A '),
|
DeviceInfo(0x0000, 0x0080, 0x00, 0x00, 'VSI 15A '),
|
||||||
DeviceInfo(0x0000, 0x0080, 0x00, 0x00, 'VSI 15A '),
|
DeviceInfo(0x0000, 0x0080, 0x00, 0x00, 'VSI 15A '),
|
||||||
DeviceInfo(0x0000, 0x0080, 0x00, 0x00, 'VSI 15A '),
|
DeviceInfo(0x0000, 0x0080, 0x00, 0x00, 'VSI 15A '),
|
||||||
|
|
@ -428,7 +427,8 @@ dev_info_table=[
|
||||||
DeviceInfo(0x0190, 0x2449, 0xa3, 0xff, '86C TM-P3569-001 '),
|
DeviceInfo(0x0190, 0x2449, 0xa3, 0xff, '86C TM-P3569-001 '),
|
||||||
]
|
]
|
||||||
|
|
||||||
def dev_info_lookup(major, ver):
|
|
||||||
|
def dev_info_lookup(major: int, ver: int):
|
||||||
fuzzy_match = None
|
fuzzy_match = None
|
||||||
|
|
||||||
for i in dev_info_table:
|
for i in dev_info_table:
|
||||||
|
|
@ -444,16 +444,19 @@ def dev_info_lookup(major, ver):
|
||||||
|
|
||||||
return fuzzy_match
|
return fuzzy_match
|
||||||
|
|
||||||
class FlashIcInfo():
|
|
||||||
def __init__(self, name, size, f18, jid0, jid1, f1b, f1c, f1e, secror_size, sector_erase_cmd, f25, f26):
|
class FlashIcInfo:
|
||||||
|
def __init__(self, name: str, size: int, f18: int, jid0: int, jid1: int, f1b: int, f1c: int,
|
||||||
|
f1e: int, secror_size: int, sector_erase_cmd: int, f25: int, f26: int):
|
||||||
self.name, self.size, self.f18, self.jid0, self.jid1, self.f1b, self.f1c, self.f1e, self.secror_size, self.sector_erase_cmd, self.f25, self.f26 = name, size, f18, jid0, jid1, f1b, f1c, f1e, secror_size, sector_erase_cmd, f25, f26
|
self.name, self.size, self.f18, self.jid0, self.jid1, self.f1b, self.f1c, self.f1e, self.secror_size, self.sector_erase_cmd, self.f25, self.f26 = name, size, f18, jid0, jid1, f1b, f1c, f1e, secror_size, sector_erase_cmd, f25, f26
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "FlashIcInfo('%s', %d, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % (
|
return "FlashIcInfo('%s', %d, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)" % (
|
||||||
self.name, self.size, self.f18, self.jid0, self.jid1, self.f1b, self.f1c, self.f1e, self.secror_size, self.sector_erase_cmd, self.f25, self.f26)
|
self.name, self.size, self.f18, self.jid0, self.jid1, self.f1b, self.f1c, self.f1e,
|
||||||
|
self.secror_size, self.sector_erase_cmd, self.f25, self.f26)
|
||||||
|
|
||||||
flash_ic_table=[
|
|
||||||
|
flash_ic_table = [
|
||||||
FlashIcInfo('M25P05-A', 65536, 0x5, 0x20, 0x20, 0x10, 0x8000, 0x0, 0x8000, 0xd8, 0x0, 0x4),
|
FlashIcInfo('M25P05-A', 65536, 0x5, 0x20, 0x20, 0x10, 0x8000, 0x0, 0x8000, 0xd8, 0x0, 0x4),
|
||||||
FlashIcInfo('M25P10-A', 131072, 0x10, 0x20, 0x20, 0x11, 0x8000, 0x0, 0x8000, 0xd8, 0x0, 0x4),
|
FlashIcInfo('M25P10-A', 131072, 0x10, 0x20, 0x20, 0x11, 0x8000, 0x0, 0x8000, 0xd8, 0x0, 0x4),
|
||||||
FlashIcInfo('M25P20', 262144, 0x11, 0x20, 0x20, 0x12, 0x0, 0x1, 0x10000, 0xd8, 0x0, 0x4),
|
FlashIcInfo('M25P20', 262144, 0x11, 0x20, 0x20, 0x12, 0x0, 0x1, 0x10000, 0xd8, 0x0, 0x4),
|
||||||
|
|
@ -476,10 +479,10 @@ flash_ic_table=[
|
||||||
FlashIcInfo('GD25Q80C', 1048576, 0x13, 0xc8, 0x40, 0x14, 0x0, 0x1, 0x1000, 0x20, 0x0, 0x4),
|
FlashIcInfo('GD25Q80C', 1048576, 0x13, 0xc8, 0x40, 0x14, 0x0, 0x1, 0x1000, 0x20, 0x0, 0x4),
|
||||||
]
|
]
|
||||||
|
|
||||||
def flash_ic_table_lookup(jedec_id0, jedec_id1, size):
|
|
||||||
|
def flash_ic_table_lookup(jedec_id0: int, jedec_id1: int, size: int):
|
||||||
for i in flash_ic_table:
|
for i in flash_ic_table:
|
||||||
if i.jid0 == jedec_id0 and i.jid1 == jedec_id1 and i.size == size:
|
if i.jid0 == jedec_id0 and i.jid1 == jedec_id1 and i.size == size:
|
||||||
return i
|
return i
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
|
|
||||||
import atexit
|
import atexit
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from validitysensor.usb import usb
|
|
||||||
from validitysensor.tls import tls
|
|
||||||
from validitysensor.sensor import sensor, reboot, RebootException
|
|
||||||
from validitysensor.flash import read_tls_flash
|
from validitysensor.flash import read_tls_flash
|
||||||
from validitysensor.init_flash import init_flash
|
|
||||||
from validitysensor.upload_fwext import upload_fwext
|
|
||||||
from validitysensor.init_db import init_db
|
from validitysensor.init_db import init_db
|
||||||
|
from validitysensor.init_flash import init_flash
|
||||||
|
from validitysensor.sensor import sensor, reboot, RebootException
|
||||||
|
from validitysensor.tls import tls
|
||||||
|
from validitysensor.upload_fwext import upload_fwext
|
||||||
|
from validitysensor.usb import usb
|
||||||
|
|
||||||
|
|
||||||
def close():
|
def close():
|
||||||
logging.debug('In atexit handler')
|
logging.debug('In atexit handler')
|
||||||
|
|
@ -24,16 +24,17 @@ def close():
|
||||||
finally:
|
finally:
|
||||||
usb.close()
|
usb.close()
|
||||||
|
|
||||||
|
|
||||||
def open_common():
|
def open_common():
|
||||||
init_flash()
|
init_flash()
|
||||||
usb.send_init()
|
usb.send_init()
|
||||||
tls.parseTlsFlash(read_tls_flash())
|
tls.parse_tls_flash(read_tls_flash())
|
||||||
tls.open()
|
tls.open()
|
||||||
upload_fwext()
|
upload_fwext()
|
||||||
sensor.open()
|
sensor.open()
|
||||||
init_db()
|
init_db()
|
||||||
|
|
||||||
# We must register atexit only after we opened usb device,
|
# We must register atexit only after we opened usb device,
|
||||||
# so that our atexit handler is called before pyusb's one and we can still talk to the device
|
# so that our atexit handler is called before pyusb's one and we can still talk to the device
|
||||||
#
|
#
|
||||||
# Don't attempt to autoreboot unless we finished initializing the sensor successfully.
|
# Don't attempt to autoreboot unless we finished initializing the sensor successfully.
|
||||||
|
|
@ -41,10 +42,12 @@ def open_common():
|
||||||
atexit.register(close)
|
atexit.register(close)
|
||||||
logging.debug('atexit registered')
|
logging.debug('atexit registered')
|
||||||
|
|
||||||
|
|
||||||
def open():
|
def open():
|
||||||
usb.open()
|
usb.open()
|
||||||
open_common()
|
open_common()
|
||||||
|
|
||||||
def open_devpath(busnum, address):
|
|
||||||
|
def open_devpath(busnum: int, address: int):
|
||||||
usb.open_devpath(busnum, address)
|
usb.open_devpath(busnum, address)
|
||||||
open_common()
|
open_common()
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
|
|
||||||
from struct import pack, unpack
|
|
||||||
import logging
|
import logging
|
||||||
|
from struct import pack, unpack
|
||||||
|
|
||||||
from .db import db
|
from .db import db
|
||||||
|
|
||||||
def machine_id_rec_value(b):
|
|
||||||
|
def machine_id_rec_value(b: str):
|
||||||
b = b.encode('utf-16le')
|
b = b.encode('utf-16le')
|
||||||
b = b + b'\0' * (0x94 - len(b))
|
b = b + b'\0' * (0x94 - len(b))
|
||||||
return pack('<HH', 0x102, len(b)) + b # 0x102 = Machine ID/GUID?
|
return pack('<HH', 0x102, len(b)) + b # 0x102 = Machine ID/GUID?
|
||||||
|
|
||||||
|
|
||||||
# This function is unused. It simply describes the Windows driver behavior.
|
# This function is unused. It simply describes the Windows driver behavior.
|
||||||
# TODO: make this GUID unique!
|
# TODO: make this GUID unique!
|
||||||
|
|
@ -24,15 +25,15 @@ def init_machine_guid(machine_guid='e7260876-58db-4d27-8c40-8d13110d6a71'):
|
||||||
|
|
||||||
if rc != machine_id_rec_value(machine_guid):
|
if rc != machine_id_rec_value(machine_guid):
|
||||||
u0, l = unpack('<HH', rc[:4])
|
u0, l = unpack('<HH', rc[:4])
|
||||||
b=rc[4:4+l]
|
b = rc[4:4 + l]
|
||||||
b=b.decode('utf-16le')
|
b = b.decode('utf-16le')
|
||||||
raise Exception('Machine GUID does not match the DB flash ownership record (%s).' % b)
|
raise Exception('Machine GUID does not match the DB flash ownership record (%s).' % b)
|
||||||
|
|
||||||
|
|
||||||
def init_db():
|
def init_db():
|
||||||
stg = db.get_user_storage(name='StgWindsor')
|
stg = db.get_user_storage(name='StgWindsor')
|
||||||
if stg == None:
|
if stg is None:
|
||||||
logging.info('Creating a new user storage object')
|
logging.info('Creating a new user storage object')
|
||||||
db.new_user_storate()
|
db.new_user_storate()
|
||||||
|
|
||||||
#init_machine_guid()
|
# init_machine_guid()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,61 +1,64 @@
|
||||||
|
|
||||||
import os
|
|
||||||
from struct import pack, unpack
|
|
||||||
from binascii import unhexlify
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from hashlib import sha256
|
|
||||||
import hmac
|
import hmac
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import typing
|
||||||
|
from binascii import unhexlify
|
||||||
|
from hashlib import sha256
|
||||||
|
from struct import pack, unpack
|
||||||
|
|
||||||
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives import hashes
|
from cryptography.hazmat.primitives import hashes
|
||||||
from cryptography.hazmat.primitives.asymmetric import ec
|
from cryptography.hazmat.primitives.asymmetric import ec
|
||||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||||
from cryptography.hazmat.backends import default_backend
|
|
||||||
|
|
||||||
|
from .blobs import reset_blob
|
||||||
|
from .flash import write_flash, erase_flash, call_cleanups, PartitionInfo, get_flash_info, FlashInfo
|
||||||
|
from .hw_tables import FlashIcInfo
|
||||||
|
from .sensor import reboot, RomInfo
|
||||||
from .tls import tls, hs_key, crt_hardcoded
|
from .tls import tls, hs_key, crt_hardcoded
|
||||||
from .usb import usb
|
from .usb import usb
|
||||||
from .flash import write_flash, erase_flash, call_cleanups, PartitionInfo, get_flash_info
|
|
||||||
from .sensor import reboot, RomInfo
|
|
||||||
from .util import assert_status, unhex
|
from .util import assert_status, unhex
|
||||||
from .blobs import reset_blob
|
|
||||||
|
|
||||||
flash_layout_hardcoded=[
|
flash_layout_hardcoded = [
|
||||||
# id type access offset size
|
# id type access offset size
|
||||||
# lvl
|
# lvl
|
||||||
PartitionInfo(1, 4, 7, 0x00001000, 0x00001000), # cert store
|
PartitionInfo(1, 4, 7, 0x00001000, 0x00001000), # cert store
|
||||||
PartitionInfo(2, 1, 2, 0x00002000, 0x0003e000), # xpfwext
|
PartitionInfo(2, 1, 2, 0x00002000, 0x0003e000), # xpfwext
|
||||||
PartitionInfo(5, 5, 3, 0x00040000, 0x00008000), # ???
|
PartitionInfo(5, 5, 3, 0x00040000, 0x00008000), # ???
|
||||||
PartitionInfo(6, 6, 3, 0x00048000, 0x00008000), # calibration data
|
PartitionInfo(6, 6, 3, 0x00048000, 0x00008000), # calibration data
|
||||||
PartitionInfo(4, 3, 5, 0x00050000, 0x00080000), # template database
|
PartitionInfo(4, 3, 5, 0x00050000, 0x00080000), # template database
|
||||||
]
|
]
|
||||||
|
|
||||||
partition_signature=unhex('''
|
partition_signature = unhex('''
|
||||||
1db02a886b007e2b47263bb8fe30bd64a1f58bea7b25f1e1ba9ae09add7ecff36333f8198339cdd713f043633710a17bc7b3f418f1d8ff435a1bf47f065dffca
|
1db02a886b007e2b47263bb8fe30bd64a1f58bea7b25f1e1ba9ae09add7ecff36333f8198339cdd713f043633710a17bc7b3f418f1d8ff435a1bf47f065dffca
|
||||||
727109152217fce73bf2bf8e01a1641f6a24b0c492a6a3f10114057275846842b1c8b66bd6700738524d4471bca3315ba23bb832743220ad195b60558aa79a3e
|
727109152217fce73bf2bf8e01a1641f6a24b0c492a6a3f10114057275846842b1c8b66bd6700738524d4471bca3315ba23bb832743220ad195b60558aa79a3e
|
||||||
deb2604834e2bb62e890b0ce405b3b8ef2fec2aab3e22bff23f89a58ff0dc015fece5d3ed3f5496ace879a92980aec9d85eb7e9df245eae03a41acfd4e7d1cb1
|
deb2604834e2bb62e890b0ce405b3b8ef2fec2aab3e22bff23f89a58ff0dc015fece5d3ed3f5496ace879a92980aec9d85eb7e9df245eae03a41acfd4e7d1cb1
|
||||||
dbd0df42d534904de00b6389f68867646e9d7c3d0b1dffd74070b2d0f2049b9f1dc7b0c9651c59be3ea891674725e1f2f7a484a941615b80211105978369cf71
|
dbd0df42d534904de00b6389f68867646e9d7c3d0b1dffd74070b2d0f2049b9f1dc7b0c9651c59be3ea891674725e1f2f7a484a941615b80211105978369cf71
|
||||||
''')
|
''')
|
||||||
|
|
||||||
crypto_backend=default_backend()
|
crypto_backend = default_backend()
|
||||||
|
|
||||||
|
|
||||||
def get_partition_signature():
|
def get_partition_signature():
|
||||||
if usb.usb_dev().idVendor == 0x138a:
|
if usb.usb_dev().idVendor == 0x138a:
|
||||||
if usb.usb_dev().idProduct == 0x0090:
|
if usb.usb_dev().idProduct == 0x0090:
|
||||||
return b''
|
return b''
|
||||||
|
|
||||||
return partition_signature
|
return partition_signature
|
||||||
|
|
||||||
|
|
||||||
def with_hdr(id, buf):
|
def with_hdr(id: int, buf: bytes):
|
||||||
return pack('<HH', id, len(buf)) + buf
|
return pack('<HH', id, len(buf)) + buf
|
||||||
|
|
||||||
|
|
||||||
def encrypt_key(client_private, client_public):
|
def encrypt_key(client_private, client_public):
|
||||||
x = unhexlify('%064x' % client_public.x)[::-1]
|
x = unhexlify('%064x' % client_public.x)[::-1]
|
||||||
y = unhexlify('%064x' % client_public.y)[::-1]
|
y = unhexlify('%064x' % client_public.y)[::-1]
|
||||||
d = unhexlify('%064x' % client_private)[::-1]
|
d = unhexlify('%064x' % client_private)[::-1]
|
||||||
|
|
||||||
m = x+y+d
|
m = x + y + d
|
||||||
l = 16 - (len(m) % 16)
|
l = 16 - (len(m) % 16)
|
||||||
m = m + bytes([l])*l
|
m = m + bytes([l]) * l
|
||||||
|
|
||||||
iv = os.urandom(0x10)
|
iv = os.urandom(0x10)
|
||||||
cipher = Cipher(algorithms.AES(tls.psk_encryption_key), modes.CBC(iv), backend=crypto_backend)
|
cipher = Cipher(algorithms.AES(tls.psk_encryption_key), modes.CBC(iv), backend=crypto_backend)
|
||||||
|
|
@ -64,45 +67,48 @@ def encrypt_key(client_private, client_public):
|
||||||
|
|
||||||
sig = hmac.new(tls.psk_validation_key, c, sha256).digest()
|
sig = hmac.new(tls.psk_validation_key, c, sha256).digest()
|
||||||
return b'\x02' + c + sig
|
return b'\x02' + c + sig
|
||||||
|
|
||||||
|
|
||||||
def make_cert(client_public):
|
def make_cert(client_public):
|
||||||
msg=(pack('<LL', 0x17, 0x20) +
|
msg = (pack('<LL', 0x17, 0x20) + unhexlify('%064x' % client_public.x)[::-1] + (b'\0' * 0x24) +
|
||||||
unhexlify('%064x' % client_public.x)[::-1] +
|
unhexlify('%064x' % client_public.y)[::-1] + (b'\0' * 0x4c))
|
||||||
(b'\0'*0x24) +
|
|
||||||
unhexlify('%064x' % client_public.y)[::-1] +
|
|
||||||
(b'\0'*0x4c))
|
|
||||||
pk = ec.derive_private_key(hs_key(), ec.SECP256R1(), backend=crypto_backend)
|
pk = ec.derive_private_key(hs_key(), ec.SECP256R1(), backend=crypto_backend)
|
||||||
s=pk.sign(msg, ec.ECDSA(hashes.SHA256()))
|
s = pk.sign(msg, ec.ECDSA(hashes.SHA256()))
|
||||||
s=pack('<L', len(s)) + s
|
s = pack('<L', len(s)) + s
|
||||||
msg = msg + s
|
msg = msg + s
|
||||||
msg += b'\0'*(444 - len(msg)) # FIXME not sure this math is right
|
msg += b'\0' * (444 - len(msg)) # FIXME not sure this math is right
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def serialize_flash_params(ic):
|
|
||||||
|
def serialize_flash_params(ic: FlashIcInfo):
|
||||||
return pack('<LLxxBx', ic.size, ic.secror_size, ic.sector_erase_cmd)
|
return pack('<LLxxBx', ic.size, ic.secror_size, ic.sector_erase_cmd)
|
||||||
|
|
||||||
def serialize_partition(p):
|
|
||||||
|
def serialize_partition(p: PartitionInfo):
|
||||||
b = pack('<BBHLL', p.id, p.type, p.access_lvl, p.offset, p.size)
|
b = pack('<BBHLL', p.id, p.type, p.access_lvl, p.offset, p.size)
|
||||||
b = b + b'\0'*4 + sha256(b).digest()
|
b = b + b'\0' * 4 + sha256(b).digest()
|
||||||
return b
|
return b
|
||||||
|
|
||||||
def partition_flash(info, layout, client_public):
|
|
||||||
|
def partition_flash(info: FlashInfo, layout: typing.List[PartitionInfo], client_public):
|
||||||
logging.info('Detected Flash IC: %s, %d bytes' % (info.ic.name, info.ic.size))
|
logging.info('Detected Flash IC: %s, %d bytes' % (info.ic.name, info.ic.size))
|
||||||
|
|
||||||
cmd = unhex('4f 0000 0000')
|
cmd = unhex('4f 0000 0000')
|
||||||
cmd += with_hdr(0, serialize_flash_params(info.ic))
|
cmd += with_hdr(0, serialize_flash_params(info.ic))
|
||||||
cmd += with_hdr(1, b''.join([serialize_partition(p) for p in layout]) + get_partition_signature())
|
cmd += with_hdr(1,
|
||||||
|
b''.join([serialize_partition(p) for p in layout]) + get_partition_signature())
|
||||||
cmd += with_hdr(5, make_cert(client_public))
|
cmd += with_hdr(5, make_cert(client_public))
|
||||||
cmd += with_hdr(3, crt_hardcoded)
|
cmd += with_hdr(3, crt_hardcoded)
|
||||||
rsp = tls.cmd(cmd)
|
rsp = tls.cmd(cmd)
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
rsp = rsp[2:]
|
rsp = rsp[2:]
|
||||||
crt_len, rsp=rsp[:4], rsp[4:]
|
crt_len, rsp = rsp[:4], rsp[4:]
|
||||||
crt_len, = unpack('<L', crt_len)
|
crt_len, = unpack('<L', crt_len)
|
||||||
tls.handle_cert(rsp[:crt_len])
|
tls.handle_cert(rsp[:crt_len])
|
||||||
rsp = rsp[crt_len:]
|
rsp = rsp[crt_len:]
|
||||||
# ^ TODO - figure out what the rest of rsp means
|
# ^ TODO - figure out what the rest of rsp means
|
||||||
|
|
||||||
|
|
||||||
def init_flash():
|
def init_flash():
|
||||||
info = get_flash_info()
|
info = get_flash_info()
|
||||||
|
|
||||||
|
|
@ -125,13 +131,13 @@ def init_flash():
|
||||||
# ^ TODO: use the firmware version which to lookup pubkey for server cert validation
|
# ^ TODO: use the firmware version which to lookup pubkey for server cert validation
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rsp=usb.cmd(unhex('50'))
|
rsp = usb.cmd(unhex('50'))
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
finally:
|
finally:
|
||||||
call_cleanups()
|
call_cleanups()
|
||||||
|
|
||||||
rsp=rsp[2:]
|
rsp = rsp[2:]
|
||||||
l,=unpack('<L', rsp[:4])
|
l, = unpack('<L', rsp[:4])
|
||||||
|
|
||||||
if len(rsp) != l:
|
if len(rsp) != l:
|
||||||
raise Exception('Length mismatch')
|
raise Exception('Length mismatch')
|
||||||
|
|
@ -153,8 +159,8 @@ def init_flash():
|
||||||
erase_flash(4)
|
erase_flash(4)
|
||||||
|
|
||||||
# Persist certs and keys on cert partition.
|
# Persist certs and keys on cert partition.
|
||||||
write_flash(1, 0, tls.makeTlsFlash())
|
write_flash(1, 0, tls.make_tls_flash())
|
||||||
|
|
||||||
# Reboot.
|
# Reboot.
|
||||||
# The device will disconnect and our service will be started by udev as soon as it is connected again.
|
# The device will disconnect and our service will be started by udev as soon as it is connected again.
|
||||||
reboot()
|
reboot()
|
||||||
|
|
|
||||||
|
|
@ -1,83 +1,101 @@
|
||||||
|
import logging
|
||||||
|
import os.path
|
||||||
import typing
|
import typing
|
||||||
|
from binascii import hexlify, unhexlify
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
import os.path
|
from struct import pack, unpack
|
||||||
import logging
|
from time import sleep
|
||||||
|
|
||||||
from usb import core as usb_core
|
from usb import core as usb_core
|
||||||
from .tls import tls
|
|
||||||
from .usb import usb, CancelledException
|
from . import timeslot as prg
|
||||||
|
from .blobs import reset_blob
|
||||||
from .db import db, SidIdentity
|
from .db import db, SidIdentity
|
||||||
from .flash import write_enable, call_cleanups, read_flash, erase_flash, write_flash_all, read_flash_all
|
from .flash import write_enable, call_cleanups, read_flash, erase_flash, write_flash_all, read_flash_all
|
||||||
from time import sleep
|
|
||||||
from struct import pack, unpack
|
|
||||||
from .table_types import SensorTypeInfo, SensorCaptureProg
|
|
||||||
from binascii import hexlify, unhexlify
|
|
||||||
from .util import assert_status, unhex
|
|
||||||
from .hw_tables import dev_info_lookup
|
from .hw_tables import dev_info_lookup
|
||||||
from .blobs import reset_blob
|
from .table_types import SensorTypeInfo, SensorCaptureProg
|
||||||
from . import timeslot as prg
|
from .tls import tls
|
||||||
|
from .usb import usb, CancelledException
|
||||||
|
from .util import assert_status, unhex
|
||||||
|
|
||||||
# TODO: this should be specific to an individual device (system may have more than one sensor)
|
# TODO: this should be specific to an individual device (system may have more than one sensor)
|
||||||
calib_data_path='/usr/share/python-validity/calib-data.bin'
|
calib_data_path = '/usr/share/python-validity/calib-data.bin'
|
||||||
|
|
||||||
|
line_update_type1_devices = [
|
||||||
|
0xB5, 0x885, 0xB3, 0x143B, 0x1055, 0xE1, 0x8B1, 0xEA, 0xE4, 0xED, 0x1825, 0x1FF5, 0x199
|
||||||
|
]
|
||||||
|
|
||||||
line_update_type1_devices = [ 0xB5, 0x885, 0xB3, 0x143B, 0x1055, 0xE1, 0x8B1, 0xEA, 0xE4, 0xED, 0x1825, 0x1FF5, 0x199 ]
|
|
||||||
|
|
||||||
# TODO use more sophisticated glow patters in different cases
|
# TODO use more sophisticated glow patters in different cases
|
||||||
def glow_start_scan():
|
def glow_start_scan():
|
||||||
cmd=unhexlify('3920bf0200ffff0000019900200000000099990000000000000000000000000020000000000000000000000000ffff000000990020000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
|
cmd = unhexlify(
|
||||||
|
'3920bf0200ffff0000019900200000000099990000000000000000000000000020000000000000000000000000ffff000000990020000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||||
|
)
|
||||||
assert_status(tls.app(cmd))
|
assert_status(tls.app(cmd))
|
||||||
|
|
||||||
|
|
||||||
def glow_end_scan():
|
def glow_end_scan():
|
||||||
cmd=unhexlify('39f4010000f401000001ff002000000000ffff0000000000000000000000000020000000000000000000000000f401000000ff0020000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000')
|
cmd = unhexlify(
|
||||||
|
'39f4010000f401000001ff002000000000ffff0000000000000000000000000020000000000000000000000000f401000000ff0020000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
|
||||||
|
)
|
||||||
assert_status(tls.app(cmd))
|
assert_status(tls.app(cmd))
|
||||||
|
|
||||||
|
|
||||||
def get_prg_status():
|
def get_prg_status():
|
||||||
return tls.app(unhexlify('5100000000'))
|
return tls.app(unhexlify('5100000000'))
|
||||||
|
|
||||||
|
|
||||||
def wait_till_finished():
|
def wait_till_finished():
|
||||||
while True:
|
while True:
|
||||||
status = get_prg_status()
|
status = get_prg_status()
|
||||||
|
|
||||||
if status[0] in [0, 7]:
|
if status[0] in [0, 7]:
|
||||||
break
|
break
|
||||||
|
|
||||||
sleep(0.2)
|
sleep(0.2)
|
||||||
|
|
||||||
|
|
||||||
def get_prg_status2():
|
def get_prg_status2():
|
||||||
return tls.app(unhexlify('5100200000'))
|
return tls.app(unhexlify('5100200000'))
|
||||||
|
|
||||||
|
|
||||||
def read_hw_reg32(addr):
|
def read_hw_reg32(addr: int):
|
||||||
rsp=tls.cmd(pack('<BLB', 7, addr, 4))
|
rsp = tls.cmd(pack('<BLB', 7, addr, 4))
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
rsp, = unpack('<L', rsp[2:])
|
rsp, = unpack('<L', rsp[2:])
|
||||||
return rsp
|
return rsp
|
||||||
|
|
||||||
def write_hw_reg32(addr, val):
|
|
||||||
rsp=tls.cmd(pack('<BLLB', 8, addr, val, 4))
|
def write_hw_reg32(addr: int, val: int):
|
||||||
|
rsp = tls.cmd(pack('<BLLB', 8, addr, val, 4))
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
|
|
||||||
|
|
||||||
class RebootException(Exception):
|
class RebootException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def reboot():
|
def reboot():
|
||||||
assert_status(tls.cmd(unhex('050200')))
|
assert_status(tls.cmd(unhex('050200')))
|
||||||
raise RebootException()
|
raise RebootException()
|
||||||
|
|
||||||
|
|
||||||
def factory_reset():
|
def factory_reset():
|
||||||
assert_status(usb.cmd(reset_blob))
|
assert_status(usb.cmd(reset_blob))
|
||||||
assert_status(usb.cmd(b'\x10' + b'\0'*0x61))
|
assert_status(usb.cmd(b'\x10' + b'\0' * 0x61))
|
||||||
reboot()
|
reboot()
|
||||||
|
|
||||||
class RomInfo():
|
|
||||||
|
class RomInfo:
|
||||||
@classmethod
|
@classmethod
|
||||||
def get(cls):
|
def get(cls):
|
||||||
rsp=tls.cmd(b'\x01')
|
rsp = tls.cmd(b'\x01')
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
rsp=rsp[2:]
|
rsp = rsp[2:]
|
||||||
return cls(*unpack('<LLBBxBxxxB', rsp[0:0x10]))
|
return cls(*unpack('<LLBBxBxxxB', rsp[0:0x10]))
|
||||||
|
|
||||||
def __init__(self, timestamp, build, major, minor, product, u1):
|
def __init__(self, timestamp: int, build: int, major: int, minor: int, product: int, u1: int):
|
||||||
self.timestamp, self.build, self.major, self.minor, self.product, self.u1 = timestamp, build, major, minor, product, u1
|
self.timestamp, self.build, self.major, self.minor, self.product, self.u1 = timestamp, build, major, minor, product, u1
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
@ -86,9 +104,9 @@ class RomInfo():
|
||||||
|
|
||||||
|
|
||||||
def identify_sensor():
|
def identify_sensor():
|
||||||
rsp=tls.cmd(b'\x75')
|
rsp = tls.cmd(b'\x75')
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
rsp=rsp[2:]
|
rsp = rsp[2:]
|
||||||
|
|
||||||
zeroes, minor, major = unpack('<LHH', rsp)
|
zeroes, minor, major = unpack('<LHH', rsp)
|
||||||
|
|
||||||
|
|
@ -97,6 +115,7 @@ def identify_sensor():
|
||||||
|
|
||||||
return dev_info_lookup(major, minor)
|
return dev_info_lookup(major, minor)
|
||||||
|
|
||||||
|
|
||||||
# <<< 0000 880d 0000 07000000
|
# <<< 0000 880d 0000 07000000
|
||||||
# 08000000 9400 0e00 0300 0080 07000000 7e7f807f808080808080808080808080808080808080818081808180818080808080818081808080818081808180
|
# 08000000 9400 0e00 0300 0080 07000000 7e7f807f808080808080808080808080808080808080818081808180818080808080818081808080818081808180
|
||||||
# a4000000 0800 0e00 0200 0000 00000000 0d007100
|
# a4000000 0800 0e00 0200 0000 00000000 0d007100
|
||||||
|
|
@ -105,15 +124,15 @@ def identify_sensor():
|
||||||
# d0000000 9400 0e00 0700 0080 07000000 2b23203c2d182e1e30182e1c321d341d341e321c301e1e241e201f201d1c321a301e1c211e21341f1e202024201f
|
# d0000000 9400 0e00 0700 0080 07000000 2b23203c2d182e1e30182e1c321d341d341e321c301e1e241e201f201d1c321a301e1c211e21341f1e202024201f
|
||||||
# 6c010000 1400 0e00 0f00 0080 05550007 7701002805720000080100020811e107
|
# 6c010000 1400 0e00 0f00 0080 05550007 7701002805720000080100020811e107
|
||||||
# 88010000 0c00 0e00 1200 0080 07000000 7002 7800 7002 7800
|
# 88010000 0c00 0e00 1200 0080 07000000 7002 7800 7002 7800
|
||||||
def get_factory_bits(tag):
|
def get_factory_bits(tag: int):
|
||||||
rsp=tls.cmd(pack('<B H HL', 0x6f, tag, 0, 0))
|
rsp = tls.cmd(pack('<B H HL', 0x6f, tag, 0, 0))
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
rsp=rsp[2:]
|
rsp = rsp[2:]
|
||||||
|
|
||||||
wtf, entries = unpack('<LL', rsp[:8])
|
wtf, entries = unpack('<LL', rsp[:8])
|
||||||
rsp = rsp[8:]
|
rsp = rsp[8:]
|
||||||
|
|
||||||
rc={}
|
rc = {}
|
||||||
for x in range(0, entries):
|
for x in range(0, entries):
|
||||||
hdr, rsp = rsp[:12], rsp[12:]
|
hdr, rsp = rsp[:12], rsp[12:]
|
||||||
ptr, l, tag, subtag, flags = unpack('<LHHHH', hdr)
|
ptr, l, tag, subtag, flags = unpack('<LHHHH', hdr)
|
||||||
|
|
@ -121,7 +140,7 @@ def get_factory_bits(tag):
|
||||||
|
|
||||||
if len(value) != l:
|
if len(value) != l:
|
||||||
raise Exception('Truncated response %d != %d' % (len(value), l))
|
raise Exception('Truncated response %d != %d' % (len(value), l))
|
||||||
|
|
||||||
rc[subtag] = value
|
rc[subtag] = value
|
||||||
rsp = rsp[l:]
|
rsp = rsp[l:]
|
||||||
|
|
||||||
|
|
@ -132,95 +151,106 @@ def get_factory_bits(tag):
|
||||||
|
|
||||||
|
|
||||||
def bitpack(b):
|
def bitpack(b):
|
||||||
l=len(b)
|
l = len(b)
|
||||||
m=min(b)
|
m = min(b)
|
||||||
x=max(b)
|
x = max(b)
|
||||||
|
|
||||||
# maximum delta which we must encode
|
# maximum delta which we must encode
|
||||||
x-=m
|
x -= m
|
||||||
|
|
||||||
# count useful bits
|
# count useful bits
|
||||||
u=0
|
u = 0
|
||||||
while x > 0:
|
while x > 0:
|
||||||
x>>=1
|
x >>= 1
|
||||||
u+=1
|
u += 1
|
||||||
|
|
||||||
# convert to array of binary strings with each element exactly u characters long
|
# convert to array of binary strings with each element exactly u characters long
|
||||||
b=[bin(i-m+0x100)[-u:] for i in b]
|
b = [bin(i - m + 0x100)[-u:] for i in b]
|
||||||
|
|
||||||
# combine chunks into one long text number with u*l binary digits and parse it as integer
|
# combine chunks into one long text number with u*l binary digits and parse it as integer
|
||||||
b=int(''.join(b[::-1]), 2)
|
b = int(''.join(b[::-1]), 2)
|
||||||
|
|
||||||
# convert back to bytes
|
# convert back to bytes
|
||||||
b=b.to_bytes((u*l+7)//8, 'little')
|
b = b.to_bytes((u * l + 7) // 8, 'little')
|
||||||
|
|
||||||
return (u, m, b)
|
return u, m, b
|
||||||
|
|
||||||
class Line():
|
|
||||||
mask=None
|
|
||||||
flags=None
|
|
||||||
data=None
|
|
||||||
v0=0
|
|
||||||
v1=0
|
|
||||||
v2=0
|
|
||||||
|
|
||||||
def clip(x):
|
class Line:
|
||||||
|
def __init__(self):
|
||||||
|
self.mask: typing.Optional[int] = None
|
||||||
|
self.flags: typing.Optional[int] = None
|
||||||
|
self.data: typing.Optional[bytes] = None
|
||||||
|
self.v0 = 0
|
||||||
|
self.v1 = 0
|
||||||
|
self.v2 = 0
|
||||||
|
|
||||||
|
|
||||||
|
def clip(x: int):
|
||||||
if x < -128:
|
if x < -128:
|
||||||
x=-128
|
x = -128
|
||||||
|
|
||||||
if x > 127:
|
if x > 127:
|
||||||
x=127
|
x = 127
|
||||||
|
|
||||||
return x & 0xff
|
return x & 0xff
|
||||||
|
|
||||||
def scale(x):
|
|
||||||
|
def scale(x: int):
|
||||||
x -= 0x80
|
x -= 0x80
|
||||||
x = int(x*10/0x22) # TODO: scaling factor depends on a device
|
x = int(x * 10 / 0x22) # TODO: scaling factor depends on a device
|
||||||
return clip(x)
|
return clip(x)
|
||||||
|
|
||||||
|
|
||||||
def add(l, r):
|
def add(l: int, r: int):
|
||||||
# Make signed
|
# Make signed
|
||||||
l, r = unpack('bb', pack('BB', l, r))
|
l, r = unpack('bb', pack('BB', l, r))
|
||||||
return clip(l+r)
|
return clip(l + r)
|
||||||
|
|
||||||
|
|
||||||
|
def chunks(b: bytes, l: int):
|
||||||
|
return [b[i:i + l] for i in range(0, len(b), l)]
|
||||||
|
|
||||||
def chunks(b, l):
|
|
||||||
return [b[i:i+l] for i in range(0, len(b), l)]
|
|
||||||
|
|
||||||
class CaptureMode(Enum):
|
class CaptureMode(Enum):
|
||||||
CALIBRATE=1
|
CALIBRATE = 1
|
||||||
IDENTIFY=2
|
IDENTIFY = 2
|
||||||
ENROLL=3
|
ENROLL = 3
|
||||||
|
|
||||||
class Sensor():
|
|
||||||
calib_data=b''
|
class Sensor:
|
||||||
|
calib_data = b''
|
||||||
|
|
||||||
def open(self):
|
def open(self):
|
||||||
self.device_info = identify_sensor()
|
self.device_info = identify_sensor()
|
||||||
|
|
||||||
logging.info('Opening sensor: %s' % self.device_info.name)
|
logging.info('Opening sensor: %s' % self.device_info.name)
|
||||||
self.type_info = SensorTypeInfo.get_by_type(self.device_info.type)
|
self.type_info = SensorTypeInfo.get_by_type(self.device_info.type)
|
||||||
|
|
||||||
if self.device_info.type == 0x199:
|
if self.device_info.type == 0x199:
|
||||||
self.key_calibration_line = 0x38 # (lines_per_calibration_data/2), but hardcoded for sensor type 0x199
|
self.key_calibration_line = 0x38 # (lines_per_calibration_data/2), but hardcoded for sensor type 0x199
|
||||||
self.calibration_frames = 3 # TODO: workout where it's really comming from
|
self.calibration_frames = 3 # TODO: workout where it's really comming from
|
||||||
self.calibration_iterations = 3 # hardcoded for type
|
self.calibration_iterations = 3 # hardcoded for type
|
||||||
elif self.device_info.type == 0xdb:
|
elif self.device_info.type == 0xdb:
|
||||||
self.key_calibration_line = 0x48 # TODO 48 is just a guess -- find it
|
self.key_calibration_line = 0x48 # TODO 48 is just a guess -- find it
|
||||||
self.calibration_frames = 6 # TODO: workout where it's really comming from
|
self.calibration_frames = 6 # TODO: workout where it's really comming from
|
||||||
self.calibration_iterations = 0
|
self.calibration_iterations = 0
|
||||||
else:
|
else:
|
||||||
raise Exception('Device %s is not supported (sensor type 0x%x)' % (self.device_info.name, self.device_info.type))
|
raise Exception('Device %s is not supported (sensor type 0x%x)' %
|
||||||
|
(self.device_info.name, self.device_info.type))
|
||||||
|
|
||||||
self.rom_info = RomInfo.get()
|
self.rom_info = RomInfo.get()
|
||||||
self.hardcoded_prog = SensorCaptureProg.get(self.rom_info, self.device_info.type, 0x18, 0x19) # TODO: find where 0x18, 0x19 coming from
|
self.hardcoded_prog = SensorCaptureProg.get(self.rom_info, self.device_info.type, 0x18,
|
||||||
|
0x19) # TODO: find where 0x18, 0x19 coming from
|
||||||
if self.hardcoded_prog is None:
|
if self.hardcoded_prog is None:
|
||||||
raise Exception('Can\'t find initial capture program for rom %s and sensor type %x' % (repr(self.rom_info), self.device_info.type))
|
raise Exception('Can\'t find initial capture program for rom %s and sensor type %x' %
|
||||||
|
(repr(self.rom_info), self.device_info.type))
|
||||||
|
|
||||||
# Look for a "2D" chunk. It must have a 32 bit integer which represent the number of lines per frame
|
# Look for a "2D" chunk. It must have a 32 bit integer which represent the number of lines per frame
|
||||||
lines_2d = [unpack('<L', v)[0] for [k, v] in prg.split_chunks(self.hardcoded_prog) if k == 0x2f][0]
|
lines_2d = [
|
||||||
self.lines_per_frame = lines_2d*self.type_info.repeat_multiplier
|
unpack('<L', v)[0] for [k, v] in prg.split_chunks(self.hardcoded_prog) if k == 0x2f
|
||||||
|
][0]
|
||||||
|
self.lines_per_frame = lines_2d * self.type_info.repeat_multiplier
|
||||||
self.bytes_per_line = self.type_info.bytes_per_line
|
self.bytes_per_line = self.type_info.bytes_per_line
|
||||||
|
|
||||||
factory_bits = get_factory_bits(0x0e00)
|
factory_bits = get_factory_bits(0x0e00)
|
||||||
|
|
@ -235,37 +265,37 @@ class Sensor():
|
||||||
with open(calib_data_path, 'wb') as f:
|
with open(calib_data_path, 'wb') as f:
|
||||||
f.write(self.calib_data)
|
f.write(self.calib_data)
|
||||||
|
|
||||||
# This is the exact logic from the DLL.
|
# This is the exact logic from the DLL.
|
||||||
# If it looks broken that was probably intended.
|
# If it looks broken that was probably intended.
|
||||||
def patch_timeslot_table(self, b, inc_address, mult):
|
def patch_timeslot_table(self, b: bytes, inc_address: bool, mult: int):
|
||||||
b=bytearray(b)
|
b = bytearray(b)
|
||||||
i=0
|
i = 0
|
||||||
while i+3 < len(b):
|
while i + 3 < len(b):
|
||||||
if b[i] & 0xf8 == 0x10:
|
if b[i] & 0xf8 == 0x10:
|
||||||
if b[i+2] > 1:
|
if b[i + 2] > 1:
|
||||||
b[i+2] *= mult
|
b[i + 2] *= mult
|
||||||
if inc_address:
|
if inc_address:
|
||||||
b[i+1] += 1
|
b[i + 1] += 1
|
||||||
i+=3
|
i += 3
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if b[i] == 0:
|
if b[i] == 0:
|
||||||
i+=1
|
i += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if b[i] == 7:
|
if b[i] == 7:
|
||||||
i+=2
|
i += 2
|
||||||
continue
|
continue
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
return bytes(b)
|
return bytes(b)
|
||||||
|
|
||||||
def patch_timeslot_again(self, b):
|
def patch_timeslot_again(self, b: bytes):
|
||||||
b=bytearray(b)
|
b = bytearray(b)
|
||||||
|
|
||||||
pc = 0
|
pc = 0
|
||||||
match=None
|
match = None
|
||||||
# Look for the last Call in the script
|
# Look for the last Call in the script
|
||||||
while pc < len(b):
|
while pc < len(b):
|
||||||
opcode, l, *operands = prg.decode_insn(b[pc:])
|
opcode, l, *operands = prg.decode_insn(b[pc:])
|
||||||
|
|
@ -276,7 +306,7 @@ class Sensor():
|
||||||
|
|
||||||
# Call
|
# Call
|
||||||
if opcode == 11:
|
if opcode == 11:
|
||||||
match = operands[1] # destination address
|
match = operands[1] # destination address
|
||||||
|
|
||||||
pc += l
|
pc += l
|
||||||
|
|
||||||
|
|
@ -303,88 +333,93 @@ class Sensor():
|
||||||
return bytes(b)
|
return bytes(b)
|
||||||
|
|
||||||
# Hack the value to be taken from the factory calibration table right in the middle of a sensor
|
# Hack the value to be taken from the factory calibration table right in the middle of a sensor
|
||||||
b[match+1] = self.factory_calibration_values[self.key_calibration_line]
|
b[match + 1] = self.factory_calibration_values[self.key_calibration_line]
|
||||||
|
|
||||||
return bytes(b)
|
return bytes(b)
|
||||||
|
|
||||||
def average(self, raw_calib_data):
|
def average(self, raw_calib_data: bytes):
|
||||||
frame_size = self.lines_per_frame * self.bytes_per_line
|
frame_size = self.lines_per_frame * self.bytes_per_line
|
||||||
interleave_lines = self.lines_per_frame // self.type_info.lines_per_calibration_data # 2, TODO: algo is quite different when it is 1
|
interleave_lines = self.lines_per_frame // self.type_info.lines_per_calibration_data # 2, TODO: algo is quite different when it is 1
|
||||||
input_frames = self.calibration_frames
|
input_frames = self.calibration_frames
|
||||||
|
|
||||||
if interleave_lines > 1:
|
if interleave_lines > 1:
|
||||||
if input_frames > 1:
|
if input_frames > 1:
|
||||||
# skip the first frame
|
# skip the first frame
|
||||||
input_frames -= 1
|
input_frames -= 1
|
||||||
base_address = frame_size
|
base_address = frame_size
|
||||||
|
|
||||||
frame=raw_calib_data[base_address:base_address+frame_size]
|
frame = raw_calib_data[base_address:base_address + frame_size]
|
||||||
|
|
||||||
# split into groups of lines
|
# split into groups of lines
|
||||||
frame=chunks(frame, interleave_lines*self.bytes_per_line)
|
frame = chunks(frame, interleave_lines * self.bytes_per_line)
|
||||||
|
|
||||||
# split group of lines into lines
|
# split group of lines into lines
|
||||||
frame=[chunks(f, self.bytes_per_line) for f in frame]
|
frame = [chunks(f, self.bytes_per_line) for f in frame]
|
||||||
|
|
||||||
# calculate averages across interleaved lines
|
# calculate averages across interleaved lines
|
||||||
frame=[bytes([sum(i)//len(f) for i in zip(*f)]) for f in frame]
|
frame = [bytes([sum(i) // len(f) for i in zip(*f)]) for f in frame]
|
||||||
frame=b''.join(frame)
|
frame = b''.join(frame)
|
||||||
else:
|
else:
|
||||||
if input_frames > 1:
|
if input_frames > 1:
|
||||||
# skip the first frame
|
# skip the first frame
|
||||||
input_frames -= 2
|
input_frames -= 2
|
||||||
base_address = frame_size*2
|
base_address = frame_size * 2
|
||||||
|
|
||||||
frames=raw_calib_data[base_address:base_address+frame_size*input_frames]
|
frames = raw_calib_data[base_address:base_address + frame_size * input_frames]
|
||||||
frames=chunks(frames, frame_size)
|
frames = chunks(frames, frame_size)
|
||||||
frame=[int(sum(i)/input_frames) for i in zip(*frames)]
|
frame = [int(sum(i) / input_frames) for i in zip(*frames)]
|
||||||
frame=bytes(frame)
|
frame = bytes(frame)
|
||||||
|
|
||||||
return frame
|
return frame
|
||||||
|
|
||||||
def process_calibration_results(self, cooked_data):
|
def process_calibration_results(self, cooked_data: bytes):
|
||||||
frame=chunks(cooked_data, self.bytes_per_line)
|
frame = chunks(cooked_data, self.bytes_per_line)
|
||||||
|
|
||||||
# apply scaling factors
|
# apply scaling factors
|
||||||
frame=[f[:8] + bytes(map(scale, f[8:])) for f in frame]
|
frame = [f[:8] + bytes(map(scale, f[8:])) for f in frame]
|
||||||
frame=b''.join(frame)
|
frame = b''.join(frame)
|
||||||
|
|
||||||
if len(self.calib_data) > 0:
|
if len(self.calib_data) > 0:
|
||||||
# Not the first calibration run. Combine results
|
# Not the first calibration run. Combine results
|
||||||
# split previous calibration info into lines
|
# split previous calibration info into lines
|
||||||
lll=chunks(self.calib_data, self.bytes_per_line)
|
lll = chunks(self.calib_data, self.bytes_per_line)
|
||||||
|
|
||||||
# split next calibration info into lines
|
# split next calibration info into lines
|
||||||
rrr=chunks(frame, self.bytes_per_line)
|
rrr = chunks(frame, self.bytes_per_line)
|
||||||
|
|
||||||
# Don't touch the first 8 bytes of each line, add everything else as signed characters, clipping the values
|
# Don't touch the first 8 bytes of each line, add everything else as signed characters, clipping the values
|
||||||
combined=[ll[:8] + bytes([add(l, r) for l, r in zip(ll[8:],rr[8:])]) for ll, rr in zip(lll, rrr)]
|
combined = [
|
||||||
|
ll[:8] + bytes([add(l, r) for l, r in zip(ll[8:], rr[8:])])
|
||||||
|
for ll, rr in zip(lll, rrr)
|
||||||
|
]
|
||||||
self.calib_data = bytes(b''.join(combined))
|
self.calib_data = bytes(b''.join(combined))
|
||||||
else:
|
else:
|
||||||
self.calib_data = frame
|
self.calib_data = frame
|
||||||
|
|
||||||
def get_key_line(self):
|
def get_key_line(self):
|
||||||
if len(self.calib_data) > 0:
|
if len(self.calib_data) > 0:
|
||||||
bytes_per_calibration_line=len(self.calib_data) // self.type_info.lines_per_calibration_data
|
bytes_per_calibration_line = len(
|
||||||
key_line_offset=8+bytes_per_calibration_line*self.key_calibration_line
|
self.calib_data) // self.type_info.lines_per_calibration_data
|
||||||
key_line=self.calib_data[key_line_offset:key_line_offset+self.type_info.line_width]
|
key_line_offset = 8 + bytes_per_calibration_line * self.key_calibration_line
|
||||||
key_line=bytes([i-1 if i == 5 else i for i in key_line])
|
key_line = self.calib_data[key_line_offset:key_line_offset + self.type_info.line_width]
|
||||||
|
key_line = bytes([i - 1 if i == 5 else i for i in key_line])
|
||||||
else:
|
else:
|
||||||
key_line=b'\0'*self.type_info.line_width
|
key_line = b'\0' * self.type_info.line_width
|
||||||
|
|
||||||
return key_line
|
return key_line
|
||||||
|
|
||||||
def line_update_type_1(self, mode, chunks):
|
def line_update_type_1(self, mode: CaptureMode,
|
||||||
|
chunks: typing.List[typing.List[typing.Union[int, bytes]]]):
|
||||||
for c in chunks:
|
for c in chunks:
|
||||||
# Timeslot Table 2D
|
# Timeslot Table 2D
|
||||||
if c[0] == 0x34:
|
if c[0] == 0x34:
|
||||||
# TODO: figure out when to use address increment
|
# TODO: figure out when to use address increment
|
||||||
tst = self.patch_timeslot_table(c[1], True, self.type_info.repeat_multiplier)
|
tst = self.patch_timeslot_table(c[1], True, self.type_info.repeat_multiplier)
|
||||||
if mode != CaptureMode.CALIBRATE:
|
if mode != CaptureMode.CALIBRATE:
|
||||||
tst=self.patch_timeslot_again(tst)
|
tst = self.patch_timeslot_again(tst)
|
||||||
c[1] = self.get_key_line() + tst[self.type_info.line_width:]
|
c[1] = self.get_key_line() + tst[self.type_info.line_width:]
|
||||||
|
|
||||||
#---------------- Reply Configuration ---------------
|
# ---------------- Reply Configuration ---------------
|
||||||
chunks += [[0x17, b'']]
|
chunks += [[0x17, b'']]
|
||||||
|
|
||||||
if mode == CaptureMode.IDENTIFY:
|
if mode == CaptureMode.IDENTIFY:
|
||||||
|
|
@ -392,53 +427,68 @@ class Sensor():
|
||||||
# It seems to be only used for identification and it looks almost identical to Finger Detect (0x26)
|
# It seems to be only used for identification and it looks almost identical to Finger Detect (0x26)
|
||||||
# Seems to be the same all the time for a given sensor and mostly hardcoded
|
# Seems to be the same all the time for a given sensor and mostly hardcoded
|
||||||
# TODO: analyse construct_wtf_4e @0000000180090BF0
|
# TODO: analyse construct_wtf_4e @0000000180090BF0
|
||||||
chunks += [[0x4e, unhexlify('fbb20f0000000f00300000008700020067000a00018000000a0200000b1900008813b80b01091000')]]
|
chunks += [[
|
||||||
|
0x4e,
|
||||||
|
unhexlify(
|
||||||
|
'fbb20f0000000f00300000008700020067000a00018000000a0200000b1900008813b80b01091000'
|
||||||
|
)
|
||||||
|
]]
|
||||||
# Image Reconstruction.
|
# Image Reconstruction.
|
||||||
# TODO: analyse add_image_reconstruction_cmd_02_buff_list_item @000000018008EA70
|
# TODO: analyse add_image_reconstruction_cmd_02_buff_list_item @000000018008EA70
|
||||||
chunks += [[0x2e, unhexlify('0200180002000000700070004d010000a0008c003c32321e3c0a0202')]]
|
chunks += [[
|
||||||
|
0x2e, unhexlify('0200180002000000700070004d010000a0008c003c32321e3c0a0202')
|
||||||
|
]]
|
||||||
elif mode == CaptureMode.ENROLL:
|
elif mode == CaptureMode.ENROLL:
|
||||||
chunks += [[0x26, unhexlify('fbb20f0000000f00300000008700020067000a00018000000a0200000b19000050c360ea01091000')]]
|
chunks += [[
|
||||||
|
0x26,
|
||||||
|
unhexlify(
|
||||||
|
'fbb20f0000000f00300000008700020067000a00018000000a0200000b19000050c360ea01091000'
|
||||||
|
)
|
||||||
|
]]
|
||||||
# Image Reconstruction. There is only one byte difference with the "identify" version. (same is true for 0097)
|
# Image Reconstruction. There is only one byte difference with the "identify" version. (same is true for 0097)
|
||||||
chunks += [[0x2e, unhexlify('0200180023000000700070004d010000a0008c003c32321e3c0a0202')]]
|
chunks += [[
|
||||||
|
0x2e, unhexlify('0200180023000000700070004d010000a0008c003c32321e3c0a0202')
|
||||||
|
]]
|
||||||
|
|
||||||
#---------------- Interleave ---------------
|
# ---------------- Interleave ---------------
|
||||||
chunks += [[0x44, pack('<L', 1)]]
|
chunks += [[0x44, pack('<L', 1)]]
|
||||||
|
|
||||||
lines=[]
|
lines: typing.List[Line] = []
|
||||||
cnt=2 # TODO figure out why 2
|
cnt = 2 # TODO figure out why 2
|
||||||
|
|
||||||
l=Line()
|
l = Line()
|
||||||
lines += [l]
|
lines += [l]
|
||||||
l.mask = 0xff
|
l.mask = 0xff
|
||||||
# Find 2nd "Enable Rx" instruction
|
# Find 2nd "Enable Rx" instruction
|
||||||
pc, _ = prg.find_nth_insn(tst, 6, 2)
|
pc, _ = prg.find_nth_insn(tst, 6, 2)
|
||||||
l.flags = (pc + 1) | (cnt << 0x14) | 0x7000000
|
l.flags = (pc + 1) | (cnt << 0x14) | 0x7000000
|
||||||
l.data = self.type_info.calibration_blob
|
l.data = self.type_info.calibration_blob
|
||||||
l.v0 = 0xf
|
l.v0 = 0xf
|
||||||
cnt += 1
|
cnt += 1
|
||||||
|
|
||||||
l=Line()
|
l = Line()
|
||||||
lines += [l]
|
lines += [l]
|
||||||
l.mask = 0xff
|
l.mask = 0xff
|
||||||
# Find 1st "Write Register" instruction to the 0x8000203C port
|
# Find 1st "Write Register" instruction to the 0x8000203C port
|
||||||
pc, _ = prg.find_nth_regwrite(tst, 0x8000203C, 1)
|
pc, _ = prg.find_nth_regwrite(tst, 0x8000203C, 1)
|
||||||
l.flags = (pc + 1) | (cnt << 0x14) | 0x7000000
|
l.flags = (pc + 1) | (cnt << 0x14) | 0x7000000
|
||||||
l.v0, l.v1, l.data = bitpack(self.factory_calibration_values)
|
l.v0, l.v1, l.data = bitpack(self.factory_calibration_values)
|
||||||
l.v0 = (l.v0-1) | 8
|
l.v0 = (l.v0 - 1) | 8
|
||||||
cnt += 1
|
cnt += 1
|
||||||
|
|
||||||
if len(self.calib_data) > 0:
|
if len(self.calib_data) > 0:
|
||||||
bytes_per_calibration_line=len(self.calib_data) // self.type_info.lines_per_calibration_data
|
bytes_per_calibration_line = len(
|
||||||
|
self.calib_data) // self.type_info.lines_per_calibration_data
|
||||||
|
|
||||||
for i in range(0, 112, 4):
|
for i in range(0, 112, 4):
|
||||||
l=Line()
|
l = Line()
|
||||||
lines += [l]
|
lines += [l]
|
||||||
l.mask=0xffffffff
|
l.mask = 0xffffffff
|
||||||
l.flags=i | (0x85 << 24)
|
l.flags = i | (0x85 << 24)
|
||||||
l.data=b''
|
l.data = b''
|
||||||
for j in range(0, 112):
|
for j in range(0, 112):
|
||||||
p=8+j*bytes_per_calibration_line+i
|
p = 8 + j * bytes_per_calibration_line + i
|
||||||
l.data += self.calib_data[p:p+4]
|
l.data += self.calib_data[p:p + 4]
|
||||||
|
|
||||||
# Align to dwords, as the sensor demands it
|
# Align to dwords, as the sensor demands it
|
||||||
for l in lines:
|
for l in lines:
|
||||||
|
|
@ -446,25 +496,28 @@ class Sensor():
|
||||||
if pad > 0:
|
if pad > 0:
|
||||||
l.data += b'\0' * (4 - pad)
|
l.data += b'\0' * (4 - pad)
|
||||||
|
|
||||||
|
# ---------------- Line Update ---------------
|
||||||
#---------------- Line Update ---------------
|
|
||||||
line_update = pack('<L', len(lines))
|
line_update = pack('<L', len(lines))
|
||||||
line_update += b''.join([pack('<LL', l.mask, l.flags) for l in lines])
|
line_update += b''.join([pack('<LL', l.mask, l.flags) for l in lines])
|
||||||
|
|
||||||
line_update += b''.join([l.data for l in lines if ((l.flags & 0x00f00000) >> 0x14) <= 1])
|
line_update += b''.join([l.data for l in lines if ((l.flags & 0x00f00000) >> 0x14) <= 1])
|
||||||
chunks += [[0x30, line_update]]
|
chunks += [[0x30, line_update]]
|
||||||
|
|
||||||
#---------------- Line Update Transform ---------------
|
# ---------------- Line Update Transform ---------------
|
||||||
update_transform = b''.join([pack('<BBH', l.v0, l.v1, l.v2) + l.data for l in lines if ((l.flags & 0x00f00000) >> 0x14) > 1])
|
update_transform = b''.join([
|
||||||
|
pack('<BBH', l.v0, l.v1, l.v2) + l.data for l in lines
|
||||||
|
if ((l.flags & 0x00f00000) >> 0x14) > 1
|
||||||
|
])
|
||||||
chunks += [[0x43, update_transform]]
|
chunks += [[0x43, update_transform]]
|
||||||
|
|
||||||
return chunks
|
return chunks
|
||||||
|
|
||||||
def line_update_type_2(self, mode, chunks):
|
def line_update_type_2(self, mode: CaptureMode,
|
||||||
|
chunks: typing.List[typing.List[typing.Union[int, bytes]]]):
|
||||||
for c in chunks:
|
for c in chunks:
|
||||||
# patch the 2D params.
|
# patch the 2D params.
|
||||||
# The following is only needed on some rom versions below 6.5 as reported by cmd_01
|
# The following is only needed on some rom versions below 6.5 as reported by cmd_01
|
||||||
#if c[0] == 0x2f:
|
# if c[0] == 0x2f:
|
||||||
# c[1] = pack('<L', unpack('<L', c[1])[0]*mult)
|
# c[1] = pack('<L', unpack('<L', c[1])[0]*mult)
|
||||||
|
|
||||||
# Timeslot Table 2D
|
# Timeslot Table 2D
|
||||||
|
|
@ -472,10 +525,10 @@ class Sensor():
|
||||||
# TODO: figure out when to use address increment
|
# TODO: figure out when to use address increment
|
||||||
tst = self.patch_timeslot_table(c[1], True, self.type_info.repeat_multiplier)
|
tst = self.patch_timeslot_table(c[1], True, self.type_info.repeat_multiplier)
|
||||||
if mode != CaptureMode.CALIBRATE:
|
if mode != CaptureMode.CALIBRATE:
|
||||||
tst=self.patch_timeslot_again(tst)
|
tst = self.patch_timeslot_again(tst)
|
||||||
c[1] = tst
|
c[1] = tst
|
||||||
|
|
||||||
#---------------- Reply Configuration ---------------
|
# ---------------- Reply Configuration ---------------
|
||||||
chunks += [[0x17, b'']]
|
chunks += [[0x17, b'']]
|
||||||
|
|
||||||
if mode == CaptureMode.IDENTIFY:
|
if mode == CaptureMode.IDENTIFY:
|
||||||
|
|
@ -483,38 +536,52 @@ class Sensor():
|
||||||
# It seems to be only used for identification and it looks almost identical to Finger Detect (0x26)
|
# It seems to be only used for identification and it looks almost identical to Finger Detect (0x26)
|
||||||
# Seems to be the same all the time for a given sensor and mostly hardcoded
|
# Seems to be the same all the time for a given sensor and mostly hardcoded
|
||||||
# TODO: analyse construct_wtf_4e @0000000180090BF0
|
# TODO: analyse construct_wtf_4e @0000000180090BF0
|
||||||
chunks += [[0x4e, unhexlify('fbb20f0000000f00300000006001020040010a00018000000a0200000b1900008813b80b01091000')]]
|
chunks += [[
|
||||||
|
0x4e,
|
||||||
|
unhexlify(
|
||||||
|
'fbb20f0000000f00300000006001020040010a00018000000a0200000b1900008813b80b01091000'
|
||||||
|
)
|
||||||
|
]]
|
||||||
# Image Reconstruction.
|
# Image Reconstruction.
|
||||||
# TODO: analyse add_image_reconstruction_cmd_02_buff_list_item @000000018008EA70
|
# TODO: analyse add_image_reconstruction_cmd_02_buff_list_item @000000018008EA70
|
||||||
chunks += [[0x2e, unhexlify('0200180002000000900090004d01000090017c013c323232640a0201')]]
|
chunks += [[
|
||||||
|
0x2e, unhexlify('0200180002000000900090004d01000090017c013c323232640a0201')
|
||||||
|
]]
|
||||||
elif mode == CaptureMode.ENROLL:
|
elif mode == CaptureMode.ENROLL:
|
||||||
chunks += [[0x26, unhexlify('fbb20f0000000f00300000006001020040010a00018000000a0200000b19000050c360ea01091000')]]
|
chunks += [[
|
||||||
|
0x26,
|
||||||
|
unhexlify(
|
||||||
|
'fbb20f0000000f00300000006001020040010a00018000000a0200000b19000050c360ea01091000'
|
||||||
|
)
|
||||||
|
]]
|
||||||
# Image Reconstruction. There is only one byte difference with the "identify" version. (same is true for 0097)
|
# Image Reconstruction. There is only one byte difference with the "identify" version. (same is true for 0097)
|
||||||
chunks += [[0x2e, unhexlify('0200180023000000900090004d01000090017c013c323232640a0201')]]
|
chunks += [[
|
||||||
|
0x2e, unhexlify('0200180023000000900090004d01000090017c013c323232640a0201')
|
||||||
|
]]
|
||||||
|
|
||||||
lines = []
|
lines = []
|
||||||
|
|
||||||
l=Line()
|
l = Line()
|
||||||
lines += [l]
|
lines += [l]
|
||||||
l.mask = 0xff
|
l.mask = 0xff
|
||||||
# Find 2nd "Enable Rx" instruction
|
# Find 2nd "Enable Rx" instruction
|
||||||
pc, _ = prg.find_nth_insn(tst, 6, 2)
|
pc, _ = prg.find_nth_insn(tst, 6, 2)
|
||||||
l.flags = (pc + 1) | 0x3000000
|
l.flags = (pc + 1) | 0x3000000
|
||||||
l.data = self.type_info.calibration_blob
|
l.data = self.type_info.calibration_blob
|
||||||
|
|
||||||
l=Line()
|
l = Line()
|
||||||
lines += [l]
|
lines += [l]
|
||||||
l.mask = 0xff
|
l.mask = 0xff
|
||||||
# Find 1st "Write Register" instruction to the 0x8000203C port
|
# Find 1st "Write Register" instruction to the 0x8000203C port
|
||||||
pc, _ = prg.find_nth_regwrite(tst, 0x800020fc, 1)
|
pc, _ = prg.find_nth_regwrite(tst, 0x800020fc, 1)
|
||||||
l.flags = (pc + 1) | 0x3000000
|
l.flags = (pc + 1) | 0x3000000
|
||||||
l.data = self.factory_calib_data
|
l.data = self.factory_calib_data
|
||||||
|
|
||||||
l=Line()
|
l = Line()
|
||||||
lines += [l]
|
lines += [l]
|
||||||
l.mask = 0xff
|
l.mask = 0xff
|
||||||
# Find 1st "Write Register" instruction to the 0x8000203C port
|
# Find 1st "Write Register" instruction to the 0x8000203C port
|
||||||
pc, _ = prg.find_nth_regwrite(tst, 0x8000203c, 1)
|
pc, _ = prg.find_nth_regwrite(tst, 0x8000203c, 1)
|
||||||
l.flags = (pc + 1) | 0x3000000
|
l.flags = (pc + 1) | 0x3000000
|
||||||
l.data = self.factory_calibration_values
|
l.data = self.factory_calibration_values
|
||||||
|
|
||||||
|
|
@ -524,8 +591,7 @@ class Sensor():
|
||||||
if pad > 0:
|
if pad > 0:
|
||||||
l.data += b'\0' * (4 - pad)
|
l.data += b'\0' * (4 - pad)
|
||||||
|
|
||||||
|
# ---------------- Line Update ---------------
|
||||||
#---------------- Line Update ---------------
|
|
||||||
line_update = pack('<L', len(lines))
|
line_update = pack('<L', len(lines))
|
||||||
line_update += b''.join([pack('<LL', l.mask, l.flags) for l in lines])
|
line_update += b''.join([pack('<LL', l.mask, l.flags) for l in lines])
|
||||||
|
|
||||||
|
|
@ -534,25 +600,25 @@ class Sensor():
|
||||||
|
|
||||||
return chunks
|
return chunks
|
||||||
|
|
||||||
def build_cmd_02(self, mode):
|
def build_cmd_02(self, mode: CaptureMode):
|
||||||
chunks=list(prg.split_chunks(self.hardcoded_prog))
|
chunks = list(prg.split_chunks(self.hardcoded_prog))
|
||||||
|
|
||||||
if self.rom_info.product != 0x30:
|
if self.rom_info.product != 0x30:
|
||||||
raise Exception('Not implemented')
|
raise Exception('Not implemented')
|
||||||
|
|
||||||
if self.device_info.type in line_update_type1_devices:
|
if self.device_info.type in line_update_type1_devices:
|
||||||
chunks=self.line_update_type_1(mode, chunks)
|
chunks = self.line_update_type_1(mode, chunks)
|
||||||
else:
|
else:
|
||||||
chunks=self.line_update_type_2(mode, chunks)
|
chunks = self.line_update_type_2(mode, chunks)
|
||||||
|
|
||||||
if mode == CaptureMode.CALIBRATE:
|
if mode == CaptureMode.CALIBRATE:
|
||||||
req_lines = self.calibration_frames*self.lines_per_frame+1 # TODO: figure out how this is actually calculated
|
req_lines = self.calibration_frames * self.lines_per_frame + 1 # TODO: figure out how this is actually calculated
|
||||||
else:
|
else:
|
||||||
req_lines = 0
|
req_lines = 0
|
||||||
|
|
||||||
return pack('<BHH', 2, self.bytes_per_line, req_lines) + prg.merge_chunks(chunks)
|
return pack('<BHH', 2, self.bytes_per_line, req_lines) + prg.merge_chunks(chunks)
|
||||||
|
|
||||||
def persist_clean_slate(self, clean_slate):
|
def persist_clean_slate(self, clean_slate: bytes):
|
||||||
start = read_flash(6, 0, 0x44)
|
start = read_flash(6, 0, 0x44)
|
||||||
|
|
||||||
if start != b'\xff' * 0x44:
|
if start != b'\xff' * 0x44:
|
||||||
|
|
@ -574,8 +640,8 @@ class Sensor():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
hs, zeroes = start[0:0x20], start[0x20:0x40]
|
hs, zeroes = start[0:0x20], start[0x20:0x40]
|
||||||
|
|
||||||
if zeroes != b'\0'*0x20:
|
if zeroes != b'\0' * 0x20:
|
||||||
logging.warning('Unexpected contents in calibration flash partition')
|
logging.warning('Unexpected contents in calibration flash partition')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
@ -586,7 +652,6 @@ class Sensor():
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def calibrate(self):
|
def calibrate(self):
|
||||||
if os.path.isfile(calib_data_path):
|
if os.path.isfile(calib_data_path):
|
||||||
with open(calib_data_path, 'rb') as f:
|
with open(calib_data_path, 'rb') as f:
|
||||||
|
|
@ -615,8 +680,9 @@ class Sensor():
|
||||||
|
|
||||||
clean_slate = self.average(usb.read_82())
|
clean_slate = self.average(usb.read_82())
|
||||||
clean_slate = pack('<H', len(clean_slate)) + clean_slate
|
clean_slate = pack('<H', len(clean_slate)) + clean_slate
|
||||||
clean_slate = clean_slate + pack('<H', 0) # TODO: still don't know what this zero is for
|
clean_slate = clean_slate + pack('<H', 0) # TODO: still don't know what this zero is for
|
||||||
clean_slate = pack('<H', len(clean_slate)) + sha256(clean_slate).digest() + b'\0'*0x20 + clean_slate
|
clean_slate = pack(
|
||||||
|
'<H', len(clean_slate)) + sha256(clean_slate).digest() + b'\0' * 0x20 + clean_slate
|
||||||
clean_slate = pack('<H', 0x5002) + clean_slate
|
clean_slate = pack('<H', 0x5002) + clean_slate
|
||||||
|
|
||||||
self.persist_clean_slate(clean_slate)
|
self.persist_clean_slate(clean_slate)
|
||||||
|
|
@ -625,7 +691,7 @@ class Sensor():
|
||||||
def cancel(self):
|
def cancel(self):
|
||||||
usb.cancel = True
|
usb.cancel = True
|
||||||
|
|
||||||
def capture(self, mode):
|
def capture(self, mode: CaptureMode) -> typing.Tuple[int, int, int, int]:
|
||||||
try:
|
try:
|
||||||
assert_status(tls.app(self.build_cmd_02(mode)))
|
assert_status(tls.app(self.build_cmd_02(mode)))
|
||||||
|
|
||||||
|
|
@ -638,8 +704,8 @@ class Sensor():
|
||||||
while True:
|
while True:
|
||||||
b = usb.wait_int()
|
b = usb.wait_int()
|
||||||
if b[0] == 2:
|
if b[0] == 2:
|
||||||
break;
|
break
|
||||||
|
|
||||||
# wait capture complete
|
# wait capture complete
|
||||||
while True:
|
while True:
|
||||||
b = usb.wait_int()
|
b = usb.wait_int()
|
||||||
|
|
@ -648,12 +714,12 @@ class Sensor():
|
||||||
|
|
||||||
if b[2] & 4:
|
if b[2] & 4:
|
||||||
break
|
break
|
||||||
|
|
||||||
res = get_prg_status2()
|
res = get_prg_status2()
|
||||||
|
|
||||||
assert_status(res)
|
assert_status(res)
|
||||||
res = res[2:]
|
res = res[2:]
|
||||||
|
|
||||||
l, res = res[:4], res[4:]
|
l, res = res[:4], res[4:]
|
||||||
l, = unpack('<L', l)
|
l, = unpack('<L', l)
|
||||||
|
|
||||||
|
|
@ -665,14 +731,13 @@ class Sensor():
|
||||||
if error != 0:
|
if error != 0:
|
||||||
raise Exception('Scanning problem: %04x' % error)
|
raise Exception('Scanning problem: %04x' % error)
|
||||||
|
|
||||||
return (x, y, w1, w2)
|
return x, y, w1, w2
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
tls.app(unhexlify('04')) # capture stop if still running, cleanup
|
tls.app(unhexlify('04')) # capture stop if still running, cleanup
|
||||||
|
|
||||||
|
def enrollment_update_start(self, key: int) -> int:
|
||||||
def enrollment_update_start(self, key):
|
rsp = tls.app(pack('<BLL', 0x68, key, 0))
|
||||||
rsp=tls.app(pack('<BLL', 0x68, key, 0))
|
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
new_key, = unpack('<L', rsp[2:])
|
new_key, = unpack('<L', rsp[2:])
|
||||||
|
|
||||||
|
|
@ -687,19 +752,19 @@ class Sensor():
|
||||||
assert_status(tls.app(pack('<BL', 0x69, 0)))
|
assert_status(tls.app(pack('<BL', 0x69, 0)))
|
||||||
|
|
||||||
# Generates interrupt
|
# Generates interrupt
|
||||||
def enrollment_update(self, prev):
|
def enrollment_update(self, prev: bytes):
|
||||||
write_enable()
|
write_enable()
|
||||||
try:
|
try:
|
||||||
rsp=tls.app(b'\x6b' + prev)
|
rsp = tls.app(b'\x6b' + prev)
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
finally:
|
finally:
|
||||||
call_cleanups()
|
call_cleanups()
|
||||||
|
|
||||||
return rsp[2:]
|
return rsp[2:]
|
||||||
|
|
||||||
def append_new_image(self, prev):
|
def append_new_image(self, prev: bytes):
|
||||||
self.enrollment_update(prev)
|
self.enrollment_update(prev)
|
||||||
|
|
||||||
usb.wait_int()
|
usb.wait_int()
|
||||||
|
|
||||||
res = self.enrollment_update(prev)
|
res = self.enrollment_update(prev)
|
||||||
|
|
@ -709,27 +774,26 @@ class Sensor():
|
||||||
if l != len(res):
|
if l != len(res):
|
||||||
raise Exception('Response size does not match %d != %d', l, len(res))
|
raise Exception('Response size does not match %d != %d', l, len(res))
|
||||||
|
|
||||||
magic_len = 0x38 # hardcoded in the DLL
|
magic_len = 0x38 # hardcoded in the DLL
|
||||||
template = header = tid = None
|
template = header = tid = None
|
||||||
|
|
||||||
while len(res) > 0:
|
while len(res) > 0:
|
||||||
tag, l = unpack('<HH', res[:4])
|
tag, l = unpack('<HH', res[:4])
|
||||||
|
|
||||||
if tag == 0:
|
if tag == 0:
|
||||||
template = res[:magic_len+l]
|
template = res[:magic_len + l]
|
||||||
elif tag == 1:
|
elif tag == 1:
|
||||||
header = res[magic_len:magic_len+l]
|
header = res[magic_len:magic_len + l]
|
||||||
elif tag == 3:
|
elif tag == 3:
|
||||||
tid = res[magic_len:magic_len+l]
|
tid = res[magic_len:magic_len + l]
|
||||||
else:
|
else:
|
||||||
logging.warning('Ignoring unknown tag %x' % tag)
|
logging.warning('Ignoring unknown tag %x' % tag)
|
||||||
|
|
||||||
res=res[magic_len+l:]
|
|
||||||
|
|
||||||
return (header, template, tid)
|
res = res[magic_len + l:]
|
||||||
|
|
||||||
|
|
||||||
def make_finger_data(self, subtype, template, tid):
|
return header, template, tid
|
||||||
|
|
||||||
|
def make_finger_data(self, subtype: int, template: bytes, tid: bytes):
|
||||||
template = pack('<HH', 1, len(template)) + template
|
template = pack('<HH', 1, len(template)) + template
|
||||||
tid = pack('<HH', 2, len(tid)) + tid
|
tid = pack('<HH', 2, len(tid)) + tid
|
||||||
|
|
||||||
|
|
@ -743,15 +807,15 @@ class Sensor():
|
||||||
# TODO: Better typing information needed.
|
# TODO: Better typing information needed.
|
||||||
def enroll(self, identity: SidIdentity, subtype: int,
|
def enroll(self, identity: SidIdentity, subtype: int,
|
||||||
update_cb: typing.Callable[[typing.Any, typing.Optional[Exception]], None]):
|
update_cb: typing.Callable[[typing.Any, typing.Optional[Exception]], None]):
|
||||||
def do_create_finger(final_template, tid):
|
def do_create_finger(final_template: bytes, tid: bytes):
|
||||||
tinfo = self.make_finger_data(subtype, final_template, tid)
|
tinfo = self.make_finger_data(subtype, final_template, tid)
|
||||||
|
|
||||||
usr=db.lookup_user(identity)
|
usr = db.lookup_user(identity)
|
||||||
if usr == None:
|
if usr is None:
|
||||||
usr = db.new_user(identity)
|
usr = db.new_user(identity)
|
||||||
else:
|
else:
|
||||||
usr = usr.dbid
|
usr = usr.dbid
|
||||||
|
|
||||||
recid = db.new_finger(usr, tinfo)
|
recid = db.new_finger(usr, tinfo)
|
||||||
usb.wait_int()
|
usb.wait_int()
|
||||||
|
|
||||||
|
|
@ -759,8 +823,8 @@ class Sensor():
|
||||||
|
|
||||||
return recid
|
return recid
|
||||||
|
|
||||||
key=0
|
key = 0
|
||||||
template=b''
|
template = b''
|
||||||
self.create_enrollment()
|
self.create_enrollment()
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
|
|
@ -785,11 +849,11 @@ class Sensor():
|
||||||
finally:
|
finally:
|
||||||
self.enrollment_update_end()
|
self.enrollment_update_end()
|
||||||
|
|
||||||
self.enrollment_update_end() # done twice for some reason
|
self.enrollment_update_end() # done twice for some reason
|
||||||
return do_create_finger(template, tid)
|
return do_create_finger(template, tid)
|
||||||
|
|
||||||
def parse_dict(self, x):
|
def parse_dict(self, x: bytes):
|
||||||
rc={}
|
rc = {}
|
||||||
|
|
||||||
while len(x) > 0:
|
while len(x) > 0:
|
||||||
(t, l), x = unpack('<HH', x[:4]), x[4:]
|
(t, l), x = unpack('<HH', x[:4]), x[4:]
|
||||||
|
|
@ -799,10 +863,10 @@ class Sensor():
|
||||||
|
|
||||||
def match_finger(self) -> typing.Tuple[int, int, bytes]:
|
def match_finger(self) -> typing.Tuple[int, int, bytes]:
|
||||||
try:
|
try:
|
||||||
stg_id=0 # match against any storage
|
stg_id = 0 # match against any storage
|
||||||
usr_id=0 # match against any user
|
usr_id = 0 # match against any user
|
||||||
cmd=pack('<BBBHHHHH', 0x5e, 2, 0xff, stg_id, usr_id, 1, 0,0)
|
cmd = pack('<BBBHHHHH', 0x5e, 2, 0xff, stg_id, usr_id, 1, 0, 0)
|
||||||
rsp=tls.app(cmd)
|
rsp = tls.app(cmd)
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
|
|
||||||
b = usb.wait_int()
|
b = usb.wait_int()
|
||||||
|
|
@ -814,23 +878,22 @@ class Sensor():
|
||||||
assert_status(rsp)
|
assert_status(rsp)
|
||||||
rsp = rsp[2:]
|
rsp = rsp[2:]
|
||||||
|
|
||||||
(l,), rsp = unpack('<H', rsp[:2]), rsp[2:]
|
(l, ), rsp = unpack('<H', rsp[:2]), rsp[2:]
|
||||||
if l != len(rsp):
|
if l != len(rsp):
|
||||||
raise Exception('Response size does not match')
|
raise Exception('Response size does not match')
|
||||||
|
|
||||||
rsp=self.parse_dict(rsp)
|
rsp = self.parse_dict(rsp)
|
||||||
|
|
||||||
usrid, subtype, hsh = rsp[1], rsp[3], rsp[4]
|
usrid, subtype, hsh = rsp[1], rsp[3], rsp[4]
|
||||||
usrid, = unpack('<L', usrid)
|
usrid, = unpack('<L', usrid)
|
||||||
subtype, = unpack('<H', subtype)
|
subtype, = unpack('<H', subtype)
|
||||||
|
|
||||||
return (usrid, subtype, hsh)
|
return usrid, subtype, hsh
|
||||||
finally:
|
finally:
|
||||||
# cleanup, ignore any errors
|
# cleanup, ignore any errors
|
||||||
tls.app(unhexlify('6200000000'))
|
tls.app(unhexlify('6200000000'))
|
||||||
|
|
||||||
|
def identify(self, update_cb: typing.Callable[[Exception], None]):
|
||||||
def identify(self, update_cb):
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
glow_start_scan()
|
glow_start_scan()
|
||||||
|
|
@ -848,17 +911,17 @@ class Sensor():
|
||||||
|
|
||||||
return self.match_finger()
|
return self.match_finger()
|
||||||
|
|
||||||
def get_finger_blobs(self, usrid, subtype):
|
def get_finger_blobs(self, usrid: int, subtype: int):
|
||||||
usr = db.get_user(usrid)
|
usr = db.get_user(usrid)
|
||||||
fingerids = [f['dbid'] for f in usr.fingers if f['subtype'] == subtype]
|
fingerids = [f['dbid'] for f in usr.fingers if f['subtype'] == subtype]
|
||||||
|
|
||||||
if len(fingerids) != 1:
|
if len(fingerids) != 1:
|
||||||
raise Exception('Unexpected matching finger count')
|
raise Exception('Unexpected matching finger count')
|
||||||
|
|
||||||
finger_record = db.get_record_children(fingerids[0])
|
finger_record = db.get_record_children(fingerids[0])
|
||||||
|
|
||||||
ids=[r['dbid'] for r in finger_record.children if r['type'] == 8]
|
ids = [r['dbid'] for r in finger_record.children if r['type'] == 8]
|
||||||
return [db.get_record_value(id).value for id in ids]
|
return [db.get_record_value(id).value for id in ids]
|
||||||
|
|
||||||
sensor = Sensor()
|
|
||||||
|
|
||||||
|
sensor = Sensor()
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
|
|
||||||
from struct import unpack, pack
|
|
||||||
import typing
|
import typing
|
||||||
|
from struct import unpack, pack
|
||||||
|
|
||||||
class SidIdentity():
|
|
||||||
|
class SidIdentity:
|
||||||
def __init__(self, revision: int, auth: int, subauth: typing.Sequence[int]):
|
def __init__(self, revision: int, auth: int, subauth: typing.Sequence[int]):
|
||||||
self.revision = revision
|
self.revision = revision
|
||||||
self.auth = auth
|
self.auth = auth
|
||||||
self.subauth = subauth
|
self.subauth = subauth
|
||||||
|
|
||||||
def to_bytes(self):
|
def to_bytes(self):
|
||||||
b=pack('>BBHL', self.revision, len(self.subauth), self.auth >> 32, self.auth & 0xffffffff)
|
b = pack('>BBHL', self.revision, len(self.subauth), self.auth >> 32, self.auth & 0xffffffff)
|
||||||
for i in self.subauth:
|
for i in self.subauth:
|
||||||
b += pack('<L', i)
|
b += pack('<L', i)
|
||||||
|
|
||||||
|
|
@ -18,6 +18,7 @@ class SidIdentity():
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'S-%d-%d-%s' % (self.revision, self.auth, '-'.join(map(str, self.subauth)))
|
return 'S-%d-%d-%s' % (self.revision, self.auth, '-'.join(map(str, self.subauth)))
|
||||||
|
|
||||||
|
|
||||||
def sid_from_bytes(b: bytes):
|
def sid_from_bytes(b: bytes):
|
||||||
revision = b[0]
|
revision = b[0]
|
||||||
subcnt = b[1]
|
subcnt = b[1]
|
||||||
|
|
@ -26,11 +27,12 @@ def sid_from_bytes(b: bytes):
|
||||||
for i in b[2:8]:
|
for i in b[2:8]:
|
||||||
auth <<= 8
|
auth <<= 8
|
||||||
auth |= i
|
auth |= i
|
||||||
|
|
||||||
subauth=unpack('<%dL' % subcnt, b[8:])
|
subauth = unpack('<%dL' % subcnt, b[8:])
|
||||||
|
|
||||||
return SidIdentity(revision, auth, subauth)
|
return SidIdentity(revision, auth, subauth)
|
||||||
|
|
||||||
|
|
||||||
def sid_from_string(s: str):
|
def sid_from_string(s: str):
|
||||||
parts = s.split('-')
|
parts = s.split('-')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,33 @@
|
||||||
|
import typing
|
||||||
from binascii import hexlify, unhexlify
|
from binascii import hexlify, unhexlify
|
||||||
|
|
||||||
|
|
||||||
class SensorTypeInfo:
|
class SensorTypeInfo:
|
||||||
table=[]
|
table: typing.List["SensorTypeInfo"] = []
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_by_type(cls, sensor_type):
|
def get_by_type(cls, sensor_type: int) -> typing.Optional["SensorTypeInfo"]:
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
from . import generated_tables
|
from . import generated_tables
|
||||||
for i in cls.table:
|
for i in cls.table:
|
||||||
if i.sensor_type == sensor_type:
|
if i.sensor_type == sensor_type:
|
||||||
return i
|
return i
|
||||||
|
|
||||||
def __init__(self, sensor_type, bytes_per_line, repeat_multiplier, lines_per_calibration_data, line_width, calibration_blob):
|
def __init__(self, sensor_type: int, bytes_per_line: int, repeat_multiplier: int,
|
||||||
self.sensor_type=sensor_type
|
lines_per_calibration_data: int, line_width: int, calibration_blob: str):
|
||||||
self.repeat_multiplier=repeat_multiplier
|
self.sensor_type = sensor_type
|
||||||
self.lines_per_calibration_data=lines_per_calibration_data
|
self.repeat_multiplier = repeat_multiplier
|
||||||
self.line_width=line_width
|
self.lines_per_calibration_data = lines_per_calibration_data
|
||||||
self.bytes_per_line=bytes_per_line
|
self.line_width = line_width
|
||||||
self.calibration_blob=unhexlify(calibration_blob)
|
self.bytes_per_line = bytes_per_line
|
||||||
|
self.calibration_blob = unhexlify(calibration_blob)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
calibration_blob=hexlify(self.calibration_blob).decode()
|
calibration_blob = hexlify(self.calibration_blob).decode()
|
||||||
return 'SensorTypeInfo(sensor_type=0x%04x, bytes_per_line=0x%x, repeat_multiplier=%d, lines_per_calibration_data=%d, line_width=%d, calibration_blob=%s)' % (
|
return 'SensorTypeInfo(sensor_type=0x%04x, bytes_per_line=0x%x, repeat_multiplier=%d, lines_per_calibration_data=%d, line_width=%d, calibration_blob=%s)' % (
|
||||||
self.sensor_type, self.bytes_per_line, self.repeat_multiplier, self.lines_per_calibration_data, self.line_width, repr(calibration_blob))
|
self.sensor_type, self.bytes_per_line, self.repeat_multiplier,
|
||||||
|
self.lines_per_calibration_data, self.line_width, repr(calibration_blob))
|
||||||
|
|
||||||
|
|
||||||
def fuzzy(expected, actual):
|
def fuzzy(expected, actual):
|
||||||
if expected == actual:
|
if expected == actual:
|
||||||
|
|
@ -32,6 +37,7 @@ def fuzzy(expected, actual):
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def metric(i, rominfo):
|
def metric(i, rominfo):
|
||||||
metric = 0
|
metric = 0
|
||||||
metric |= fuzzy(i.major, rominfo.major)
|
metric |= fuzzy(i.major, rominfo.major)
|
||||||
|
|
@ -42,13 +48,15 @@ def metric(i, rominfo):
|
||||||
metric <<= 2
|
metric <<= 2
|
||||||
metric |= fuzzy(i.u1, rominfo.u1)
|
metric |= fuzzy(i.u1, rominfo.u1)
|
||||||
|
|
||||||
return metric
|
return metric
|
||||||
|
|
||||||
|
|
||||||
class SensorCaptureProg:
|
class SensorCaptureProg:
|
||||||
table=[]
|
table: typing.List["SensorCaptureProg"] = []
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get(cls, rominfo, sensor_type, a0, a1):
|
def get(cls, rominfo, sensor_type: int, a0: int, a1: int):
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
from . import generated_tables
|
from . import generated_tables
|
||||||
|
|
||||||
maximum = 0
|
maximum = 0
|
||||||
|
|
@ -74,20 +82,20 @@ class SensorCaptureProg:
|
||||||
|
|
||||||
if found is not None:
|
if found is not None:
|
||||||
return b''.join(found.blobs)
|
return b''.join(found.blobs)
|
||||||
|
|
||||||
def __init__(self, major, minor, build, u1, dev_type, a0, a1, blobs):
|
def __init__(self, major: int, minor: int, build: int, u1: int, dev_type: int, a0: int, a1: int,
|
||||||
self.major=major
|
blobs: typing.Sequence[str]):
|
||||||
self.minor=minor
|
self.major = major
|
||||||
self.build=build
|
self.minor = minor
|
||||||
self.u1=u1
|
self.build = build
|
||||||
self.dev_type=dev_type
|
self.u1 = u1
|
||||||
self.a0=a0
|
self.dev_type = dev_type
|
||||||
self.a1=a1
|
self.a0 = a0
|
||||||
blobs=[unhexlify(b) for b in blobs]
|
self.a1 = a1
|
||||||
self.blobs=blobs
|
self.blobs = [unhexlify(b) for b in blobs]
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
blobs=[hexlify(b).decode() for b in self.blobs]
|
blobs = [hexlify(b).decode() for b in self.blobs]
|
||||||
|
|
||||||
return 'SensorCaptureProg(major=0x%x, minor=0x%x, build=0x%x, u1=0x%x, dev_type=0x%x, a0=0x%x, a1=0x%x, blobs=%s)' % (
|
return 'SensorCaptureProg(major=0x%x, minor=0x%x, build=0x%x, u1=0x%x, dev_type=0x%x, a0=0x%x, a1=0x%x, blobs=%s)' % (
|
||||||
self.major, self.minor, self.build, self.u1, self.dev_type, self.a0, self.a1,
|
self.major, self.minor, self.build, self.u1, self.dev_type, self.a0, self.a1,
|
||||||
|
|
|
||||||
|
|
@ -1,151 +1,155 @@
|
||||||
|
import typing
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
from struct import unpack, pack
|
from struct import unpack, pack
|
||||||
|
|
||||||
codes={}
|
codes = {}
|
||||||
codes[0x0] = "No Operation"
|
codes[0x0] = "No Operation"
|
||||||
codes[0x1] = "Swipe"
|
codes[0x1] = "Swipe"
|
||||||
codes[0x2] = "Timeslot Configuration"
|
codes[0x2] = "Timeslot Configuration"
|
||||||
codes[0x3] = "Register"
|
codes[0x3] = "Register"
|
||||||
codes[0x4] = "Register Set 32"
|
codes[0x4] = "Register Set 32"
|
||||||
codes[0x5] = "Register Operation 32"
|
codes[0x5] = "Register Operation 32"
|
||||||
codes[0x6] = "Security"
|
codes[0x6] = "Security"
|
||||||
codes[0x7] = "WOE"
|
codes[0x7] = "WOE"
|
||||||
codes[0x8] = "Motion 1"
|
codes[0x8] = "Motion 1"
|
||||||
codes[0xa] = "CPUCLK"
|
codes[0xa] = "CPUCLK"
|
||||||
codes[0xb] = "Motion 2"
|
codes[0xb] = "Motion 2"
|
||||||
codes[0xc] = "Calibration Block"
|
codes[0xc] = "Calibration Block"
|
||||||
codes[0xd] = "Sweep"
|
codes[0xd] = "Sweep"
|
||||||
codes[0xe] = "Zone Configuration"
|
codes[0xe] = "Zone Configuration"
|
||||||
codes[0xf] = "Zones Per Sweep"
|
codes[0xf] = "Zones Per Sweep"
|
||||||
codes[0x10] = "Lines Per Sweep Iteration"
|
codes[0x10] = "Lines Per Sweep Iteration"
|
||||||
codes[0x11] = "Lines Per Sweep"
|
codes[0x11] = "Lines Per Sweep"
|
||||||
codes[0x12] = "Total Zones"
|
codes[0x12] = "Total Zones"
|
||||||
codes[0x13] = "CAL WOE Ctrl"
|
codes[0x13] = "CAL WOE Ctrl"
|
||||||
codes[0x14] = "Cal WOE Mask"
|
codes[0x14] = "Cal WOE Mask"
|
||||||
codes[0x15] = "BW Reduciton"
|
codes[0x15] = "BW Reduciton"
|
||||||
codes[0x16] = "AGC"
|
codes[0x16] = "AGC"
|
||||||
codes[0x17] = "Reply Configuration"
|
codes[0x17] = "Reply Configuration"
|
||||||
codes[0x18] = "Motion 3"
|
codes[0x18] = "Motion 3"
|
||||||
codes[0x19] = "WOVAR"
|
codes[0x19] = "WOVAR"
|
||||||
codes[0x1a] = "Block MOde"
|
codes[0x1a] = "Block MOde"
|
||||||
codes[0x1b] = "Bit Reduction"
|
codes[0x1b] = "Bit Reduction"
|
||||||
codes[0x1c] = "Motion 4"
|
codes[0x1c] = "Motion 4"
|
||||||
codes[0x1d] = "Calibration WOENF"
|
codes[0x1d] = "Calibration WOENF"
|
||||||
codes[0x1e] = "Calibration"
|
codes[0x1e] = "Calibration"
|
||||||
codes[0x1f] = "Zone Configuration A"
|
codes[0x1f] = "Zone Configuration A"
|
||||||
codes[0x20] = "Set Register 32"
|
codes[0x20] = "Set Register 32"
|
||||||
codes[0x21] = "Register Operation 32A"
|
codes[0x21] = "Register Operation 32A"
|
||||||
codes[0x22] = "Fingerprint Buffering"
|
codes[0x22] = "Fingerprint Buffering"
|
||||||
codes[0x23] = "Reply Config + Timeslot Table"
|
codes[0x23] = "Reply Config + Timeslot Table"
|
||||||
codes[0x24] = "Baseline"
|
codes[0x24] = "Baseline"
|
||||||
codes[0x25] = "SO Alternate"
|
codes[0x25] = "SO Alternate"
|
||||||
codes[0x26] = "Finger Detect"
|
codes[0x26] = "Finger Detect"
|
||||||
codes[0x27] = "Finger Detect Sample Register"
|
codes[0x27] = "Finger Detect Sample Register"
|
||||||
codes[0x28] = "Finger Detect Scan Registers"
|
codes[0x28] = "Finger Detect Scan Registers"
|
||||||
codes[0x29] = "Timeslot Table Offset"
|
codes[0x29] = "Timeslot Table Offset"
|
||||||
codes[0x2a] = "ACM Config"
|
codes[0x2a] = "ACM Config"
|
||||||
codes[0x2b] = "ACM Control"
|
codes[0x2b] = "ACM Control"
|
||||||
codes[0x2c] = "CEM Config"
|
codes[0x2c] = "CEM Config"
|
||||||
codes[0x2d] = "CEM Control"
|
codes[0x2d] = "CEM Control"
|
||||||
codes[0x2e] = "Image Reconstruction"
|
codes[0x2e] = "Image Reconstruction"
|
||||||
codes[0x2f] = "2D"
|
codes[0x2f] = "2D"
|
||||||
codes[0x30] = "Line Update"
|
codes[0x30] = "Line Update"
|
||||||
codes[0x31] = "FDetect Timeslot Table"
|
codes[0x31] = "FDetect Timeslot Table"
|
||||||
codes[0x32] = "Register List 16"
|
codes[0x32] = "Register List 16"
|
||||||
codes[0x33] = "Register list 32"
|
codes[0x33] = "Register list 32"
|
||||||
codes[0x34] = "Timeslot Table 2D"
|
codes[0x34] = "Timeslot Table 2D"
|
||||||
codes[0x35] = "Timeslot Table Offset for Finger Detect"
|
codes[0x35] = "Timeslot Table Offset for Finger Detect"
|
||||||
codes[0x36] = "Security Aligned"
|
codes[0x36] = "Security Aligned"
|
||||||
codes[0x37] = "WOF2"
|
codes[0x37] = "WOF2"
|
||||||
codes[0x38] = "WOE WOF"
|
codes[0x38] = "WOE WOF"
|
||||||
codes[0x39] = "Navigation"
|
codes[0x39] = "Navigation"
|
||||||
codes[0x3a] = "WOE WOF2 Version2"
|
codes[0x3a] = "WOE WOF2 Version2"
|
||||||
codes[0x3b] = "Cal WOE WOF2"
|
codes[0x3b] = "Cal WOE WOF2"
|
||||||
codes[0x3c] = "Event Signal"
|
codes[0x3c] = "Event Signal"
|
||||||
codes[0x3d] = "IFS Frame Stats"
|
codes[0x3d] = "IFS Frame Stats"
|
||||||
codes[0x3e] = "SNR Method 4"
|
codes[0x3e] = "SNR Method 4"
|
||||||
codes[0x3f] = "WOE WOF2 Version 3"
|
codes[0x3f] = "WOE WOF2 Version 3"
|
||||||
codes[0x40] = "Calibrate WOE WOF2 Version 3"
|
codes[0x40] = "Calibrate WOE WOF2 Version 3"
|
||||||
codes[0x41] = "Finger Detect Ratchet"
|
codes[0x41] = "Finger Detect Ratchet"
|
||||||
codes[0x42] = "Data Encoder"
|
codes[0x42] = "Data Encoder"
|
||||||
codes[0x43] = "Line Update Transform"
|
codes[0x43] = "Line Update Transform"
|
||||||
codes[0x44] = "Line Update InterLeave"
|
codes[0x44] = "Line Update InterLeave"
|
||||||
codes[0x45] = "SO Table Values for Macros"
|
codes[0x45] = "SO Table Values for Macros"
|
||||||
codes[0x46] = "Timeslot Macro Definitions"
|
codes[0x46] = "Timeslot Macro Definitions"
|
||||||
codes[0x47] = "Enable ASP Feature"
|
codes[0x47] = "Enable ASP Feature"
|
||||||
codes[0x48] = "Baseline Frame"
|
codes[0x48] = "Baseline Frame"
|
||||||
codes[0x49] = "Rx Select"
|
codes[0x49] = "Rx Select"
|
||||||
codes[0x4e] = "WTF"
|
codes[0x4e] = "WTF"
|
||||||
codes[0xffff] = "Unknown"
|
codes[0xffff] = "Unknown"
|
||||||
|
|
||||||
insn_to_string=[
|
insn_to_string = [
|
||||||
'NOOP', # 0
|
'NOOP', # 0
|
||||||
'End of Table', # 1
|
'End of Table', # 1
|
||||||
'Return', # 2
|
'Return', # 2
|
||||||
'Clear SO', # 3
|
'Clear SO', # 3
|
||||||
'End of Data', # 4
|
'End of Data', # 4
|
||||||
'Marco %02x', # 5
|
'Marco %02x', # 5
|
||||||
'Enable Rx 0x%02x', # 6
|
'Enable Rx 0x%02x', # 6
|
||||||
'Idle Rx 0x%03x', # 7
|
'Idle Rx 0x%03x', # 7
|
||||||
'Enable SO 0x%03x', # 8
|
'Enable SO 0x%03x', # 8
|
||||||
'Disable SO 0x%03x', # 9
|
'Disable SO 0x%03x', # 9
|
||||||
'Interrupt %x', # 10
|
'Interrupt %x', # 10
|
||||||
'Call rx_inc=%d, addr=%x, repeat=%d', # 11
|
'Call rx_inc=%d, addr=%x, repeat=%d', # 11
|
||||||
'Features %02x', # 12
|
'Features %02x', # 12
|
||||||
'Register Write *0x%08x = 0x%04x', # 13
|
'Register Write *0x%08x = 0x%04x', # 13
|
||||||
'Sample %x, %x', # 14
|
'Sample %x, %x', # 14
|
||||||
'Sample Repeat %x, %x, repeat=%x', # 15
|
'Sample Repeat %x, %x, repeat=%x', # 15
|
||||||
]
|
]
|
||||||
|
|
||||||
def decode_insn(b):
|
|
||||||
|
def decode_insn(b: bytes):
|
||||||
if b[0] == 0:
|
if b[0] == 0:
|
||||||
return (0, 1)
|
return 0, 1
|
||||||
elif b[0] == 1:
|
elif b[0] == 1:
|
||||||
return (1, 1)
|
return 1, 1
|
||||||
elif b[0] == 2:
|
elif b[0] == 2:
|
||||||
return (2, 1)
|
return 2, 1
|
||||||
elif b[0] == 3:
|
elif b[0] == 3:
|
||||||
return (3, 1)
|
return 3, 1
|
||||||
elif b[0] == 4:
|
elif b[0] == 4:
|
||||||
return (4, 1)
|
return 4, 1
|
||||||
elif b[0] == 5:
|
elif b[0] == 5:
|
||||||
return (5, 2, b[1])
|
return 5, 2, b[1]
|
||||||
elif b[0] == 6:
|
elif b[0] == 6:
|
||||||
return (6, 2, b[1])
|
return 6, 2, b[1]
|
||||||
elif b[0] == 7:
|
elif b[0] == 7:
|
||||||
return (7, 2, 0x100 if b[1] == 0 else b[1])
|
return 7, 2, 0x100 if b[1] == 0 else b[1]
|
||||||
elif b[0] & 0xfe == 8:
|
elif b[0] & 0xfe == 8:
|
||||||
return (8, 2, (b[0] & 1) << 8 | b[1])
|
return 8, 2, (b[0] & 1) << 8 | b[1]
|
||||||
elif b[0] & 0xfe == 0xa:
|
elif b[0] & 0xfe == 0xa:
|
||||||
return (9, 2, (b[0] & 1) << 8 | b[1])
|
return 9, 2, (b[0] & 1) << 8 | b[1]
|
||||||
elif b[0] & 0xfc == 0xc:
|
elif b[0] & 0xfc == 0xc:
|
||||||
return (10, 1, b[0] & 3)
|
return 10, 1, b[0] & 3
|
||||||
elif b[0] & 0xf8 == 0x10:
|
elif b[0] & 0xf8 == 0x10:
|
||||||
return (11, 3, b[0] & 7, b[1] << 2, 0x100 if b[2] == 0 else b[2])
|
return 11, 3, b[0] & 7, b[1] << 2, 0x100 if b[2] == 0 else b[2]
|
||||||
elif b[0] & 0xe0 == 0x20:
|
elif b[0] & 0xe0 == 0x20:
|
||||||
return (12, 1, b[0] & 0x1f) # TODO check how features are converted to op args
|
return 12, 1, b[0] & 0x1f # TODO check how features are converted to op args
|
||||||
elif b[0] & 0xc0 == 0x40:
|
elif b[0] & 0xc0 == 0x40:
|
||||||
return (13, 3, (b[0] & 0x3f)*4+0x80002000, b[1] | (b[2] << 8))
|
return 13, 3, (b[0] & 0x3f) * 4 + 0x80002000, b[1] | (b[2] << 8)
|
||||||
elif b[0] & 0xc0 == 0x80:
|
elif b[0] & 0xc0 == 0x80:
|
||||||
return (14, 1, (b[0] & 0x38) >> 3, b[0] & 7)
|
return 14, 1, (b[0] & 0x38) >> 3, b[0] & 7
|
||||||
elif b[0] & 0xc0 == 0xc0:
|
elif b[0] & 0xc0 == 0xc0:
|
||||||
return (15, 2, (b[0] & 0x38) >> 3, b[0] & 7, 0x100 if b[1] == 0 else b[1])
|
return 15, 2, (b[0] & 0x38) >> 3, b[0] & 7, 0x100 if b[1] == 0 else b[1]
|
||||||
else:
|
else:
|
||||||
raise Exception('Unhandled instruction %02x' % b)
|
raise Exception('Unhandled instruction %02x' % b)
|
||||||
|
|
||||||
def disassm_timeslot_table(b, off):
|
|
||||||
pc=off
|
def disassm_timeslot_table(b: bytes, off: int):
|
||||||
|
pc = off
|
||||||
while len(b) > 0:
|
while len(b) > 0:
|
||||||
op, sz, *operands = decode_insn(b)
|
op, sz, *operands = decode_insn(b)
|
||||||
if sz > len(b):
|
if sz > len(b):
|
||||||
raise Exception('Truncated instruction')
|
raise Exception('Truncated instruction')
|
||||||
print(' %04x: %-6s %s' % (pc, hexlify(b[:sz]).decode(), insn_to_string[op] % tuple(operands)))
|
print(' %04x: %-6s %s' %
|
||||||
|
(pc, hexlify(b[:sz]).decode(), insn_to_string[op] % tuple(operands)))
|
||||||
b = b[sz:]
|
b = b[sz:]
|
||||||
pc += sz
|
pc += sz
|
||||||
|
|
||||||
def find_nth_insn(b, opcode, n):
|
|
||||||
pc=0
|
def find_nth_insn(b: bytes, opcode: int, n: int):
|
||||||
|
pc = 0
|
||||||
while len(b) > 0:
|
while len(b) > 0:
|
||||||
op, sz, *_ = decode_insn(b)
|
op, sz, *_ = decode_insn(b)
|
||||||
|
|
||||||
|
|
@ -153,15 +157,16 @@ def find_nth_insn(b, opcode, n):
|
||||||
raise Exception('Truncated instruction')
|
raise Exception('Truncated instruction')
|
||||||
|
|
||||||
if op == opcode:
|
if op == opcode:
|
||||||
n-=1
|
n -= 1
|
||||||
if n == 0:
|
if n == 0:
|
||||||
return (pc, b[:sz])
|
return pc, b[:sz]
|
||||||
|
|
||||||
b = b[sz:]
|
b = b[sz:]
|
||||||
pc += sz
|
pc += sz
|
||||||
|
|
||||||
def find_nth_regwrite(b, reg_addr, n):
|
|
||||||
pc=0
|
def find_nth_regwrite(b: bytes, reg_addr: int, n: int):
|
||||||
|
pc = 0
|
||||||
while len(b) > 0:
|
while len(b) > 0:
|
||||||
op, sz, *operands = decode_insn(b)
|
op, sz, *operands = decode_insn(b)
|
||||||
|
|
||||||
|
|
@ -171,24 +176,28 @@ def find_nth_regwrite(b, reg_addr, n):
|
||||||
if op == 13:
|
if op == 13:
|
||||||
addr, value = operands
|
addr, value = operands
|
||||||
if addr == reg_addr:
|
if addr == reg_addr:
|
||||||
n-=1
|
n -= 1
|
||||||
if n == 0:
|
if n == 0:
|
||||||
return (pc, b[:sz])
|
return pc, b[:sz]
|
||||||
|
|
||||||
b = b[sz:]
|
b = b[sz:]
|
||||||
pc += sz
|
pc += sz
|
||||||
|
|
||||||
|
|
||||||
def split_chunks(b):
|
def split_chunks(b: bytes) -> typing.Generator[typing.List[typing.Union[int, bytes]], None, None]:
|
||||||
while len(b) > 0:
|
while len(b) > 0:
|
||||||
(typ, sz), b = unpack('<HH', b[:4]), b[4:]
|
(typ, sz), b = unpack('<HH', b[:4]), b[4:]
|
||||||
p, b = b[:sz], b[sz:]
|
p, b = b[:sz], b[sz:]
|
||||||
yield [typ, p]
|
yield [typ, p]
|
||||||
|
|
||||||
def merge_chunks(cs):
|
|
||||||
|
def merge_chunks(cs: typing.List[typing.List[typing.Union[int, bytes]]]):
|
||||||
return b''.join([pack('<HH', key, len(val)) + val for key, val in cs])
|
return b''.join([pack('<HH', key, len(val)) + val for key, val in cs])
|
||||||
|
|
||||||
def dump_all(b):
|
|
||||||
|
def dump_all(b: bytes):
|
||||||
|
ts: typing.Optional[bytes] = None
|
||||||
|
ts_off: typing.Optional[int] = None
|
||||||
while len(b) > 0:
|
while len(b) > 0:
|
||||||
(typ, sz), b = unpack('<HH', b[:4]), b[4:]
|
(typ, sz), b = unpack('<HH', b[:4]), b[4:]
|
||||||
p, b = b[:sz], b[sz:]
|
p, b = b[:sz], b[sz:]
|
||||||
|
|
@ -198,19 +207,19 @@ def dump_all(b):
|
||||||
print(' *0x%08x = 0x%08x' % (addr, val))
|
print(' *0x%08x = 0x%08x' % (addr, val))
|
||||||
elif typ == 0x32:
|
elif typ == 0x32:
|
||||||
print('Set Registers 16:')
|
print('Set Registers 16:')
|
||||||
(base,), p = unpack('<L', p[:4]), p[4:]
|
(base, ), p = unpack('<L', p[:4]), p[4:]
|
||||||
while len(p) > 0:
|
while len(p) > 0:
|
||||||
(off, val), p = unpack('<HH', p[:4]), p[4:]
|
(off, val), p = unpack('<HH', p[:4]), p[4:]
|
||||||
print(' *0x%08x = 0x%04x' % (off + base, val))
|
print(' *0x%08x = 0x%04x' % (off + base, val))
|
||||||
elif typ == 0x33:
|
elif typ == 0x33:
|
||||||
print('Set Registers 32:')
|
print('Set Registers 32:')
|
||||||
(base,), p = unpack('<L', p[:4]), p[4:]
|
(base, ), p = unpack('<L', p[:4]), p[4:]
|
||||||
while len(p) > 0:
|
while len(p) > 0:
|
||||||
(off, val), p = unpack('<HL', p[:6]), p[6:]
|
(off, val), p = unpack('<HL', p[:6]), p[6:]
|
||||||
print(' *0x%08x = 0x%08x' % (off + base, val))
|
print(' *0x%08x = 0x%08x' % (off + base, val))
|
||||||
elif typ == 0x34:
|
elif typ == 0x34:
|
||||||
print('%04x (%20s): (0x%x bytes) %s' % (typ, codes[typ], len(p), hexlify(p).decode()))
|
print('%04x (%20s): (0x%x bytes) %s' % (typ, codes[typ], len(p), hexlify(p).decode()))
|
||||||
ts=p
|
ts = p
|
||||||
elif typ == 0x29:
|
elif typ == 0x29:
|
||||||
ts_off, = unpack('<L', p)
|
ts_off, = unpack('<L', p)
|
||||||
print('%04x (%20s): 0x%x' % (typ, codes[typ], ts_off))
|
print('%04x (%20s): 0x%x' % (typ, codes[typ], ts_off))
|
||||||
|
|
@ -220,4 +229,3 @@ def dump_all(b):
|
||||||
if ts is not None:
|
if ts is not None:
|
||||||
print('Timeslot table, starting at 0x%x:' % ts_off)
|
print('Timeslot table, starting at 0x%x:' % ts_off)
|
||||||
disassm_timeslot_table(ts[ts_off:], ts_off)
|
disassm_timeslot_table(ts[ts_off:], ts_off)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,25 @@
|
||||||
import hmac
|
import hmac
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
import logging
|
import typing
|
||||||
|
from binascii import hexlify, unhexlify
|
||||||
|
from hashlib import sha256
|
||||||
from struct import pack, unpack
|
from struct import pack, unpack
|
||||||
from binascii import *
|
|
||||||
|
|
||||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
|
from cryptography.hazmat.primitives import hashes
|
||||||
from cryptography.hazmat.primitives.asymmetric import ec
|
from cryptography.hazmat.primitives.asymmetric import ec
|
||||||
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
|
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
|
||||||
from cryptography.hazmat.primitives import hashes
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||||
from hashlib import sha256
|
|
||||||
|
|
||||||
|
from .usb import usb, Usb
|
||||||
from .util import unhex
|
from .util import unhex
|
||||||
from .usb import usb
|
|
||||||
|
|
||||||
|
password_hardcoded = unhexlify('717cd72d0962bc4a2846138dbb2c24192512a76407065f383846139d4bec2033')
|
||||||
|
gwk_sign_hardcoded = unhexlify('3a4c76b76a97981d1274247e166610e77f4d9c9d07d3c728e532916bdd28b454')
|
||||||
|
|
||||||
password_hardcoded=unhexlify('717cd72d0962bc4a2846138dbb2c24192512a76407065f383846139d4bec2033')
|
crt_hardcoded = unhex('''
|
||||||
gwk_sign_hardcoded=unhexlify('3a4c76b76a97981d1274247e166610e77f4d9c9d07d3c728e532916bdd28b454')
|
|
||||||
|
|
||||||
crt_hardcoded=unhex('''
|
|
||||||
170000000001000001000000fcffffffffffffffffffffff00000000000000000000000001000000fffff
|
170000000001000001000000fcffffffffffffffffffffff00000000000000000000000001000000fffff
|
||||||
fff0000000000000000000000000000000000000000000000000000000000000000000000004b60d2273e
|
fff0000000000000000000000000000000000000000000000000000000000000000000000004b60d2273e
|
||||||
3cce3bf6b053ccb0061d65bc86987655bdebb3e7933aaad835c65a0000000000000000000000000000000
|
3cce3bf6b053ccb0061d65bc86987655bdebb3e7933aaad835c65a0000000000000000000000000000000
|
||||||
|
|
@ -32,56 +32,63 @@ ae6bcffffffffffffffff00000000ffffffff0000000000000000000000000000000000000000000
|
||||||
fff000000000000000000000000000000000000000000000000000000000000000000000000
|
fff000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
''')
|
''')
|
||||||
|
|
||||||
crypto_backend=default_backend()
|
crypto_backend = default_backend()
|
||||||
|
|
||||||
def prf(secret, seed, length):
|
|
||||||
|
def prf(secret: bytes, seed: bytes, length: int):
|
||||||
n = (length + 0x20 - 1) // 0x20
|
n = (length + 0x20 - 1) // 0x20
|
||||||
|
|
||||||
res = b''
|
res = b''
|
||||||
a = hmac.new(secret, seed, sha256).digest()
|
a = hmac.new(secret, seed, sha256).digest()
|
||||||
|
|
||||||
while n > 0:
|
while n > 0:
|
||||||
res += hmac.new(secret, a+seed, sha256).digest()
|
res += hmac.new(secret, a + seed, sha256).digest()
|
||||||
a = hmac.new(secret, a, sha256).digest()
|
a = hmac.new(secret, a, sha256).digest()
|
||||||
n -= 1
|
n -= 1
|
||||||
|
|
||||||
return res[:length]
|
return res[:length]
|
||||||
|
|
||||||
|
|
||||||
def hs_key():
|
def hs_key():
|
||||||
key=password_hardcoded[:0x10]
|
key = password_hardcoded[:0x10]
|
||||||
seed=password_hardcoded[0x10:] + b'\xaa'*2
|
seed = password_hardcoded[0x10:] + b'\xaa' * 2
|
||||||
hs_key=prf(key, b'HS_KEY_PAIR_GEN' + seed, 0x20)
|
hs_key = prf(key, b'HS_KEY_PAIR_GEN' + seed, 0x20)
|
||||||
return int(hs_key[::-1].hex(), 16)
|
return int(hs_key[::-1].hex(), 16)
|
||||||
|
|
||||||
def with_2bytes_size(chunk):
|
|
||||||
|
def with_2bytes_size(chunk: bytes):
|
||||||
return pack('>H', len(chunk)) + chunk
|
return pack('>H', len(chunk)) + chunk
|
||||||
|
|
||||||
def with_3bytes_size(chunk):
|
|
||||||
|
def with_3bytes_size(chunk: bytes):
|
||||||
return pack('>BH', len(chunk) >> 16, len(chunk)) + chunk
|
return pack('>BH', len(chunk) >> 16, len(chunk)) + chunk
|
||||||
|
|
||||||
def with_1byte_size(chunk):
|
|
||||||
|
def with_1byte_size(chunk: bytes):
|
||||||
return pack('>B', len(chunk)) + chunk
|
return pack('>B', len(chunk)) + chunk
|
||||||
|
|
||||||
|
|
||||||
def to_bytes(n):
|
def to_bytes(n):
|
||||||
b=b''
|
b = b''
|
||||||
while n:
|
while n:
|
||||||
b += (n & 0xff).to_bytes(1, 'big')
|
b += (n & 0xff).to_bytes(1, 'big')
|
||||||
n >>= 8
|
n >>= 8
|
||||||
|
|
||||||
return b
|
return b
|
||||||
|
|
||||||
def pad(b):
|
|
||||||
l = 16 - (len(b) % 16)
|
|
||||||
return b + bytes([l-1])*l
|
|
||||||
|
|
||||||
def unpad(b):
|
def pad(b: bytes):
|
||||||
return b[:-1-b[-1]]
|
l = 16 - (len(b) % 16)
|
||||||
|
return b + bytes([l - 1]) * l
|
||||||
|
|
||||||
|
|
||||||
|
def unpad(b: bytes):
|
||||||
|
return b[:-1 - b[-1]]
|
||||||
|
|
||||||
|
|
||||||
# TODO assert the right state transitions
|
# TODO assert the right state transitions
|
||||||
class Tls():
|
class Tls:
|
||||||
|
def __init__(self, usb: Usb):
|
||||||
def __init__(self, usb):
|
|
||||||
self.usb = usb
|
self.usb = usb
|
||||||
self.reset()
|
self.reset()
|
||||||
try:
|
try:
|
||||||
|
|
@ -101,20 +108,20 @@ class Tls():
|
||||||
self.secure_tx = False
|
self.secure_tx = False
|
||||||
|
|
||||||
# Info about the host computer
|
# Info about the host computer
|
||||||
def set_hwkey(self, product_name, serial_number):
|
def set_hwkey(self, product_name: str, serial_number: str):
|
||||||
hw_key = bytes(product_name, 'ascii') + b'\0' + \
|
hw_key = bytes(product_name, 'ascii') + b'\0' + \
|
||||||
bytes(serial_number, 'ascii') + b'\0'
|
bytes(serial_number, 'ascii') + b'\0'
|
||||||
|
|
||||||
# pre-TLS keys
|
# pre-TLS keys
|
||||||
self.psk_encryption_key = prf(password_hardcoded, b'GWK' + hw_key, 0x20)
|
self.psk_encryption_key = prf(password_hardcoded, b'GWK' + hw_key, 0x20)
|
||||||
self.psk_validation_key = prf(self.psk_encryption_key,
|
self.psk_validation_key = prf(self.psk_encryption_key, b'GWK_SIGN' + gwk_sign_hardcoded,
|
||||||
b'GWK_SIGN' + gwk_sign_hardcoded, 0x20)
|
0x20)
|
||||||
|
|
||||||
def cmd(self, cmd):
|
def cmd(self, cmd: typing.Union[bytes, typing.Callable[[], bytes]]):
|
||||||
if self.secure_rx and self.secure_tx:
|
if self.secure_rx and self.secure_tx:
|
||||||
rsp=self.app(cmd)
|
rsp = self.app(cmd)
|
||||||
else:
|
else:
|
||||||
rsp=self.usb.cmd(cmd)
|
rsp = self.usb.cmd(cmd)
|
||||||
|
|
||||||
return rsp
|
return rsp
|
||||||
|
|
||||||
|
|
@ -124,31 +131,27 @@ class Tls():
|
||||||
|
|
||||||
self.handshake_hash = sha256()
|
self.handshake_hash = sha256()
|
||||||
|
|
||||||
rsp=self.usb.cmd(unhexlify('44000000') + self.make_handshake(self.make_client_hello()))
|
rsp = self.usb.cmd(unhexlify('44000000') + self.make_handshake(self.make_client_hello()))
|
||||||
self.parse_tls_response(rsp)
|
self.parse_tls_response(rsp)
|
||||||
|
|
||||||
self.make_keys()
|
self.make_keys()
|
||||||
|
|
||||||
rsp=self.usb.cmd(
|
rsp = self.usb.cmd(
|
||||||
unhexlify('44000000') +
|
unhexlify('44000000') + self.make_handshake(self.make_certs() + self.make_client_kex() +
|
||||||
self.make_handshake(
|
self.make_cert_verify()) +
|
||||||
self.make_certs() +
|
self.make_change_cipher_spec() + self.make_handshake(self.make_finish()))
|
||||||
self.make_client_kex() +
|
|
||||||
self.make_cert_verify()) +
|
|
||||||
self.make_change_cipher_spec() +
|
|
||||||
self.make_handshake(self.make_finish()))
|
|
||||||
|
|
||||||
self.parse_tls_response(rsp)
|
self.parse_tls_response(rsp)
|
||||||
|
|
||||||
def trace(self, s):
|
def trace(self, s: str):
|
||||||
if self.trace_enabled:
|
if self.trace_enabled:
|
||||||
logging.debug(s)
|
logging.debug(s)
|
||||||
|
|
||||||
def app(self, b):
|
def app(self, b: typing.Union[bytes, typing.Callable[[], bytes]]):
|
||||||
b = b() if callable(b) else b
|
b = b() if callable(b) else b
|
||||||
return self.parse_tls_response(self.usb.cmd(self.make_app_data(b)))
|
return self.parse_tls_response(self.usb.cmd(self.make_app_data(b)))
|
||||||
|
|
||||||
def update_neg(self, b):
|
def update_neg(self, b: bytes):
|
||||||
self.handshake_hash.update(b)
|
self.handshake_hash.update(b)
|
||||||
|
|
||||||
def make_keys(self):
|
def make_keys(self):
|
||||||
|
|
@ -156,27 +159,28 @@ class Tls():
|
||||||
self.session_public = skey.private_numbers().public_numbers
|
self.session_public = skey.private_numbers().public_numbers
|
||||||
pre_master_secret = skey.exchange(ec.ECDH(), self.ecdh_q)
|
pre_master_secret = skey.exchange(ec.ECDH(), self.ecdh_q)
|
||||||
seed = self.client_random + self.server_random
|
seed = self.client_random + self.server_random
|
||||||
self.master_secret = prf(pre_master_secret, b'master secret'+seed, 0x30)
|
self.master_secret = prf(pre_master_secret, b'master secret' + seed, 0x30)
|
||||||
key_block = prf(self.master_secret, b'key expansion'+seed, 0x120)
|
key_block = prf(self.master_secret, b'key expansion' + seed, 0x120)
|
||||||
self.sign_key = key_block[0x00:0x20]
|
self.sign_key = key_block[0x00:0x20]
|
||||||
self.validation_key = key_block[0x20:0x20+0x20]
|
self.validation_key = key_block[0x20:0x20 + 0x20]
|
||||||
self.encryption_key = key_block[0x40:0x40+0x20]
|
self.encryption_key = key_block[0x40:0x40 + 0x20]
|
||||||
self.decryption_key = key_block[0x60:0x60+0x20]
|
self.decryption_key = key_block[0x60:0x60 + 0x20]
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
with open('tls.dict', 'wb') as f:
|
with open('tls.dict', 'wb') as f:
|
||||||
pickle.dump({
|
pickle.dump(
|
||||||
'sign_key': self.sign_key,
|
{
|
||||||
'validation_key': self.validation_key,
|
'sign_key': self.sign_key,
|
||||||
'encryption_key': self.encryption_key,
|
'validation_key': self.validation_key,
|
||||||
'decryption_key': self.decryption_key,
|
'encryption_key': self.encryption_key,
|
||||||
'secure_rx': self.secure_rx,
|
'decryption_key': self.decryption_key,
|
||||||
'secure_tx': self.secure_tx
|
'secure_rx': self.secure_rx,
|
||||||
}, f)
|
'secure_tx': self.secure_tx
|
||||||
|
}, f)
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
with open('tls.dict', 'rb') as f:
|
with open('tls.dict', 'rb') as f:
|
||||||
d=pickle.load(f)
|
d = pickle.load(f)
|
||||||
self.sign_key = d['sign_key']
|
self.sign_key = d['sign_key']
|
||||||
self.validation_key = d['validation_key']
|
self.validation_key = d['validation_key']
|
||||||
self.encryption_key = d['encryption_key']
|
self.encryption_key = d['encryption_key']
|
||||||
|
|
@ -184,46 +188,46 @@ class Tls():
|
||||||
self.secure_rx = d['secure_rx']
|
self.secure_rx = d['secure_rx']
|
||||||
self.secure_tx = d['secure_tx']
|
self.secure_tx = d['secure_tx']
|
||||||
|
|
||||||
def decrypt(self, c):
|
def decrypt(self, c: bytes):
|
||||||
iv, c = c[:0x10], c[0x10:]
|
iv, c = c[:0x10], c[0x10:]
|
||||||
cipher = Cipher(algorithms.AES(self.decryption_key), modes.CBC(iv), backend=crypto_backend)
|
cipher = Cipher(algorithms.AES(self.decryption_key), modes.CBC(iv), backend=crypto_backend)
|
||||||
decryptor = cipher.decryptor()
|
decryptor = cipher.decryptor()
|
||||||
m = decryptor.update(c) + decryptor.finalize()
|
m = decryptor.update(c) + decryptor.finalize()
|
||||||
m=unpad(m)
|
m = unpad(m)
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def encrypt(self, b):
|
def encrypt(self, b: bytes):
|
||||||
#iv = unhexlify('454849acdd075174d6b9e713a957c2e7')
|
# iv = unhexlify('454849acdd075174d6b9e713a957c2e7')
|
||||||
iv = os.urandom(0x10)
|
iv = os.urandom(0x10)
|
||||||
cipher = Cipher(algorithms.AES(self.encryption_key), modes.CBC(iv), backend=crypto_backend)
|
cipher = Cipher(algorithms.AES(self.encryption_key), modes.CBC(iv), backend=crypto_backend)
|
||||||
encryptor = cipher.encryptor()
|
encryptor = cipher.encryptor()
|
||||||
b=pad(b)
|
b = pad(b)
|
||||||
c=encryptor.update(b) + encryptor.finalize()
|
c = encryptor.update(b) + encryptor.finalize()
|
||||||
return iv + c
|
return iv + c
|
||||||
|
|
||||||
def validate(self, t, b):
|
def validate(self, t: int, b: bytes):
|
||||||
b, hs = b[:-0x20], b[-0x20:]
|
b, hs = b[:-0x20], b[-0x20:]
|
||||||
|
|
||||||
hdr = pack('>BBBH', t, 3, 3, len(b))
|
hdr = pack('>BBBH', t, 3, 3, len(b))
|
||||||
sig=hmac.new(self.validation_key, hdr+b, sha256).digest()
|
sig = hmac.new(self.validation_key, hdr + b, sha256).digest()
|
||||||
|
|
||||||
if sig != hs:
|
if sig != hs:
|
||||||
raise Exception('Packet signature validation check failed')
|
raise Exception('Packet signature validation check failed')
|
||||||
|
|
||||||
self.trace('<tls< %02x: %s' % (t, hexlify(b).decode()))
|
self.trace('<tls< %02x: %s' % (t, hexlify(b).decode()))
|
||||||
return b
|
return b
|
||||||
|
|
||||||
def sign(self, t, b):
|
def sign(self, t: int, b: bytes):
|
||||||
self.trace('>tls> %02x: %s' % (t, hexlify(b).decode()))
|
self.trace('>tls> %02x: %s' % (t, hexlify(b).decode()))
|
||||||
|
|
||||||
hdr = pack('>BBBH', t, 3, 3, len(b))
|
hdr = pack('>BBBH', t, 3, 3, len(b))
|
||||||
sig=hmac.new(self.sign_key, hdr+b, sha256).digest()
|
sig = hmac.new(self.sign_key, hdr + b, sha256).digest()
|
||||||
return b + sig
|
return b + sig
|
||||||
|
|
||||||
def make_finish(self):
|
def make_finish(self):
|
||||||
self.secure_tx = True
|
self.secure_tx = True
|
||||||
hs_hash = self.handshake_hash.copy().digest()
|
hs_hash = self.handshake_hash.copy().digest()
|
||||||
verify_data = prf(self.master_secret, b'client finished'+hs_hash, 0xc)
|
verify_data = prf(self.master_secret, b'client finished' + hs_hash, 0xc)
|
||||||
return b'\x14' + with_3bytes_size(verify_data)
|
return b'\x14' + with_3bytes_size(verify_data)
|
||||||
|
|
||||||
def make_change_cipher_spec(self):
|
def make_change_cipher_spec(self):
|
||||||
|
|
@ -231,12 +235,13 @@ class Tls():
|
||||||
|
|
||||||
def make_certs(self):
|
def make_certs(self):
|
||||||
cert = self.tls_cert
|
cert = self.tls_cert
|
||||||
cert = unhexlify('ac16') + cert # what's this?
|
cert = unhexlify('ac16') + cert # what's this?
|
||||||
cert = pack('>BH', 0, len(self.tls_cert)) + cert # this seems to violate the standard (should be len(cert))
|
cert = pack('>BH', 0, len(
|
||||||
cert = pack('>BH', 0, len(self.tls_cert)) + cert # same
|
self.tls_cert)) + cert # this seems to violate the standard (should be len(cert))
|
||||||
|
cert = pack('>BH', 0, len(self.tls_cert)) + cert # same
|
||||||
return self.with_neg_hdr(0x0b, cert)
|
return self.with_neg_hdr(0x0b, cert)
|
||||||
|
|
||||||
def with_neg_hdr(self, t, b):
|
def with_neg_hdr(self, t: int, b: bytes):
|
||||||
b = pack('>B', t) + with_3bytes_size(b)
|
b = pack('>B', t) + with_3bytes_size(b)
|
||||||
self.update_neg(b)
|
self.update_neg(b)
|
||||||
return b
|
return b
|
||||||
|
|
@ -246,11 +251,11 @@ class Tls():
|
||||||
return self.with_neg_hdr(0x10, b)
|
return self.with_neg_hdr(0x10, b)
|
||||||
|
|
||||||
def make_cert_verify(self):
|
def make_cert_verify(self):
|
||||||
buf=self.handshake_hash.copy().digest()
|
buf = self.handshake_hash.copy().digest()
|
||||||
b=self.priv_key.sign(buf, ec.ECDSA(Prehashed(hashes.SHA256())))
|
b = self.priv_key.sign(buf, ec.ECDSA(Prehashed(hashes.SHA256())))
|
||||||
return self.with_neg_hdr(0x0f, b)
|
return self.with_neg_hdr(0x0f, b)
|
||||||
|
|
||||||
def handle_server_hello(self, p):
|
def handle_server_hello(self, p: bytes):
|
||||||
if p[:2] != unhexlify('0303'):
|
if p[:2] != unhexlify('0303'):
|
||||||
raise Exception('unexpected TLS version %s' % hexlify(p[:2]).decode())
|
raise Exception('unexpected TLS version %s' % hexlify(p[:2]).decode())
|
||||||
|
|
||||||
|
|
@ -258,50 +263,54 @@ class Tls():
|
||||||
|
|
||||||
self.server_random, p = p[:0x20], p[0x20:]
|
self.server_random, p = p[:0x20], p[0x20:]
|
||||||
l = p[0]
|
l = p[0]
|
||||||
self.server_sessid, p = p[1:1+l], p[1+l:]
|
self.server_sessid, p = p[1:1 + l], p[1 + l:]
|
||||||
|
|
||||||
(suite,), p = unpack('>H', p[:2]), p[2:]
|
(suite, ), p = unpack('>H', p[:2]), p[2:]
|
||||||
|
|
||||||
if suite != 0xc005:
|
if suite != 0xc005:
|
||||||
raise Exception('Server accepted unsupported cipher suite %04x' % suite)
|
raise Exception('Server accepted unsupported cipher suite %04x' % suite)
|
||||||
|
|
||||||
if p[0] != 0:
|
if p[0] != 0:
|
||||||
raise Exception('Server selected to enable compression, which we don''t support %02x' % p[0])
|
raise Exception('Server selected to enable compression, which we don'
|
||||||
|
't support %02x' % p[0])
|
||||||
|
|
||||||
p = p[1:]
|
p = p[1:]
|
||||||
|
|
||||||
if p != b'':
|
if p != b'':
|
||||||
raise Exception('Not expecting any more data')
|
raise Exception('Not expecting any more data')
|
||||||
|
|
||||||
def handle_cert_req(self, p):
|
def handle_cert_req(self, p: bytes):
|
||||||
(sign_and_hash_algo,), p = unpack('>H', p[:2]), p[2:]
|
(sign_and_hash_algo, ), p = unpack('>H', p[:2]), p[2:]
|
||||||
if sign_and_hash_algo != 0x140:
|
if sign_and_hash_algo != 0x140:
|
||||||
raise Exception('Server requested a cert with an unsupported sign and hash algo combination %04x' % sign_and_hash_algo)
|
raise Exception(
|
||||||
|
'Server requested a cert with an unsupported sign and hash algo combination %04x' %
|
||||||
|
sign_and_hash_algo)
|
||||||
|
|
||||||
(l,), p = unpack('>H', p[:2]), p[2:]
|
(l, ), p = unpack('>H', p[:2]), p[2:]
|
||||||
if l != 0:
|
if l != 0:
|
||||||
raise Exception('Server requested a cert with non-empty list of CAs')
|
raise Exception('Server requested a cert with non-empty list of CAs')
|
||||||
|
|
||||||
if p != b'':
|
if p != b'':
|
||||||
raise Exception('Not expecting any more data')
|
raise Exception('Not expecting any more data')
|
||||||
|
|
||||||
def handle_server_hello_done(self, p):
|
def handle_server_hello_done(self, p: bytes):
|
||||||
if p != b'':
|
if p != b'':
|
||||||
raise Exception('Not expecting any body for "server hello done" pkt: %s' % hexlify(p).decode())
|
raise Exception('Not expecting any body for "server hello done" pkt: %s' %
|
||||||
|
hexlify(p).decode())
|
||||||
|
|
||||||
def handle_finish(self, b):
|
def handle_finish(self, b: bytes):
|
||||||
hs_hash = self.handshake_hash.copy().digest()
|
hs_hash = self.handshake_hash.copy().digest()
|
||||||
verify_data = prf(self.master_secret, b'server finished'+hs_hash, 0xc)
|
verify_data = prf(self.master_secret, b'server finished' + hs_hash, 0xc)
|
||||||
if verify_data != b:
|
if verify_data != b:
|
||||||
raise Exception('Final handshake check failed')
|
raise Exception('Final handshake check failed')
|
||||||
|
|
||||||
def handle_app_data(self, b):
|
def handle_app_data(self, b: bytes):
|
||||||
if not self.secure_rx:
|
if not self.secure_rx:
|
||||||
raise Exception('App payload before secure connection established')
|
raise Exception('App payload before secure connection established')
|
||||||
|
|
||||||
return self.validate(0x17, self.decrypt(b))
|
return self.validate(0x17, self.decrypt(b))
|
||||||
|
|
||||||
def handle_handshake(self, handshake):
|
def handle_handshake(self, handshake: bytes) -> None:
|
||||||
if self.secure_rx:
|
if self.secure_rx:
|
||||||
handshake = self.validate(0x16, self.decrypt(handshake))
|
handshake = self.validate(0x16, self.decrypt(handshake))
|
||||||
|
|
||||||
|
|
@ -325,10 +334,10 @@ class Tls():
|
||||||
else:
|
else:
|
||||||
raise Exception('Unknown handshake packet %02x' % t)
|
raise Exception('Unknown handshake packet %02x' % t)
|
||||||
|
|
||||||
self.update_neg(hdr+p)
|
self.update_neg(hdr + p)
|
||||||
|
|
||||||
def parse_tls_response(self, rsp):
|
def parse_tls_response(self, rsp: bytes):
|
||||||
app_data=b''
|
app_data = b''
|
||||||
|
|
||||||
while len(rsp) > 0:
|
while len(rsp) > 0:
|
||||||
while len(rsp) < 5:
|
while len(rsp) < 5:
|
||||||
|
|
@ -347,7 +356,7 @@ class Tls():
|
||||||
elif t == 0x14:
|
elif t == 0x14:
|
||||||
if pkt != unhexlify('01'):
|
if pkt != unhexlify('01'):
|
||||||
raise Exception('Unexpected ChangeCipherSpec payload')
|
raise Exception('Unexpected ChangeCipherSpec payload')
|
||||||
|
|
||||||
self.secure_rx = True
|
self.secure_rx = True
|
||||||
|
|
||||||
elif t == 0x17:
|
elif t == 0x17:
|
||||||
|
|
@ -358,47 +367,48 @@ class Tls():
|
||||||
|
|
||||||
return app_data
|
return app_data
|
||||||
|
|
||||||
def make_app_data(self, b):
|
def make_app_data(self, b: bytes):
|
||||||
if not self.secure_tx:
|
if not self.secure_tx:
|
||||||
raise Exception('App payload before secure connection established')
|
raise Exception('App payload before secure connection established')
|
||||||
|
|
||||||
b=self.encrypt(self.sign(0x17, b))
|
b = self.encrypt(self.sign(0x17, b))
|
||||||
|
|
||||||
return unhexlify('170303') + with_2bytes_size(b)
|
return unhexlify('170303') + with_2bytes_size(b)
|
||||||
|
|
||||||
def make_handshake(self, b):
|
def make_handshake(self, b: bytes):
|
||||||
if self.secure_tx:
|
if self.secure_tx:
|
||||||
b=self.encrypt(self.sign(0x16, b))
|
b = self.encrypt(self.sign(0x16, b))
|
||||||
|
|
||||||
return unhexlify('160303') + with_2bytes_size(b)
|
return unhexlify('160303') + with_2bytes_size(b)
|
||||||
|
|
||||||
def make_client_hello(self):
|
def make_client_hello(self):
|
||||||
h = unhexlify('0303') # TLS 1.2
|
h = unhexlify('0303') # TLS 1.2
|
||||||
#self.client_random = unhexlify('bc349559ac16c8f8362191395b4d04a435d870315f519eed8777488bc2b9600c')
|
# self.client_random = unhexlify('bc349559ac16c8f8362191395b4d04a435d870315f519eed8777488bc2b9600c')
|
||||||
self.client_random = os.urandom(0x20)
|
self.client_random = os.urandom(0x20)
|
||||||
h += self.client_random # client's random
|
h += self.client_random # client's random
|
||||||
h += with_1byte_size(unhexlify('00000000000000')) # session ID
|
h += with_1byte_size(unhexlify('00000000000000')) # session ID
|
||||||
|
|
||||||
suits = b''
|
suits = b''
|
||||||
suits += pack('>H', 0xc005) # TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
|
suits += pack('>H', 0xc005) # TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
|
||||||
suits += pack('>H', 0x003d) # TLS_RSA_WITH_AES_256_CBC_SHA256
|
suits += pack('>H', 0x003d) # TLS_RSA_WITH_AES_256_CBC_SHA256
|
||||||
suits += pack('>H', 0x008d) # TLS_RSA_WITH_AES_256_CBC_SHA256
|
suits += pack('>H', 0x008d) # TLS_RSA_WITH_AES_256_CBC_SHA256
|
||||||
h += with_2bytes_size(suits)
|
h += with_2bytes_size(suits)
|
||||||
|
|
||||||
h += with_1byte_size(b'') # no compression options
|
h += with_1byte_size(b'') # no compression options
|
||||||
|
|
||||||
exts = b''
|
exts = b''
|
||||||
exts += self.make_ext(0x004, pack('>H', 0x0017)) # truncated_hmac = 0x17
|
exts += self.make_ext(0x004, pack('>H', 0x0017)) # truncated_hmac = 0x17
|
||||||
exts += self.make_ext(0x00b, with_1byte_size(unhexlify('00'))) # EC points format = uncompressed
|
exts += self.make_ext(0x00b,
|
||||||
|
with_1byte_size(unhexlify('00'))) # EC points format = uncompressed
|
||||||
# h += with_2bytes_size(exts)
|
# h += with_2bytes_size(exts)
|
||||||
h += pack('>H', len(exts)-2) + exts # -2? WHY?!...
|
h += pack('>H', len(exts) - 2) + exts # -2? WHY?!...
|
||||||
|
|
||||||
return self.with_neg_hdr(0x01, h)
|
return self.with_neg_hdr(0x01, h)
|
||||||
|
|
||||||
def make_ext(self, id, b):
|
def make_ext(self, id: int, b: bytes):
|
||||||
return pack('>H', id) + with_2bytes_size(b)
|
return pack('>H', id) + with_2bytes_size(b)
|
||||||
|
|
||||||
def parseTlsFlash(self, reply):
|
def parse_tls_flash(self, reply: bytes):
|
||||||
while len(reply) > 0:
|
while len(reply) > 0:
|
||||||
hdr, reply = reply[:4], reply[4:]
|
hdr, reply = reply[:4], reply[4:]
|
||||||
hs, reply = reply[:0x20], reply[0x20:]
|
hs, reply = reply[:0x20], reply[0x20:]
|
||||||
|
|
@ -410,7 +420,7 @@ class Tls():
|
||||||
|
|
||||||
self.trace('block id %04x (%d bytes)' % (id, sz))
|
self.trace('block id %04x (%d bytes)' % (id, sz))
|
||||||
|
|
||||||
m=sha256()
|
m = sha256()
|
||||||
m.update(body)
|
m.update(body)
|
||||||
|
|
||||||
if m.digest() != hs:
|
if m.digest() != hs:
|
||||||
|
|
@ -431,37 +441,37 @@ class Tls():
|
||||||
else:
|
else:
|
||||||
self.trace('unhandled block id %04x (%d bytes): %s' % (id, sz, hexlify(body)))
|
self.trace('unhandled block id %04x (%d bytes): %s' % (id, sz, hexlify(body)))
|
||||||
|
|
||||||
def makeTlsFlashBlock(self, id, body):
|
def make_tls_flash_block(self, id: int, body: bytes):
|
||||||
m=sha256()
|
m = sha256()
|
||||||
m.update(body)
|
m.update(body)
|
||||||
hdr = pack('<HH', id, len(body))
|
hdr = pack('<HH', id, len(body))
|
||||||
return hdr+m.digest()+body
|
return hdr + m.digest() + body
|
||||||
|
|
||||||
def makeTlsFlash(self):
|
def make_tls_flash(self):
|
||||||
b = self.makeTlsFlashBlock(0, b'\0')
|
b = self.make_tls_flash_block(0, b'\0')
|
||||||
b+= self.makeTlsFlashBlock(4, self.priv_blob)
|
b += self.make_tls_flash_block(4, self.priv_blob)
|
||||||
b+= self.makeTlsFlashBlock(3, self.tls_cert)
|
b += self.make_tls_flash_block(3, self.tls_cert)
|
||||||
b+= self.makeTlsFlashBlock(5, crt_hardcoded)
|
b += self.make_tls_flash_block(5, crt_hardcoded)
|
||||||
b+= self.makeTlsFlashBlock(1, b'\0' * 0x100)
|
b += self.make_tls_flash_block(1, b'\0' * 0x100)
|
||||||
b+= self.makeTlsFlashBlock(2, b'\0' * 0x100)
|
b += self.make_tls_flash_block(2, b'\0' * 0x100)
|
||||||
b+= self.makeTlsFlashBlock(6, self.ecdh_blob)
|
b += self.make_tls_flash_block(6, self.ecdh_blob)
|
||||||
b+= b'\xff' * (0x1000 - len(b))
|
b += b'\xff' * (0x1000 - len(b))
|
||||||
return b
|
return b
|
||||||
|
|
||||||
def handle_empty(self, body):
|
def handle_empty(self, body: bytes):
|
||||||
if body != b'\0' * len(body):
|
if body != b'\0' * len(body):
|
||||||
raise Exception('Expected empty block')
|
raise Exception('Expected empty block')
|
||||||
|
|
||||||
def handle_cert(self, body):
|
def handle_cert(self, body: bytes):
|
||||||
# TODO validate cert, check if pub keys match
|
# TODO validate cert, check if pub keys match
|
||||||
self.tls_cert = body
|
self.tls_cert = body
|
||||||
self.trace('TLS cert blob: %s' % hexlify(self.tls_cert))
|
self.trace('TLS cert blob: %s' % hexlify(self.tls_cert))
|
||||||
|
|
||||||
def handle_ecdh(self, body):
|
def handle_ecdh(self, body: bytes):
|
||||||
self.ecdh_blob = body
|
self.ecdh_blob = body
|
||||||
key, signature = body[:0x90], body[0x90:]
|
key, signature = body[:0x90], body[0x90:]
|
||||||
x = key[0x8:0x8+0x20]
|
x = key[0x8:0x8 + 0x20]
|
||||||
y = key[0x4c:0x4c+0x20]
|
y = key[0x4c:0x4c + 0x20]
|
||||||
|
|
||||||
x, y = [int(hexlify(i[::-1]), 0x10) for i in [x, y]]
|
x, y = [int(hexlify(i[::-1]), 0x10) for i in [x, y]]
|
||||||
|
|
||||||
|
|
@ -477,35 +487,39 @@ class Tls():
|
||||||
l, = unpack('<L', l)
|
l, = unpack('<L', l)
|
||||||
signature, zeroes = signature[:l], signature[l:]
|
signature, zeroes = signature[:l], signature[l:]
|
||||||
|
|
||||||
if zeroes != b'\0'*len(zeroes):
|
if zeroes != b'\0' * len(zeroes):
|
||||||
raise Exception('Zeroes expected')
|
raise Exception('Zeroes expected')
|
||||||
|
|
||||||
# The following pub key is hardcoded for each fw revision in the synaWudfBioUsb.dll.
|
# The following pub key is hardcoded for each fw revision in the synaWudfBioUsb.dll.
|
||||||
# Corresponding private key should only be known to a genuine Synaptic device.
|
# Corresponding private key should only be known to a genuine Synaptic device.
|
||||||
fwpub = ec.EllipticCurvePublicNumbers(
|
fwpub = ec.EllipticCurvePublicNumbers(
|
||||||
0xf727653b4e16ce0665a6894d7f3a30d7d0a0be310d1292a743671fdf69f6a8d3,
|
0xf727653b4e16ce0665a6894d7f3a30d7d0a0be310d1292a743671fdf69f6a8d3,
|
||||||
0xa85538f8b6bec50d6eef8bd5f4d07a886243c58b2393948df761a84721a6ca94, ec.SECP256R1()).public_key(crypto_backend)
|
0xa85538f8b6bec50d6eef8bd5f4d07a886243c58b2393948df761a84721a6ca94,
|
||||||
|
ec.SECP256R1()).public_key(crypto_backend)
|
||||||
|
|
||||||
# throws InvalidSignature
|
# throws InvalidSignature
|
||||||
fwpub.verify(signature, key, ec.ECDSA(hashes.SHA256()))
|
fwpub.verify(signature, key, ec.ECDSA(hashes.SHA256()))
|
||||||
|
|
||||||
|
def handle_priv(self, body: bytes):
|
||||||
def handle_priv(self, body):
|
|
||||||
self.priv_blob = body
|
self.priv_blob = body
|
||||||
prefix, body = body[0], body[1:]
|
prefix, body = body[0], body[1:]
|
||||||
if prefix != 2:
|
if prefix != 2:
|
||||||
raise Exception('Unknown private key prefix %02x' % prefix)
|
raise Exception('Unknown private key prefix %02x' % prefix)
|
||||||
|
|
||||||
c, hs = body[:-0x20], body[-0x20:]
|
c, hs = body[:-0x20], body[-0x20:]
|
||||||
sig=hmac.new(self.psk_validation_key, c, sha256).digest()
|
sig = hmac.new(self.psk_validation_key, c, sha256).digest()
|
||||||
if hs != sig:
|
if hs != sig:
|
||||||
raise Exception('Signature verification failed. This device was probably paired with another computer.')
|
raise Exception(
|
||||||
|
'Signature verification failed. This device was probably paired with another computer.'
|
||||||
|
)
|
||||||
|
|
||||||
iv, c = c[:0x10], c[0x10:]
|
iv, c = c[:0x10], c[0x10:]
|
||||||
cipher = Cipher(algorithms.AES(self.psk_encryption_key), modes.CBC(iv), backend=crypto_backend)
|
cipher = Cipher(algorithms.AES(self.psk_encryption_key),
|
||||||
|
modes.CBC(iv),
|
||||||
|
backend=crypto_backend)
|
||||||
decryptor = cipher.decryptor()
|
decryptor = cipher.decryptor()
|
||||||
m = decryptor.update(c) + decryptor.finalize()
|
m = decryptor.update(c) + decryptor.finalize()
|
||||||
m=m[:-m[-1]] # unpad (standard this time)
|
m = m[:-m[-1]] # unpad (standard this time)
|
||||||
|
|
||||||
x, m = m[:0x20], m[0x20:]
|
x, m = m[:0x20], m[0x20:]
|
||||||
y, m = m[:0x20], m[0x20:]
|
y, m = m[:0x20], m[0x20:]
|
||||||
|
|
@ -519,8 +533,8 @@ class Tls():
|
||||||
self.trace('d=0x%x' % d)
|
self.trace('d=0x%x' % d)
|
||||||
|
|
||||||
# Someone has reported that x and y are 0 after pairing with the latest windows driver.
|
# Someone has reported that x and y are 0 after pairing with the latest windows driver.
|
||||||
#pub_key = ec.EllipticCurvePublicNumbers(x, y, ec.SECP256R1())
|
# pub_key = ec.EllipticCurvePublicNumbers(x, y, ec.SECP256R1())
|
||||||
#self.priv_key = ec.EllipticCurvePrivateNumbers(d, pub_key).private_key(crypto_backend)
|
# self.priv_key = ec.EllipticCurvePrivateNumbers(d, pub_key).private_key(crypto_backend)
|
||||||
|
|
||||||
self.priv_key = ec.derive_private_key(d, ec.SECP256R1(), backend=crypto_backend)
|
self.priv_key = ec.derive_private_key(d, ec.SECP256R1(), backend=crypto_backend)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
from time import ctime
|
|
||||||
import logging
|
import logging
|
||||||
|
import typing
|
||||||
from os.path import basename
|
from os.path import basename
|
||||||
|
from time import ctime
|
||||||
|
|
||||||
from .usb import usb
|
|
||||||
from .sensor import reboot, write_hw_reg32, read_hw_reg32, identify_sensor
|
|
||||||
from .flash import write_flash_all, write_fw_signature, get_fw_info
|
from .flash import write_flash_all, write_fw_signature, get_fw_info
|
||||||
|
from .sensor import reboot, write_hw_reg32, read_hw_reg32, identify_sensor
|
||||||
|
from .usb import usb
|
||||||
|
|
||||||
|
firmware_home = '/usr/share/python-validity'
|
||||||
|
|
||||||
firmware_home='/usr/share/python-validity'
|
|
||||||
|
|
||||||
def default_fwext_name():
|
def default_fwext_name():
|
||||||
if usb.usb_dev().idVendor == 0x138a:
|
if usb.usb_dev().idVendor == 0x138a:
|
||||||
|
|
@ -14,15 +16,17 @@ def default_fwext_name():
|
||||||
return '6_07f_Lenovo.xpfwext'
|
return '6_07f_Lenovo.xpfwext'
|
||||||
|
|
||||||
# It looks like the firmware file must match DLL, not the hardware.
|
# It looks like the firmware file must match DLL, not the hardware.
|
||||||
# Both DLL and xpfwext are universal.
|
# Both DLL and xpfwext are universal.
|
||||||
# The device dependant code seems to be loaded dynamically (via encrypted blobs).
|
# The device dependant code seems to be loaded dynamically (via encrypted blobs).
|
||||||
# So, it is important that xpfwext file is matching the blobs contents.
|
# So, it is important that xpfwext file is matching the blobs contents.
|
||||||
return '6_07f_lenovo_mis_qm.xpfwext'
|
return '6_07f_lenovo_mis_qm.xpfwext'
|
||||||
|
|
||||||
def upload_fwext(fw_path=None):
|
|
||||||
fwi=get_fw_info(2)
|
def upload_fwext(fw_path: typing.Optional[str] = None):
|
||||||
if fwi != None:
|
fwi = get_fw_info(2)
|
||||||
logging.info('Detected firmware version %d.%d (%s))' % (fwi.major, fwi.minor, ctime(fwi.buildtime)))
|
if fwi is not None:
|
||||||
|
logging.info('Detected firmware version %d.%d (%s))' %
|
||||||
|
(fwi.major, fwi.minor, ctime(fwi.buildtime)))
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
logging.info('No firmware detected. Uploading...')
|
logging.info('No firmware detected. Uploading...')
|
||||||
|
|
@ -32,33 +36,32 @@ def upload_fwext(fw_path=None):
|
||||||
if read_hw_reg32(0x80002080) not in [2, 3]:
|
if read_hw_reg32(0x80002080) not in [2, 3]:
|
||||||
raise Exception('Unexpected register value')
|
raise Exception('Unexpected register value')
|
||||||
|
|
||||||
dev=identify_sensor()
|
dev = identify_sensor()
|
||||||
logging.debug('Sensor: %s' % dev.name)
|
logging.debug('Sensor: %s' % dev.name)
|
||||||
# ^ TODO -- what is the real reason to detect HW at this stage?
|
# ^ TODO -- what is the real reason to detect HW at this stage?
|
||||||
# just a guess: perhaps it is used to construct fwext filename
|
# just a guess: perhaps it is used to construct fwext filename
|
||||||
|
|
||||||
|
|
||||||
default_name = firmware_home + '/' + default_fwext_name()
|
default_name = firmware_home + '/' + default_fwext_name()
|
||||||
if not fw_path:
|
if not fw_path:
|
||||||
fw_path = default_name
|
fw_path = default_name
|
||||||
elif basename(fw_path) != default_name:
|
elif basename(fw_path) != default_name:
|
||||||
logging.warning('WARNING: Your device fw is supposed to be called {}'.format(
|
logging.warning('WARNING: Your device fw is supposed to be called {}'.format(default_name))
|
||||||
default_name))
|
|
||||||
|
|
||||||
with open(fw_path, 'rb') as f:
|
with open(fw_path, 'rb') as f:
|
||||||
fwext=f.read()
|
fwext = f.read()
|
||||||
|
|
||||||
fwext=fwext[fwext.index(b'\x1a')+1:]
|
fwext = fwext[fwext.index(b'\x1a') + 1:]
|
||||||
fwext, signature = fwext[:-0x100], fwext[-0x100:]
|
fwext, signature = fwext[:-0x100], fwext[-0x100:]
|
||||||
|
|
||||||
write_flash_all(2, 0, fwext)
|
write_flash_all(2, 0, fwext)
|
||||||
write_fw_signature(2, signature)
|
write_fw_signature(2, signature)
|
||||||
|
|
||||||
fwi=get_fw_info(2)
|
fwi = get_fw_info(2)
|
||||||
if fwi == None:
|
if fwi is None:
|
||||||
raise Exception('No firmware detected')
|
raise Exception('No firmware detected')
|
||||||
|
|
||||||
logging.info('Loaded FWExt version %d.%d (%s), %d modules' % (fwi.major, fwi.minor, ctime(fwi.buildtime), len(fwi.modules)))
|
logging.info('Loaded FWExt version %d.%d (%s), %d modules' %
|
||||||
|
(fwi.major, fwi.minor, ctime(fwi.buildtime), len(fwi.modules)))
|
||||||
|
|
||||||
# Reboot
|
# Reboot
|
||||||
reboot()
|
reboot()
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,37 @@
|
||||||
|
|
||||||
import logging
|
|
||||||
import errno
|
import errno
|
||||||
import usb.core as ucore
|
import logging
|
||||||
from binascii import *
|
import typing
|
||||||
from .util import assert_status
|
from binascii import hexlify, unhexlify
|
||||||
from struct import unpack
|
from struct import unpack
|
||||||
from usb.core import USBError
|
|
||||||
from .blobs import init_hardcoded, init_hardcoded_clean_slate
|
|
||||||
|
|
||||||
supported_devices=[
|
import usb.core as ucore
|
||||||
|
from usb.core import USBError
|
||||||
|
|
||||||
|
from .blobs import init_hardcoded, init_hardcoded_clean_slate
|
||||||
|
from .util import assert_status
|
||||||
|
|
||||||
|
supported_devices = [
|
||||||
(0x138a, 0x0090),
|
(0x138a, 0x0090),
|
||||||
(0x138a, 0x0097),
|
(0x138a, 0x0097),
|
||||||
(0x06cb, 0x009a),
|
(0x06cb, 0x009a),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class CancelledException(Exception):
|
class CancelledException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Usb():
|
|
||||||
|
class Usb:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.interrupt_cb = None
|
|
||||||
self.trace_enabled = False
|
self.trace_enabled = False
|
||||||
self.dev = None
|
self.dev: typing.Optional[ucore.Device] = None
|
||||||
self.cancel = False
|
self.cancel = False
|
||||||
|
|
||||||
def open(self, vendor=None, product=None):
|
def open(self, vendor=None, product=None):
|
||||||
if vendor is not None and product is not None:
|
if vendor is not None and product is not None:
|
||||||
dev = ucore.find(idVendor=vendor, idProduct=product)
|
dev = ucore.find(idVendor=vendor, idProduct=product)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
def match(d):
|
def match(d):
|
||||||
return (d.idVendor, d.idProduct) in supported_devices
|
return (d.idVendor, d.idProduct) in supported_devices
|
||||||
|
|
||||||
|
|
@ -35,15 +39,15 @@ class Usb():
|
||||||
|
|
||||||
self.open_dev(dev)
|
self.open_dev(dev)
|
||||||
|
|
||||||
def open_devpath(self, busnum, address):
|
def open_devpath(self, busnum: int, address: int):
|
||||||
def match(d):
|
def match(d):
|
||||||
return d.bus == busnum and d.address == address
|
return d.bus == busnum and d.address == address
|
||||||
|
|
||||||
dev = ucore.find(custom_match=match)
|
dev = ucore.find(custom_match=match)
|
||||||
|
|
||||||
self.open_dev(dev)
|
self.open_dev(dev)
|
||||||
|
|
||||||
def open_dev(self, dev):
|
def open_dev(self, dev: ucore.Device):
|
||||||
if dev is None:
|
if dev is None:
|
||||||
raise Exception('No matching devices found')
|
raise Exception('No matching devices found')
|
||||||
|
|
||||||
|
|
@ -62,39 +66,39 @@ class Usb():
|
||||||
return self.dev
|
return self.dev
|
||||||
|
|
||||||
def send_init(self):
|
def send_init(self):
|
||||||
#self.dev.set_configuration()
|
# self.dev.set_configuration()
|
||||||
|
|
||||||
# TODO analyse responses, detect hardware type
|
# TODO analyse responses, detect hardware type
|
||||||
assert_status(self.cmd(unhexlify('01'))) # RomInfo.get()
|
assert_status(self.cmd(unhexlify('01'))) # RomInfo.get()
|
||||||
assert_status(self.cmd(unhexlify('19')))
|
assert_status(self.cmd(unhexlify('19')))
|
||||||
|
|
||||||
# 43 -- get partition header(?) (02 -- fwext partition)
|
# 43 -- get partition header(?) (02 -- fwext partition)
|
||||||
# c28c745a in response is a FwextBuildtime = 0x5A748CC2
|
# c28c745a in response is a FwextBuildtime = 0x5A748CC2
|
||||||
rsp=self.cmd(unhexlify('4302')) # get_fw_info()
|
rsp = self.cmd(unhexlify('4302')) # get_fw_info()
|
||||||
|
|
||||||
assert_status(self.cmd(init_hardcoded))
|
assert_status(self.cmd(init_hardcoded))
|
||||||
|
|
||||||
(err,), rsp = unpack('<H', rsp[:2]), rsp[2:]
|
(err, ), rsp = unpack('<H', rsp[:2]), rsp[2:]
|
||||||
if err != 0:
|
if err != 0:
|
||||||
# fwext is not loaded
|
# fwext is not loaded
|
||||||
logging.info('Clean slate')
|
logging.info('Clean slate')
|
||||||
self.cmd(init_hardcoded_clean_slate)
|
self.cmd(init_hardcoded_clean_slate)
|
||||||
|
|
||||||
def cmd(self, out):
|
def cmd(self, out: typing.Union[bytes, typing.Callable[[], bytes]]):
|
||||||
if callable(out):
|
if callable(out):
|
||||||
out = out()
|
out = out()
|
||||||
if not out:
|
if not out:
|
||||||
return 0
|
return 0
|
||||||
self.trace('>cmd> %s' % hexlify(out).decode())
|
self.trace('>cmd> %s' % hexlify(out).decode())
|
||||||
self.dev.write(1, out)
|
self.dev.write(1, out)
|
||||||
resp = self.dev.read(129, 100*1024)
|
resp = self.dev.read(129, 100 * 1024)
|
||||||
resp = bytes(resp)
|
resp = bytes(resp)
|
||||||
self.trace('<cmd< %s' % hexlify(resp).decode())
|
self.trace('<cmd< %s' % hexlify(resp).decode())
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
def read_82(self):
|
def read_82(self):
|
||||||
try:
|
try:
|
||||||
resp = self.dev.read(130, 1024*1024, timeout=10000)
|
resp = self.dev.read(130, 1024 * 1024, timeout=10000)
|
||||||
resp = bytes(resp)
|
resp = bytes(resp)
|
||||||
self.trace('<130< %s' % hexlify(resp).decode())
|
self.trace('<130< %s' % hexlify(resp).decode())
|
||||||
return resp
|
return resp
|
||||||
|
|
@ -122,8 +126,9 @@ class Usb():
|
||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
def trace(self, s):
|
def trace(self, s: str):
|
||||||
if self.trace_enabled:
|
if self.trace_enabled:
|
||||||
logging.debug(s)
|
logging.debug(s)
|
||||||
|
|
||||||
usb=Usb()
|
|
||||||
|
usb = Usb()
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from struct import unpack
|
|
||||||
from binascii import unhexlify
|
from binascii import unhexlify
|
||||||
|
from struct import unpack
|
||||||
|
|
||||||
def assert_status(b):
|
|
||||||
s,=unpack('<H', b[:2])
|
def assert_status(b: bytes):
|
||||||
|
s, = unpack('<H', b[:2])
|
||||||
if s != 0:
|
if s != 0:
|
||||||
if s == 0x44f:
|
if s == 0x44f:
|
||||||
raise Exception('Signature validation failed: %04x' % s)
|
raise Exception('Signature validation failed: %04x' % s)
|
||||||
|
|
@ -12,6 +12,5 @@ def assert_status(b):
|
||||||
raise Exception('Failed: %04x' % s)
|
raise Exception('Failed: %04x' % s)
|
||||||
|
|
||||||
|
|
||||||
def unhex(x):
|
def unhex(x: str):
|
||||||
return unhexlify(re.sub('\W', '', x))
|
return unhexlify(re.sub(r'\W', '', x))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,34 @@
|
||||||
finger_ids = {
|
finger_ids = {
|
||||||
# https://github.com/tpn/winsdk-10/blob/9b69fd26ac0c7d0b83d378dba01080e93349c2ed/Include/10.0.16299.0/shared/winbio_types.h#L864-L878
|
# https://github.com/tpn/winsdk-10/blob/9b69fd26ac0c7d0b83d378dba01080e93349c2ed/Include/10.0.16299.0/shared/winbio_types.h#L864-L878
|
||||||
"WINBIO_ANSI_381_POS_UNKNOWN": 0,
|
"WINBIO_ANSI_381_POS_UNKNOWN": 0,
|
||||||
"WINBIO_ANSI_381_POS_RH_THUMB": 1,
|
"WINBIO_ANSI_381_POS_RH_THUMB": 1,
|
||||||
"WINBIO_ANSI_381_POS_RH_INDEX_FINGER": 2,
|
"WINBIO_ANSI_381_POS_RH_INDEX_FINGER": 2,
|
||||||
"WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER": 3,
|
"WINBIO_ANSI_381_POS_RH_MIDDLE_FINGER": 3,
|
||||||
"WINBIO_ANSI_381_POS_RH_RING_FINGER": 4,
|
"WINBIO_ANSI_381_POS_RH_RING_FINGER": 4,
|
||||||
"WINBIO_ANSI_381_POS_RH_LITTLE_FINGER": 5,
|
"WINBIO_ANSI_381_POS_RH_LITTLE_FINGER": 5,
|
||||||
"WINBIO_ANSI_381_POS_LH_THUMB": 6,
|
"WINBIO_ANSI_381_POS_LH_THUMB": 6,
|
||||||
"WINBIO_ANSI_381_POS_LH_INDEX_FINGER": 7,
|
"WINBIO_ANSI_381_POS_LH_INDEX_FINGER": 7,
|
||||||
"WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER": 8,
|
"WINBIO_ANSI_381_POS_LH_MIDDLE_FINGER": 8,
|
||||||
"WINBIO_ANSI_381_POS_LH_RING_FINGER": 9,
|
"WINBIO_ANSI_381_POS_LH_RING_FINGER": 9,
|
||||||
"WINBIO_ANSI_381_POS_LH_LITTLE_FINGER": 10,
|
"WINBIO_ANSI_381_POS_LH_LITTLE_FINGER": 10,
|
||||||
|
"WINBIO_ANSI_381_POS_RH_FOUR_FINGERS": 13,
|
||||||
|
"WINBIO_ANSI_381_POS_LH_FOUR_FINGERS": 14,
|
||||||
|
"WINBIO_ANSI_381_POS_TWO_THUMBS": 15,
|
||||||
|
|
||||||
"WINBIO_ANSI_381_POS_RH_FOUR_FINGERS": 13,
|
# https://github.com/tpn/winsdk-10/blob/9b69fd26ac0c7d0b83d378dba01080e93349c2ed/Include/10.0.16299.0/shared/winbio_types.h#L920-L929
|
||||||
"WINBIO_ANSI_381_POS_LH_FOUR_FINGERS": 14,
|
"WINBIO_FINGER_UNSPECIFIED_POS_01": 0xf5,
|
||||||
"WINBIO_ANSI_381_POS_TWO_THUMBS": 15,
|
"WINBIO_FINGER_UNSPECIFIED_POS_02": 0xf6,
|
||||||
|
"WINBIO_FINGER_UNSPECIFIED_POS_03": 0xf7,
|
||||||
|
"WINBIO_FINGER_UNSPECIFIED_POS_04": 0xf8,
|
||||||
# https://github.com/tpn/winsdk-10/blob/9b69fd26ac0c7d0b83d378dba01080e93349c2ed/Include/10.0.16299.0/shared/winbio_types.h#L920-L929
|
"WINBIO_FINGER_UNSPECIFIED_POS_05": 0xf9,
|
||||||
"WINBIO_FINGER_UNSPECIFIED_POS_01": 0xf5,
|
"WINBIO_FINGER_UNSPECIFIED_POS_06": 0xfa,
|
||||||
"WINBIO_FINGER_UNSPECIFIED_POS_02": 0xf6,
|
"WINBIO_FINGER_UNSPECIFIED_POS_07": 0xfb,
|
||||||
"WINBIO_FINGER_UNSPECIFIED_POS_03": 0xf7,
|
"WINBIO_FINGER_UNSPECIFIED_POS_08": 0xfc,
|
||||||
"WINBIO_FINGER_UNSPECIFIED_POS_04": 0xf8,
|
"WINBIO_FINGER_UNSPECIFIED_POS_09": 0xfd,
|
||||||
"WINBIO_FINGER_UNSPECIFIED_POS_05": 0xf9,
|
"WINBIO_FINGER_UNSPECIFIED_POS_10": 0xfe
|
||||||
"WINBIO_FINGER_UNSPECIFIED_POS_06": 0xfa,
|
|
||||||
"WINBIO_FINGER_UNSPECIFIED_POS_07": 0xfb,
|
|
||||||
"WINBIO_FINGER_UNSPECIFIED_POS_08": 0xfc,
|
|
||||||
"WINBIO_FINGER_UNSPECIFIED_POS_09": 0xfd,
|
|
||||||
"WINBIO_FINGER_UNSPECIFIED_POS_10": 0xfe
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Store the keys in the reverse order for faster lookups
|
# Store the keys in the reverse order for faster lookups
|
||||||
finger_names = {}
|
finger_names = {}
|
||||||
for name, index in finger_ids.items():
|
for name, index in finger_ids.items():
|
||||||
finger_names[index] = name
|
finger_names[index] = name
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue